Observer Scripts
A quick reference to write your own observer scripts
Script Template
Observer 'ArbitraryObserverName' {
Init {
# Init is called before any action. Use it to initialize your observer script.
# TODO: implement observer setup
# import modules
# fetch observer environment
$tenantId = $env:GOV_TENANT_ID
$clientId = $env:GOV_CLIENT_ID
$CertificateFile = $env:GOV_CERTIFICATE_FILE
$CertificatePassword = Get-Content $env:GOV_CERTIFICATE_SECRET -Raw | ConvertTo-SecureString -AsPlainText -Force
$Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($CertificateFile, $CertificatePassword)
#$organizationname = $env:GOV_ORGANIZATION_NAME
# get access token with client certificate
$Token = Get-MsalToken -ClientId $clientId -TenantId $tenantId -ClientCertificate $Certificate -Verbose
}
Shutdown {
# Shutdown is called after any successful or non-successful action. Use it to release resources.
# TODO: implement observer shutdown
Disconnect-MgGraph
}
Action 'List' {
# Perform list observation (delta + non-delta)
param($Order)
# TODO: implement list observation
return New-ObservationResult `
-Table "TABLE_NAME" `
-PartitionKey "PARTITION_KEY" `
-ItemId "INVENTORY_ITEM_ID" `
-ObjectId "OPTIONAL_GOVERNED_OBJECT_ID" `
-Observation @{ OPTIONAL_KEY_VALUE_PAIRS = "..." } `
-ParentRefs @( "OPTIONAL_PARENT_OBJECT_ALIASES" ) `
-ChildRefs @( "OPTIONAL_CHILD_OBJECT_ALIASES" ) `
-Message "OPTIONAL_MESSAGE" `
-Reason "OPTIONAL_REASON"
return New-ObservationError `
-ObservationType "OBSERVATION_TYPE" `
-ItemId "OPTIONAL_INVENTORY_ITEM_ID" `
-ObjectId "OPTIONAL_GOVERNED_OBJECT_ID" `
-Message "OPTIONAL_MESSAGE" `
-Reason "OPTIONAL_REASON" `
-Repeat -Cooldown COOLDOWN_SECS
}
Action 'Object' {
# Perform single object observation
param($Order)
# TODO: implement single object observation
return New-ObservationResult `
-Table "TABLE_NAME" `
-PartitionKey "PARTITION_KEY" `
-ItemId "INVENTORY_ITEM_ID" `
-ObjectId "OPTIONAL_GOVERNED_OBJECT_ID" `
-Observation @{ OPTIONAL_KEY_VALUE_PAIRS = "..." } `
-ParentRefs @( "OPTIONAL_PARENT_OBJECT_ALIASES" ) `
-ChildRefs @( "OPTIONAL_CHILD_OBJECT_ALIASES" ) `
-Message "OPTIONAL_MESSAGE" `
-Reason "OPTIONAL_REASON"
return New-ObservationError `
-ObservationType "OBSERVATION_TYPE" `
-ItemId "OPTIONAL_INVENTORY_ITEM_ID" `
-ObjectId "OPTIONAL_GOVERNED_OBJECT_ID" `
-Message "OPTIONAL_MESSAGE" `
-Reason "OPTIONAL_REASON" `
-Repeat -Cooldown COOLDOWN_SECS
}
Action 'ArbitraryActionName' {
param($Order)
}
}
Observation Orders
Full List Observation
Sample
{
"OrderId": "dc720478-d3ad-4003-9d45-35434e9ff4bc",
"ObservationType": "M365UserLicense/List",
"Payload": {
"delta": false
}
}
Delta List Observation
{
"OrderId": "dc720478-d3ad-4003-9d45-35434e9ff4bc",
"ObservationType": "M365UserLicense/List",
"Payload": {
"delta": true
}
}
Single Object Observation
Sample
{
"OrderId": "dc720478-d3ad-4003-9d45-35434e9ff4bc",
"ObservationType": "M365UserLicense/Object",
"Payload": {
"__NativeId": [
"f30db892-07e9-47e9-837c-80727f46fd3d",
"3218bdff-cfd8-4d36-bce9-492f2cd21b92"
],
"__ObjectId": "6ee2b7ef-d64e-4e15-9bf8-6fcb2be61d08",
"__MasterItemKey": "[\"Group\",\"License_FlowFree\",\"FLOW_FREE\"]",
"__InventoryItemId": "f30db892-07e9-47e9-837c-80727f46fd3d:3218bdff-cfd8-4d36-bce9-492f2cd21b92",
// all "IsSpec" fields from the target object
"id": "f30db892-07e9-47e9-837c-80727f46fd3d:3218bdff-cfd8-4d36-bce9-492f2cd21b92",
"license": "FLOW_FREE",
"user": "",
"group": "License_FlowFree",
"LicenseAssigned": true,
"licenseType": "Group",
"licenseActive": true
}
}
Minimal Example
Observer Script
# ./Scripts/Observers/xMinimal.Observer.ps1
Observer 'Minimal' {
Init {}
Shutdown {}
Action "Hello" {
param($Order)
$name = $Order.Payload["name"]
return New-ObservationResult -Table 'HelloWorld' -PartitionKey 'Greetings' -ItemId $name `
-Observation @{ message = "Hello ${name}!" } -Reason "Observed"
}
}
Script Binding
// appsettings.json
{
"ScriptBindings": {
"Observations": {
"Minimal/Hello": {
"Observer": "./Scripts/Observers/xMinimal.Observer.ps1",
"Action": "Hello"
}
}
}
// ...
}
Order Payload
Property Payload is mandatory and cannot be changed. Add your values within Payload
// Scripts/mocks/minimal-hello-order.json
{
"Payload": {
"name": "World"
}
}
Debugger Parameters
# Scripts/DebugObserverScript.ps1
param(
# Select your action
[string] $Action = 'Minimal/Hello',
# You can export a governed object via RestAPI and provide it as JSON file.
[string] $MockFile = './mocks/minimal-hello-order.json',
# Must provide the appsettings.json to have the same settings for script invocation.
[string] $AppConfig = '../appsettings.json'
)