Public/New-UTCMMonitor.ps1
|
function New-UTCMMonitor { <# .SYNOPSIS Creates a new UTCM configuration monitor for automated drift detection. .DESCRIPTION Creates a configurationMonitor via POST /beta/admin/configurationManagement/configurationMonitors. Monitors run periodically (every 6 hours at fixed GMT times: 6 AM, 12 PM, 6 PM, 12 AM) and compare the current tenant configuration against the specified baseline. The baseline defines which resources and property values to monitor. When a property drifts from its desired value, the API records a configurationDrift that can be queried via Get-UTCMDrift. .PARAMETER DisplayName Friendly name for the monitor. Required. .PARAMETER Description Optional description. .PARAMETER BaselineDisplayName Friendly name for the baseline attached to the monitor. Default: same as monitor DisplayName. .PARAMETER BaselineDescription Optional description for the baseline. .PARAMETER BaselineResources Array of hashtables defining resources to monitor. Each hashtable must have: - displayName (string): friendly name for this resource instance - resourceType (string): UTCM resource type (e.g., microsoft.exchange.sharedmailbox) - properties (hashtable): key-value pairs of the desired configuration state .PARAMETER Parameters Optional hashtable of key-value pairs that can be referenced in the baseline. .OUTPUTS PSObject representing the created configurationMonitor. .EXAMPLE $resources = @( @{ displayName = 'TestSharedMailbox Resource' resourceType = 'microsoft.exchange.sharedmailbox' properties = @{ DisplayName = 'TestSharedMailbox' Alias = 'testSharedMailbox' Identity = 'TestSharedMailbox' Ensure = 'Present' PrimarySmtpAddress = 'testSharedMailbox@contoso.onmicrosoft.com' } } ) New-UTCMMonitor -DisplayName 'Exchange Monitor' -BaselineResources $resources .EXAMPLE # Monitor an accepted domain stays present $resources = @( @{ displayName = 'Accepted Domain' resourceType = 'microsoft.exchange.accepteddomain' properties = @{ Identity = 'contoso.onmicrosoft.com' DomainType = 'InternalRelay' Ensure = 'Present' } } ) New-UTCMMonitor -DisplayName 'Domain Monitor' -Description 'Ensure domain stays present' -BaselineResources $resources #> [CmdletBinding(SupportsShouldProcess = $true)] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $DisplayName, [string] $Description, [string] $BaselineDisplayName, [string] $BaselineDescription, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [hashtable[]] $BaselineResources, [hashtable] $Parameters ) if (Get-Command -Name Ensure-GraphConnection -ErrorAction SilentlyContinue) { Ensure-GraphConnection } if (-not $BaselineDisplayName) { $BaselineDisplayName = "$DisplayName Baseline" } # Build baseline resource objects $resourceObjects = foreach ($res in $BaselineResources) { if (-not $res.displayName -or -not $res.resourceType -or -not $res.properties) { throw "Each BaselineResources entry must have 'displayName', 'resourceType', and 'properties' keys." } @{ displayName = $res.displayName resourceType = $res.resourceType properties = $res.properties } } $body = @{ displayName = $DisplayName baseline = @{ displayName = $BaselineDisplayName resources = @($resourceObjects) } } if ($Description) { $body['description'] = $Description } if ($BaselineDescription) { $body['baseline']['description'] = $BaselineDescription } if ($Parameters) { $body['parameters'] = $Parameters } if (-not $PSCmdlet.ShouldProcess($DisplayName, "Create UTCM configuration monitor")) { return } if (Get-Command -Name Write-Log -ErrorAction SilentlyContinue) { Write-Log -Message ("Creating UTCM monitor: {0} (resources={1})" -f $DisplayName, ($resourceObjects.Count)) -Color Cyan } $result = Invoke-GraphRequestWithRetry -Method 'POST' -Uri $script:ConfigurationMonitorsUri -Body $body if (Get-Command -Name Write-Log -ErrorAction SilentlyContinue) { Write-Log -Message ("Monitor created: {0} (id={1}, status={2})" -f $result.displayName, $result.id, $result.status) -Color Green } return $result } |