CONTEXT: Creating a custom management pack for SCOM[System Center]. Working on the script discovery stage presently.
When ran, my script returns the required values from a rest endpoint exposed in json.
###########
## Authentication variables
$user = "darthMaul"
$pwd = "!deathstar" | ConvertTo-SecureString -asPlainText -Force
$limit = 1
function GetServiceStates($offset)
{
$defUrl = "https://demo1.galacticempire.co.uk/tie-fighter/api/v2/service_states?limit=$limit&offset=$offset"
$cred = New-Object System.Management.Automation.PSCredential($user,$pwd)
#$stackStatus = Invoke-WebRequest -Uri $url -Credential $cred
$stackStatus = Invoke-RestMethod -Uri $defUrl -Credential $cred
if ($stackStatus.Count -ge 1) {
#appends only the service url for an individual service
$parsedUrls = $stackStatus.serviceUrl
#secure requests required else the call fails
$UrlsParsed = $parsedUrls.Replace("http","https")
#$UrlsParsed
#for each service found perform an addition call to determine the status of the service.
foreach ($Url in $UrlsParsed)
{
$sep = Invoke-WebRequest -uri $url -Credential $cred
$svcStatus = $sep | select @{name="Response";Expression ={$_.statuscode}}, @{name="Status";Expression ={$_.statusdescription}}
$svcCall = $sep | ConvertFrom-Json | select displayname, serviceTypeUrl, port, serviceport
$svcStatus | Add-Member -MemberType NoteProperty -Name displayname -Value $svcCall.displayname
$svcStatus | Add-Member -MemberType NoteProperty -Name serviceTypeUrl -Value $svcCall.serviceTypeUrl
$svcStatus | Add-Member -MemberType NoteProperty -Name port -Value $svcCall.port
$svcStatus | Add-Member -MemberType NoteProperty -Name servicePort -Value $svcCall.servicePort
$svcStatus | ft
$offset++
}
if($offset -ge $limit){
GetServiceStates($offset)
}
}
}
GetServiceStates(0)
DIFFICULTY/PROBLEM/CHALLENGE: Having some trouble converting this into a discovery object.
Here's my breaking script.
param($sourceId,$managedEntityId)
## Authentication variables
$user = "darthMaul"
$pwd = "!deathstar" | ConvertTo-SecureString -asPlainText -Force
$limit = 1
$api = New-Object -comObject 'MOM.ScriptAPI'
$discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)
#Log script event
#$api.LogScriptEvent('Scripts/ManageAppServiceStatus.ps1',999,4,$service)
$defUrl = "https://demo1.galacticempire.co.uk/tie-fighter/api/v2/service_states?limit=$limit&offset=$offset"
$cred = New-Object System.Management.Automation.PSCredential($user,$pwd)
$stackStatus = Invoke-RestMethod -Uri $defUrl -Credential $cred
if ($stackStatus.Count -ge 1)
{
#appends only the service url for an individual service
$parsedUrls = $stackStatus.serviceUrl
#secure requests required else the call fails
$UrlsParsed = $parsedUrls.Replace("http","https")
#$UrlsParsed
#for each service found perform an addition call to determine the status of the service.
foreach ($Url in $UrlsParsed)
{
#create discoverty instance
$instance = $discoveryData.CreateClassInstance("$MPElement[Name='StackAppServiceStatus.Discovery.ProbeService']$")
$sep = Invoke-WebRequest -uri $url -Credential $cred
#collects first different data sets
$svcStatus = $sep | select @{name="Response";Expression ={$_.statuscode}}, @{name="Status";Expression ={$_.statusdescription}}
#collects seconds different data sets
$svcCall = $sep | ConvertFrom-Json | select displayname, serviceTypeUrl, port, serviceport
#appends both data set together
$svcStatus | Add-Member -MemberType NoteProperty -Name displayname -Value $svcCall.displayname
$svcStatus | Add-Member -MemberType NoteProperty -Name serviceTypeUrl -Value $svcCall.serviceTypeUrl
$svcStatus | Add-Member -MemberType NoteProperty -Name port -Value $svcCall.port
$svcStatus | Add-Member -MemberType NoteProperty -Name servicePort -Value $svcCall.servicePort
#formats results
$svcStatus | ft
$offset++
$instance.AddProperty("$MPElement[Name='StackAppServiceStatus.Discovery.ProbeService']/Response$", 'Response' + $svcStatus.response)
$instance.AddProperty("$MPElement[Name='StackAppServiceStatus.Discovery.ProbeService']/Status$", 'Status' + $svcStatus.status)
$instance.AddProperty("$MPElement[Name='StackAppServiceStatus.Discovery.ProbeService']/Displayname$", 'Displayname' + $svcStatus.displayname)
$instance.AddProperty("$MPElement[Name='StackAppServiceStatus.Discovery.ProbeService']/Port$", 'Port' + $svcStatus.port)
#store all variables into instance
$discoveryData.AddInstance($instance)
}
if($offset -ge $limit)
{
GetServiceStates($offset)
}
}
$discoveryData = GetServiceStates(0)
Although this is very frustrating, enjoying it. Just need direction or structure of some sort. Any help is appreciated.
Thanks.
ERROR MESSAGE
Exception calling "CreateDiscoveryData" with "3" argument(s): "Invalid class string (Exception from HRESULT: 0x800401F3
(CO_E_CLASSSTRING))"
At line:13 char:1
+ $discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
You cannot call a method on a null-valued expression.
At line:33 char:9
+ $instance = $discoveryData.CreateClassInstance("$MPElement[Name='StackAp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
First exception - it looks like that you are not passing target class and discovery class IDs to discovery script correctly, so MOMAPI can't create DiscoveryData instance.
$sourceID must be initialized with $MPElement$ value $managedEntityID must be initialize with $Target/Id$ value
You can read more details about using parameters in scripts there: https://msdn.microsoft.com/en-us/library/hh329047.aspx
The second exception is caused by the first one because discoveryData wasn't created so it's null :)
Good luck! Roman.