Check your M365 Licenses with Azure Automation

Hallo zusammen,

Meines Wissens gibt es keine automatischen Warnungen, wenn die Anzahl der zugewiesenen Lizenzen überschritten werden. Auch ist es nicht möglich eine Art Schwellwert für eine Warnung anzugeben, um allenfalls neue Lizenzen zu bestellen.

Die gekauften M365 Lizenzen lassen sich ja mit dem AzureAD PowerShell Modul gut auslesen.

Connect-AzureAd
Get-AzureADSubscribedSku | Select -Property Sku*,ConsumedUnits -ExpandProperty PrepaidUnits | ft

Ich habe das ganze mal mit einem Azure Automation Account umgesetzt. Dazu braucht es das AzureAD oder AzureADPreview Module aus der Gallery

Nun kann das Runbook vorbereitet werden.

Mit "Edit" gelangt man in den SourceCode Editor

Ich habe folgendes PowerShell Script geschrieben. Mit dem Hashtable $MinLicenses kann man die Schwellwerte festlegen. Die Schwierigkeit ist meist nur den SKU String zu finden. Hier hilft folgender Link: https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference

Die AzureAD Application benötigt im Minimum "Directory Reader" Permissions.

Write-Output "Connecting to AzureAD"
$connection = Get-AutomationConnection –Name AzureRunAsConnection
$tenant = "<yourm365Tenant>.onmicrosoft.com"
Connect-AzureAD -CertificateThumbprint $connection.CertificateThumbprint -ApplicationId $connection.ApplicationID -Tenant $Tenant

#Connect-AzureAD -AccountId 
#Get-AzureADSubscribedSku | Select -Property Sku*,ConsumedUnits -ExpandProperty PrepaidUnits | ft
"Getting Licenses"
$Licenses = Get-AzureADSubscribedSku | Select -Property Sku*,ConsumedUnits -ExpandProperty PrepaidUnits

#Define Minimum Licenses
$MinLicenses = @{}
$MinLicenses.add( 'MCOEV'"3" )
$MinLicenses.add( 'WINDOWS_STORE'"20" )

#Create HTML Output
"Creating HTML Output"
$Output = @()
$Output += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
$Output += '<html xmlns="http://www.w3.org/1999/xhtml">'
$Output += '<head>'
$Output += '<title>HTML TABLE</title>'
$Output += '<head></head>'
$Output += '<body>'
$Output += '<table>'
$Output += '<colgroup><col/><col/><col/><col/><col/><col/></colgroup>'
$Output += '<tr><th>SkuId</th><th>SkuPartNumber</th><th>ConsumedUnits</th><th>Enabled</th><th>Suspended</th><th>Warning</th><th>Available</th></tr>'

#Iterate through Licenses
Foreach ($Line in $Licenses)
{

            $SKUID = $Line.SkuID
            $SKU = $Line.SkuPartNumber
            $ConsumedUnits = $Line.ConsumedUnits
            $PrepaidUnits = $Line.Enabled
            $AvailableUnits = $PrepaidUnits - $ConsumedUnits
            $Suspended = $Line.Suspended
            $Warning = $Line.Warning
            
            $RequiredMinimum = $MinLicenses["$SKU"]

            #Red if ConsumedUnits > PrepaidUnits
            If ($ConsumedUnits -gt $PrepaidUnits)
            {
                $Value = '<tr bgcolor="#ff0000"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                $Output += $value

            } else {
                If ($RequiredMinimum -ne $null)
                {
                    #Yellow if AvailableUnits < Required Minimum
                    If ($AvailableUnits -lt $RequiredMinimum)
                    {
                        $Value = '<tr bgcolor="#ffff00"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                        $Output += $value
                    } else {
                        #Yellow if Suspended or Warning otherwise Green
                        If ($Suspended -ne "0" -OR $Warning -ne "0")
                        {
                            $Value = '<tr bgcolor="#ffff00"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                        } else {
                            $Value = '<tr bgcolor="#00ff00"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                        }
                        $Output += $value                        
                    }
                } else {
                    #Yellow if Suspended or Warning otherwise Green
                    If ($Suspended -ne "0" -OR $Warning -ne "0")
                    {
                        $Value = '<tr bgcolor="#ffff00"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                    } else {
                        $Value = '<tr bgcolor="#00ff00"><td>' + $SKUID + '</td><td>' + $SKU + '</td><td>' + $ConsumedUnits + '</td><td>' + $PrepaidUnits + '</td><td>' + $Suspended + '</td><td>' + $Warning + '</td><td>' +$AvailableUnits + '<td></tr>'
                    }
                    $Output += $value
                }
            }
}

#Add-Content -Path $htmlfile -Value '</table></body></html>'
$Output += '</table></body></html>'

#Convert Array to String
[string]$HTMLBody = $Output

#Send Mail
"Sending Mail"
$from = "licenseadmin@runbook.yourdomain.tld"
$to = "recipient@yourdomain.tld"
$subject = "M365 License Check"
$smtpserver = "<m365tenant>.mail.protection.outlook.com"
$port = "25"
$Body = $HTMLBody
Send-MailMessage -From $From -To $to -Subject $Subject -Body $Body -BodyAsHtml -SmtpServer $SMTPServer -port $port 

Der Testlauf hat jedenfalls geklappt

Und so sieht das Mail dann aus

Jetzt nur noch einen Schedule definieren

Täglich um eine bestimmte Zeit ausführen

Grüsse
Andres Bohren