Forum Discussion

Oliver_Kelsey's avatar
4 days ago

DataSource PowerShell Active Discovery and Collector scripts

Hello LM Community!

I am trying to configure a new DataSource that uses PowerShell scripts for both Active Discovery and Collector Attributes with the end goal being to populate the discovered devices/instances with data.

My Active Discovery script is as follows (I've left out the functions that generate bearer tokens and make the MS Graph calls).

$tenantID = '<tenantId>'
$appID = '<appId>'
$appSecret = '<appSecret>'
$appCredentials = New-Object System.Management.Automation.PSCredential($appID, (ConvertTo-SecureString $appSecret -AsPlainText -Force))
$authToken = Get-MSGraphAuthToken -Credential $appCredentials -TenantID $tenantID

$resourceURL = "https://graph.microsoft.com/v1.0/servicePrincipals"
$applications = (Invoke-MSGraphQuery -method GET -Uri $resourceURL -token $authToken -Recursive).value | Where-Object {$_.preferredSingleSignOnMode -eq "saml"}

foreach ($application in $applications) {
    Write-Host "$($application.appId)##$($application.appDisplayName)"
}

This successfully imports all of the instances as I would expect with their respective 'appId' and 'appDisplayName'. These can be seen under the Resources tab in LM.

My Collector Attributes script is as follows (again functions left out):

$tenantID = '<tenantId>'
$appID = '<appId>'
$appSecret = '<appSecret>'
$global:appCredentials = New-Object System.Management.Automation.PSCredential($appID, (ConvertTo-SecureString $appSecret -AsPlainText -Force))
$global:authToken = Get-MSGraphAuthToken -Credential $appCredentials -TenantID $tenantID

$resourceURL = "https://graph.microsoft.com/v1.0/servicePrincipals"
$applications = (Invoke-MSGraphQuery -method GET -Uri $resourceURL -token $authToken -Recursive).value | Where-Object {$_.preferredSingleSignOnMode -eq "saml"}

$todayDate = Get-Date

foreach ($application in $applications) {
    $expirationDate = $application.keyCredentials.endDateTime[0] | Get-Date -Format yyyy-MM-dd
    $daysToExpiration = (New-TimeSpan -Start $todayDate -End $($application.keyCredentials.endDateTime[0])).Days
    $data = [PSCustomObject]@{
        appId = $application.appId
        expirationDate = $expirationDate
        daysToExpiration = $daysToExpiration
    } | ConvertTo-Json
    $data
}

When I test this script, I select the Device to run it from and the Instance to run it against. The output contains the 'appId', 'expirationDate' and 'daysToExpiration' properties of all the instances, and not just the instance I want to match the latter two data points to. This would be as expected when looking at the script, but not what I want to achieve.

I don't understand how the Collector script is supposed to match the values of the properties to their respective Instances. Could someone please explain this to me?

I then want to interpret the output with a JSON parser, so I have some JSON Datapoints configured to pull in the desired 'expirationDate' and 'daysToExpiration'. For example:
Interpreter: JSON
JSON Path: $.daysToExpiration

This appears to only work for one of the properties but not both.

I have read other articles and documentation that mentions key pairs, but ideally I would like to stick with JSON.

1 Reply

  • Within your for loop, output one line for expirationDate and one for the daysToExpiration. Prepend each with the appId. So it would look like this:

    123.expirationDate: 20240724
    123.daysToExpiration: 20
    456.expirationDate: 20250725
    456.daysToExpiration: 21

    Where 123 and 456 are the app IDs. Note, only integers/decimal numbers are accepted, so if you want the expiration date, you'll need to pull that in as an ILP during instance discovery.