Monitor soap request via powershell

Hi,

I need to monitor a value via a soap request. I want to do this with a powershell script monitor.

Before I get the value, I need to authenticate via this method, found in the documentation of the application:

#Authentication
$Webservice = New-WebServiceProxy -Uri $Wsdl
$Authentication = new-Object -TypeName Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication
$Authentication.username = ‘??’
$Authentication.password = ‘??’
$Webservice.authenticationValue = $Authentication

When I run my script as a task in scom, I get the right information.
When I do the same in a monitor, I’m getting this error:

Exception setting “authenticationValue”: “Cannot convert the “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication” value of type “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication” to type “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy9vice_cc_MessagingToolsAPI_WSDL.authentication”.”

On the internet, I found that this has to do with not ending the session between 2 checks of the monitor. This can be true, because when I run the same via a task, everytime the session will ended when the task is completed.

Has anybody an idea how I can solve this problem?

Kind regards,
Luc

Hi Luc,
I have probed a system using an authenticated SOAP request and it works fine on my end, so the short answer will be that it is possible to do so. However, a lot will have to do with your design AND with the capabilities of the Endpoint being monitored. I think your problem is more that the username/password is not properly passed over.

That being said, couple pointers:

  1. Create a Secure Reference (You will be able to fill this out using a RunAs account)
<SecureReference ID="CORP.MP.APPL.App.WebServiceAccount" Accessibility="Public" Context="CORP.MP.APPL.App.Server" />
  1. Use the secure reference as parameters in your script
<Parameters>
  <Parameter>
	<Name>Username</Name>
	<Value>$RunAs[Name="CORP.MP.APPL.App.WebServiceAccount"]/UserName$</Value>
  </Parameter>
  <Parameter>
	<Name>Password</Name>
	<Value>$RunAs[Name="CORP.MP.APPL.App.WebServiceAccount"]/Password$</Value>
  </Parameter>
</Parameters>
  1. Corresponding Script Code
Param(
[string]$Username,
[string]$Password
)
  1. I usually make a quick check inside the script to make sure I have the user/pwd before moving forward
if ([string]::IsNullOrWhitespace($Username) -or [string]::IsNullOrWhitespace($Password)) {
	Throw "Missing username or password!!!"
} 

#Add-Log is an internal function I use to log stuff, adjust to your methods
Add-Log "Credentials were successfully passed, username is '$Username' password will not be shown"
#Rest of your code goes here...

If indeed it is caused by some kind of session timeout on your WSDL endpoint, there should be some kind of “logoff” function somewhere in there as well (and of course, that depends on your app…)

Was about to click on send, when I remembered that if your environment uses proxies, you will need to adjust your Invoke-RestMethod request accordingly. In my case, the endpoint is internal so I explicitly remove the proxy within the script:

$WebClient = New-Object Net.WebClient
$WebClient.Proxy = $null		
[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($Null)

$RM = Invoke-RestMethod -Method Post -Uri $WSDL -Headers $Headers -Body $RequestXML -Proxy $null -ErrorAction Stop

You may also want to check if your endpoint uses sessions, in which case you may need the SessionVariable Parameter in the first request

$RM = Invoke-RestMethod -SessionVariable MySessionVariableName -Uri....

and the WebSession in the following requests

$RM = Invoke-RestMethod -WebSession $MySessionVariableName -URI...

Hope this helps!

Hi Pascal,
Thanks for your answer.
The idea of putting the username and password in a runas profile was another problem were I was searching a solution for. I’ll give that a try next week.
For my question about the soap request, it’s all new for me and I don’t understand very well your solution.
I’m only know that the only way to autenticate my application is by this way, I’ve got from the application owner in the company:

$Webservice = New-WebServiceProxy -Uri $Wsdl
$Authentication = new-Object -TypeName Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication
$Authentication.username = ‘??’
$Authentication.password = ‘??’
$Webservice.authenticationValue = $Authentication

Running my script with this way of authentication as a task in scom, I’m getting the right results, but when running the same in a monitor, I’m getting an error.

Can you explain it a little bit more what I have to do?

Kind regards,
Luc

Hum, I do remember my original code was making use of the New-WebServiceProxy, then I moved it to use the Invoke-RestMethod.

Here’s my original code (with minimal changes to anonymize the code)

	$WSP = New-WebServiceProxy -Uri $WSDL -Class Monitoring -Namespace MyApp-ErrorAction Stop
	$WSP.Credentials = [System.Management.Automation.PSCredential]((New-Object  System.Management.Automation.PSCredential($WSUser, $($WSPwd | ConvertTo-SecureString -asPlainText -Force)) ))
	$WSP.PreAuthenticate = $true 

#Info here comes from WSP documentation as well  
	$estats = New-Object MyApp.webStatisticInput 
	$estats.locale = 'en' 
  
	$wpk = New-Object MyApp.webProfileKey 
	$wpk.name = 'Monitoring' 
	$wpk.abbreviation = 'Monitor' 
	$estats.statisticProfileCollectionKey = $wpk 
  
  #the executeStatistics is the function inside the WSP that gave me the info I needed 
	try { $stats = $WSP.executeStatistics($estats)  } catch {
		if ($ShowLogs) { "Trapped!!!" }
		$RetLog += "`nError while capturing data at first pass, trying second time..."
		$stats = $WSP.executeStatistics($estats) 
	}

That said, what I would do is to get more logs on your end and advise what exactly fails. Is the script not executing at all? If the script runs fine in tasks, I don’t think the problem is with the code within the script but likely somewhere else in the workflow. Can you share what error you get exactly?

I have noted that sometimes powershell scripts fail to run, within the workflow. To catch these, I look into the event logs. Use this custom query, replacing with your stuff of course. I tend to use ID 4100 & 4101 in my probe scripts.

<QueryList>
  <Query Id="0" Path="Operations Manager">
    <Select Path="Operations Manager">*[System[(EventID=4100 or EventID=4101)]]</Select>
  </Query>
  <Query Id="1" Path="Operations Manager">
    <Select Path="Operations Manager">
            *[System[(EventID=1201)]]
            and
            *[EventData[Data='CORP.MP.MyApp.Solution']]
          </Select>
  </Query>
  <Query Id="2" Path="Operations Manager">
    <Select Path="Operations Manager">
			*[System[(EventID=22406)]]
			and
			*[EventData[Data='ScriptName.ps1']]
		</Select>
  </Query>
</QueryList>

Hi Pascal,

I’m getting this error when running my powershell in a monitor:

Exception setting “authenticationValue”: “Cannot convert the “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication” value of type “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1vice_cc_MessagingToolsAPI_WSDL.authentication” to type “Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy9vice_cc_MessagingToolsAPI_WSDL.authentication”.”

Kind regards,
Luc

Strange that the only difference between the 2 types is a “9” instead of a “1” inside of WebServiceProxy9vice…

Have you tried changing your Authentication variable?

$Authentication = new-Object -TypeName Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy9vice_cc_MessagingToolsAPI_WSDL.authentication

Aside from that, no more ideas, sorry…