I am SOAP novice, but I have been struggling with this for days and can't figure out where I'm going wrong. I'm trying to use Ruby to talk to VMware Site Recovery Manager
I have a powershell script that can successfully use to login. I want to take this powershell script and re-write it in ruby.
Here are the wsdl files:
https://srm-vcenter-a:8095/srm?wsdl
http://pastebin.com/xJ6AwLaC
https://srm-vcenter-a:8095/srm-Service?wsdl
http://pastebin.com/nmH5mzdH
The powershell code
$Server = "srm-vcenter-a"
$UserName = "administrator"
$Password = "mypw"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Write-Host "Connecting to SRM"
$webSvc = New-WebServiceProxy ("https://" + $Server + ":8095/srm-Service?wsdl") -Namespace SRM
$srm = New-Object SRM.SrmService
$srm.Url = "Https://" + $Server + ":9007"
$srm.Timeout = 600000
$srm.CookieContainer = New-Object System.Net.CookieContainer
$srmSvcRef = New-Object SRM.ManagedObjectReference
$srmSvcRef.Type = "SrmServiceInstance"
$srmSvcRef.Value = $srmSvcRef.Type
$srmSvcContent = $srm.RetrieveContent($srmSvcRef)
$srm.SrmLoginLocale($srmSvcRef, $UserName, $Password, $null)
$srmObject = New-Object System.Object
$srmObject | Add-Member -Type NoteProperty -value $Server -Name SRMServer
$srmObject | Add-Member -Type NoteProperty -value $srm -Name SRMService
$srmObject | Add-Member -Type NoteProperty -value $srmSvcContent -Name SRMContent
...
I have tried using Savon, soap4r, and handsoap and I don't know what I'm missing.
Here is the Savon code that doesn't work.
require 'savon'
require 'rubygems'
client = Savon.client do
wsdl "https://srm-vcenter-a:8095/srm?wsdl"
#endpoint "https://srm-vcenter-a:8095/srm-Service?wsdl"
endpoint "http://srm5-vcenter-a:9007"
namespace "https://srm-vcenter-a/sdk/srm"
#proxy "https://srm-vcenter-a:8095/srm-Service?wsdl"
ssl_version :TLSv1
ssl_verify_mode :none
convert_request_keys_to :lower_camelcase
end
message = { username: 'administrator', password: 'mypw' }
response = client.call(:srm_login_locale, message: message)
Thanks in advance for all help
Having taken a brief look at your code it appears that in PowerShell you have
$srm.SrmLoginLocale($srmSvcRef, $UserName, $Password, $null)
While in Ruby you have
message = { username: 'administrator', password: 'mypw' }
response = client.call(:srm_login_locale, message: message)
In the PowerShell code there are 4 values passed to the SrmLoginLocale method:
$srmSvcRef
$UserName
$Password
$null
In the ruby code you are missing the first parameter and the fourth parameter in your call. Try creating the equivalent of $srmSvcRef in ruby. I am not a ruby programmer but I think the code would look something like:
srm_svc_ref = { value: 'SrmServiceInstance', type: 'SrmServiceInstance'}
message = { _this: srm_svc_ref, username: 'administrator', password: 'mypw', locale: nil}
response = client.call(:srm_login_locale, message: message)
Related
We have a few computers that are used in a lab for processing and users can log in directly on-site or via remote desktop. We are trying to clean up the machines and decided to remove user folders for those who have not logged on in the past year. I am able to use windows event viewer to find the information, but I haven't figured out a way to export the information I need.
I found this script which seems to do exactly what I need, except I'm getting the following error when I run it: https://github.com/adbertram/Random-PowerShell-Work/blob/master/ActiveDirectory/Get-UserLogonSessionHistory.ps1
PS C:\Users\vmc\Documents> .\userevents.ps1
Get-WinEvent : Could not retrieve information about the Security log. Error: Attempted to perform an unauthorized
operation..
At C:\Users\vmc\Documents\userevents.ps1:48 char:29
+ ... ($events = Get-WinEvent -ComputerName $computer -LogName $logNames - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : LogInfoUnavailable,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : There is not an event log on the BIGBERTHA computer that matches "Security".
At C:\Users\vmc\Documents\userevents.ps1:48 char:29
+ ... ($events = Get-WinEvent -ComputerName $computer -LogName $logNames - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Security:String) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
C:\Users\vmc\Documents\userevents.ps1 : A positional parameter cannot be found that accepts argument '.'.
At line:1 char:1
+ .\userevents.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [userevents.ps1], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,userevents.ps1
I do have a log called 'Security' when I look at the Windows Event Viewer, so I'm not sure why I can't query this log?
Thank you for any help- suggestions to get this script to run or another way to compile this list are very much appreciated!
Script from the link (saved to userevents.ps1, called from powershell above)
<#
.SYNOPSIS
This script finds all logon, logoff and total active session times of all users on all computers specified. For this script
to function as expected, the advanced AD policies; Audit Logon, Audit Logoff and Audit Other Logon/Logoff Events must be
enabled and targeted to the appropriate computers via GPO or local policy.
.EXAMPLE
.PARAMETER ComputerName
An array of computer names to search for events on. If this is not provided, the script will search the local computer.
.INPUTS
None. You cannot pipe objects to Get-ActiveDirectoryUserActivity.ps1.
.OUTPUTS
None. If successful, this script does not output anything.
#>
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = $Env:COMPUTERNAME
)
try {
#region Defie all of the events to indicate session start or top
$sessionEvents = #(
#{ 'Label' = 'Logon'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4624 } ## Advanced Audit Policy --> Audit Logon
#{ 'Label' = 'Logoff'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4647 } ## Advanced Audit Policy --> Audit Logoff
#{ 'Label' = 'Startup'; 'EventType' = 'SessionStop'; 'LogName' = 'System'; 'ID' = 6005 }
#{ 'Label' = 'RdpSessionReconnect'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4778 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'RdpSessionDisconnect'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4779 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'Locked'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4800 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'Unlocked'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4801 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
)
## All of the IDs that designate when user activity starts
$sessionStartIds = ($sessionEvents | where { $_.EventType -eq 'SessionStart' }).ID
## All of the IDs that designate when user activity stops
$sessionStopIds = ($sessionEvents | where { $_.EventType -eq 'SessionStop' }).ID
#endregion
## Define all of the log names we'll be querying
$logNames = ($sessionEvents.LogName | select -Unique)
## Grab all of the interesting IDs we'll be looking for
$ids = $sessionEvents.Id
## Build the insane XPath query for the security event log in order to query events as fast as possible
$logonXPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
$otherXpath = 'Event[System[({0})]]' -f "EventID=$((#($ids).where({ $_ -ne '4624' })) -join ' or EventID=')"
$xPath = '({0}) or ({1})' -f $logonXPath, $otherXpath
foreach ($computer in $ComputerName) {
## Query each computer's event logs using the Xpath filter
if (-not ($events = Get-WinEvent -ComputerName $computer -LogName $logNames -FilterXPath $xPath)) {
Write-Warning -Message 'No logon events found'.
} else {
Write-Verbose -Message "Found [$($events.Count)] events to look through"
## Set up the output object
$output = [ordered]#{
'ComputerName' = $computer
'Username' = $null
'StartTime' = $null
'StartAction' = $null
'StopTime' = $null
'StopAction' = $null
'Session Active (Days)' = $null
'Session Active (Min)' = $null
}
## Need current users because if no stop time, they're still probably logged in
$getGimInstanceParams = #{
ClassName = 'Win32_ComputerSystem'
}
if ($computer -ne $Env:COMPUTERNAME) {
$getGimInstanceParams.ComputerName = $computer
}
$loggedInUsers = Get-CimInstance #getGimInstanceParams | Select-Object -ExpandProperty UserName | foreach { $_.split('\')[1] }
## Find all user start activity events and begin parsing
#($events).where({ $_.Id -in $sessionStartIds }).foreach({
try {
$logonEvtId = $_.Id
$output.StartAction = #($sessionEvents).where({ $_.ID -eq $logonEvtId }).Label
$xEvt = [xml]$_.ToXml()
## Figure out the login session ID
$output.Username = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'TargetUserName' }).'#text'
$logonId = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'TargetLogonId' }).'#text'
if (-not $logonId) {
$logonId = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'LogonId' }).'#text'
}
$output.StartTime = $_.TimeCreated
Write-Verbose -Message "New session start event found: event ID [$($logonEvtId)] username [$($output.Username)] logonID [$($logonId)] time [$($output.StartTime)]"
## Try to match up the user activity end event with the start event we're processing
if (-not ($sessionEndEvent = #($Events).where({ ## If a user activity end event could not be found, assume the user is still logged on
$_.TimeCreated -gt $output.StartTime -and
$_.ID -in $sessionStopIds -and
(([xml]$_.ToXml()).Event.EventData.Data | where { $_.Name -eq 'TargetLogonId' }).'#text' -eq $logonId
})) | select -last 1) {
if ($output.UserName -in $loggedInUsers) {
$output.StopTime = Get-Date
$output.StopAction = 'Still logged in'
} else {
throw "Could not find a session end event for logon ID [$($logonId)]."
}
} else {
## Capture the user activity end time
$output.StopTime = $sessionEndEvent.TimeCreated
Write-Verbose -Message "Session stop ID is [$($sessionEndEvent.Id)]"
$output.StopAction = #($sessionEvents).where({ $_.ID -eq $sessionEndEvent.Id }).Label
}
$sessionTimespan = New-TimeSpan -Start $output.StartTime -End $output.StopTime
$output.'Session Active (Days)' = [math]::Round($sessionTimespan.TotalDays, 2)
$output.'Session Active (Min)' = [math]::Round($sessionTimespan.TotalMinutes, 2)
[pscustomobject]$output
} catch {
Write-Warning -Message $_.Exception.Message
}
})
}
}
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
First you got this error:
Attempted to perform an unauthorized
And:
There is not an event log on the BIGBERTHA computer that matches "Security"
This clearly indicates that the account used to run the query against the remote computer does not have the necesssary permission. You can't access the and/or find the Security Log because of insufficient acces rights.
In your 2nd run with the right account and elevated shell you did get further, because you now get the error:
The specified query is invalid
That means you have been able to connect to the remote computer and read the security log but get-winevent could not execute the operation because the query syntax is invalid.
This part of the code builds the filter:
$logonXPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
$otherXpath = 'Event[System[({0})]]' -f "EventID=$((#($ids).where({ $_ -ne '4624' })) -join ' or EventID=')"
$xPath = '({0}) or ({1})' -f $logonXPath, $otherXpath
The scripts works for me... but in the end you do not need the whole functionality, think this will help:
#Query
$XPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
#Get List containing the dnsHostNames of the computers to query
$computer = gc [path]
#Run Query against computers and gather result
$result = #(
foreach ($computer in $computers){
#run query
$events = get-winevent -LogName security -FilterXPath $XPath -ComputerName $computer
#parse events as xml and extract necessary information, return object
$eventobj = #(
foreach ($event in $events){
[xml]$xml = $event.toxml()
$attrsht = [ordered]#{
TimeCreated=$xml.event.system.TimeCreated.SystemTime
eventId=$xml.event.system.eventId
SubjectUserSid=$xml.event.EventData.data[0].'#text'
SubjectUserName=$xml.event.EventData.data[1].'#text'
SubjectDomainName=$xml.event.EventData.data[2].'#text'
TargetUserSid=$xml.event.EventData.data[4].'#text'
TargetUserName=$xml.event.EventData.data[5].'#text'
TargetDomainName=$xml.event.EventData.data[6].'#text'
LogonType=$xml.event.EventData.data[8].'#text'
LogonProcessName=$xml.event.EventData.data[9].'#text'
ipAdress=$xml.event.EventData.data[18].'#text'
}
#return event object
new-object -TypeName psobject -Property $attrsht
}
)
$attrsht = #{
Computer=$computer
Events=$eventobj
}
#return object per computer containing all events
new-object -TypeName psobject -Property $attrsht
}
)
#As the property events is an array you can export it by using json
$result | ConvertTo-Json | set-content [path]
#If you want a csv we have to flattern the array
$result = #(
foreach ($computer in $computers){
#run query
$events = get-winevent -LogName security -FilterXPath $XPath -ComputerName $computer
#parse events as xml and extract necessary information, return object
foreach ($event in $events){
[xml]$xml = $event.toxml()
$attrsht = [ordered]#{
computername=$computer
TimeCreated=$xml.event.system.TimeCreated.SystemTime
eventId=$xml.event.system.eventId
SubjectUserSid=$xml.event.EventData.data[0].'#text'
SubjectUserName=$xml.event.EventData.data[1].'#text'
SubjectDomainName=$xml.event.EventData.data[2].'#text'
TargetUserSid=$xml.event.EventData.data[4].'#text'
TargetUserName=$xml.event.EventData.data[5].'#text'
TargetDomainName=$xml.event.EventData.data[6].'#text'
LogonType=$xml.event.EventData.data[8].'#text'
LogonProcessName=$xml.event.EventData.data[9].'#text'
ipAdress=$xml.event.EventData.data[18].'#text'
}
#return event object
new-object -TypeName psobject -Property $attrsht
}
}
)
$result | export-csv [path] -NoClobber -NoTypeInformation -Delimiter ";"
I'm using winexe from my backend api to run commands on Windows Domain Server. I want to set IIS App Pool Identity as an Account from Active Directory. The problem is that while using this command :
%windir%\system32\inetsrv\appcmd.exe set config /section:applicationPools ^
/[name='POOLNAME'].processModel.identityType:SpecificUser ^
/[name='POOLNAME'].processModel.userName:DOMAIN\USER ^
/[name='POOLNAME'].processModel.password:PASSWORD
It runs successfully everytime even if the username and password is incorrect. Even the pool gets Started with wrong password. However setting wrong password through GUI fails.
I want to identify when the password or username is being set wrongly.
PS: I even tried using Set-ItemProperty on powershell and the result was the same.
You can't test your credentials with AppPool, but you can definitely test them.
# Service Principal credentials
$username = 'Username'
$password = 'Password' | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList $username, $password
if (Test-Credential -Credential $credential) {
Write-Verbose "Credentials for $($credential.UserName) are valid..."
# do the appcmd stuff
}
else {
Write-Warning 'Credentials are not valid or some other logic'
}
Just add Test-Credential function definition at the top of your script
function Test-Credential {
[CmdletBinding()]
Param
(
# Specifies the user account credentials to use when performing this task.
[Parameter()]
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$DS = $null
$Username = $Credential.UserName
$SplitUser = $Username.Split('\')
if ($SplitUser.Count -eq 2 ) {$Username = $SplitUser[1]}
if ($SplitUser.Count -eq 1 -or $SplitUser[0] -eq $env:COMPUTERNAME ) {
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('machine', $env:COMPUTERNAME)
}
else {
try {
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('domain')
}
catch {
return $false
}
}
$DS.ValidateCredentials($Username, $Credential.GetNetworkCredential().Password)
}
(PS: Code is valid even though prettifier break with backslash quote syntax)
amazingly i puzzled out that you can do it like this - but it still doesn't validate
appcmd set apppool junkapp /processmodel.password:junkpassword
I am trying to create rest api to update configuration in all environments in urban code.
Is there any rest client or do we need write any custom code.?
How do I start? Your kind suggestions please
Are you asking about updating environment properties? If so. I do this with Powershell.
$webUrl = "https://ibm-ucd.myCompany.com"
$ucdApiUserName = "yourCLIAccount"
$ucdApiPass = "yourCLIpassword"
$appName = "MyApplication"
$environment = "ADT"
$propertyNewValue = "myNewValue"
$credential = New-Object System.Management.Automation.PSCredential ($ucdApiUserName,(ConvertTo-SecureString $ucdApiPass -AsPlainText -Force))
####################################################################
## Bypass Cert Issues with connecting to HTTPS API
####################################################################
$certData = [string][System.Net.ServicePointManager]::CertificatePolicy
if ($certData -ne "TrustAllCertsPolicy")
{
add-type #"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"#
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}
$hash = [ordered] #{
"application" = "$AppName";
"environment" = "$environment";
"isSecure" = "false";
"name" = "myEnvProperty";
"value" = "$propertyNewValue"
}
$newValuesJson = $hash | ConvertTo-Json
Write-Host "Updating uDeploy environment properties for $environment"
$uri = "$WebUrl/cli/environment/propValue?"
Invoke-RestMethod -Method 'PUT' -ContentType "application/json" -Credential
$credential -uri $uri -Body $newValuesJson | Out-Null
We have two APIs that does a POST and GET requests. Both of them used to work perfectly fine but the API that does POST started giving an error:
Invoke-WebRequest : The underlying connection was: An unexpected error occurred on a receive.`
I have been trying to research for few days and all the KBs pointing to some sort of SSL/TLS and adding this piece of code:
[Net.ServicePointManager]::SecurityProtocol = "SystemDefault,Tls12, Tls11, Tls, Ssl3"
but I already had this code from the start. However, I cannot find a solution to my problem.
OS : Windows 2012
PowerShell Version: 4.0
function funName ($Val1, $Val2) {
[Net.ServicePointManager]::SecurityProtocol = "SystemDefault,Tls12, Tls11, Tls, Ssl3"
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
$url = "https://someAPI/post.request/do-something"
$user = "username"
$pass = "password"
$pair = "$($user):$($pass)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds "
$Headers = #{
"Accept"="application/json"
Authorization = $basicAuthValue
}
$Body = #{
'#type' ='x'
parm1 = $Val1
parm2 = $Val2
}
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $url -Headers $Headers -Method Post -Body $Body | Out-Null
}
## Deactivation Request ffffffff##
funName -RequestID Val1 adID Val2
As stated earlier, this used to work up until last week.
Set this to the top of your script:
Add-Type #"
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace myTrust
{
public class TrustAllCertsPolicy : ICertificatePolicy
{
public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
return true;
}
}
}
"#
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object myTrust.TrustAllCertsPolicy
I was working on a similar request to retrieve data from API and I found out that I was calling my function as funName -val1 1234 val2 9999 where I was missing "-" on my seconda parameter. As soon as I fixed that it starting working again funName -val1 1234 -val2 9999 . Thanks Stackoverflow community for the help on this.
I'm trying to download a file from Linux server with Apache web server to Windows Server 2012 R2 using Windows PowerShell
Note: the URL is HTTPS
$source = "https://uri"
$destination = "C:\path\file.txt"
$username = "admin"
$password = "#dfkl!f" | ConvertTo-SecureString -asPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username,$password)
Invoke-WebRequest $source -OutFile $destination -Credential $cred
Invoke-WebRequest : Authorization Required
This server could not verify that you are authorized to access the document requested. Either you supplied the wrong
credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.
Apache/2.2.15 (CentOS) Server at url Port 443
When I type the credentials through browser i m able to download but through powershell it show bad credentials
I just tried this against one of my Apache/Linux boxes on a SSL page that uses Basic auth, and it seemed to work... Your mileage might vary...
$source = "https://Uri"
$destination = "C:\Foo\Bar"
$username = 'mylogin'
$password = 'reallgoodpassword'
$auth = 'Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($username+':'+$password ))
Invoke-WebRequest -Headers #{ "Accept" = "*/*"; "Authorization" = $auth } -Uri $source -Method Get
try to create the passwordstring with
$password = ConvertTo-SecureString "#dfkl!f" -AsPlainText -Force