Version History:
2020.11.17.2338 - Added API Url params
2020.10.23.1408 - updated reference to Service-StatusBag
2020.10.06.1550 - Added CD_SkuPartNumberRegEx
2020.10.02.1141 - Added Service-FailureBag function. Added logging.
2020.09.29.1445 - Modified to produce monitor type-specific PBs for each instance so that PB data is specific to the mon that will use it. (will provide more streamlined State Change tab details in HealthExplorer)
2020.09.28.1444 - Moved TLS function call higher before access token retrieval
2020.09.17.0912 - Polishing.
2020.09.16.1150 - Tyson, revised for MP. Made one universal script to accommodate any mailflow direction.
Requirements: Must have an Azure application registered and have the following:
Delegated permissions, Sites.Read.All
ClientID & Application Secret
===============================================================================================================================================================
#>
# Comma-separated list of event IDs, script will only write to log for these EventIDs. This is a way to only write specific events. Only valid if $WriteToEventLog parameter is 'true'.
[string]$EventIDFilter,
# Comma-separated list of .ps1 files to load
[string]$PoshLibraryPath,
# This is a clever way to utilize the exact same script for both rule/mon and agent tasks.
[Parameter(Mandatory=$false,
ValueFromPipeline=$false,
ValueFromPipelineByPropertyName=$false,
ValueFromRemainingArguments=$false)]
[ValidateSet('PropertyBag', 'Serialized')]
[string]$ScriptOutputType = 'PropertyBag',
# Azure tenant
[string]$TenantName,
[string]$TLSVersion,
# Typically this is the name of the workflow calling this script. Should be set to the name of the probe/WA if being used by both rules/mons so as not to break cookdown.
# Keep in mind that datasource params need to be identical for cookdown to work.
[string]$WorkflowName,
# type:string. SCOM bool params are different than Posh bool. Will get converted to Posh bool below.
[string]$WriteToEventLog = 'false'
)
# Set defaults for event filters. Apparently setting this in the Params declaration did not work.
If (-NOT $EventIDFilter) {
$EventIDFilter = "9990,9991,9992,9995,9996,9997,9998,9999"
}
$ScriptName = 'M365SLIC.LicenseMon.ps1'
[bool]$WriteToEventLog = [System.Convert]::ToBoolean($WriteToEventLog)
$Testing = $false
$NameSpace = "License"
######################### FUNCTIONS ############################
################################################################
Function Load-Library {
Param (
[string]$PoshLibraryPath
)
$ErrorActionPreference = 'STOP'
If ($PoshLibraryPath ){
ForEach ($Path in $PoshLibraryPath.Split(',') ){
Try {
If (($Path.Length) -AND ($Path -notmatch '^-1$')) {
. $Path
}
} Catch {
Write-Host "Line [$($MyInvocation.ScriptLineNumber )]: Error loading PoshLibrary at path:[$($Path)]. This is likely to cause many other dependent functions to fail. `n`nError data: $($_)`n`n"
}
}
}
$ErrorActionPreference = 'CONTINUE'
}
################################################################
############## TESTING ##############
<# #Run this as needed when testing
# Encode user data/passwords in current test user context
$M365_ClientSecret = Encode-UserData $M365_ClientSecret_PLAINTEXT
$M365_AccountPassword = Encode-UserData $M365_AccountPassword_PLAINTEXT
$error.Clear()
}
$Msg =@"
Retrieved License object(s):
$($Licenses.Value.skuPartNumber | Out-String)
"@
LogIt -EventID 9992 -Type $info -Msg $Msg -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
} Catch {
$Message = "Unable to get $($NameSpace) object(s) from Graph URL: [$($LicenseUrl)]. See error data. Will output connectivity failure bag data. Exiting."
LogIt -EventID 9995 -Type $warn -Msg $Message -Proceed $true -LINE $(_LINE_); $Error.Clear()
# Output service bag
Service-StatusBag -Message $Message -Status FAILURE
Exit
}
#$Skus = $Licenses.Value
# If regex is provided (used for Serial output task PA). Otherwise all objects will match an empty comparison.
$Skus = $Licenses.Value | Where-Object {$_.skuPartNumber -match $CD_SkuPartNumberRegEx }
#----------------------------------------
# Build bag for LicensesConsumed
LogIt -EventID 9992 -Type $info -Msg "Proceed to build bags for bag category: [LicensesConsumed]..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
ForEach ($SkuPN in $Skus) {
LogIt -EventID 9992 -Type $info -Msg "Build (LicensesConsumed) bag for SKU [$($SkuPN.skuPartNumber)]..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
$Units = [math]::Max(( $SkuPN.PrepaidUnits.Enabled - $SkuPN.ConsumedUnits),0)
[double]$Percent = 0