Um die guppenbasierte Lizenzierung überwachen zu können bietet Microsoft bis jetzt keine Möglichkeit. Einzig über das Azure Portal oder via PowerShell kann der aktuelle Status überprüft werden. Ein automatische Benachrichtigung erhält man allerdings leider nicht.
Im Portal sieht man die Lizenzierungsfehler zum Beispiel an einer Gruppe. Dort sieht man den betroffenen Benutzer und den Grund des Fehlers.

Einen sehr guten Überblick über den Status, kann man ansonsten auch via PowerShell in Erfahrung bringen. Microsoft stellt umfangreiche Möglichkeiten zum Troubleshooten der guppenbasierten Lizenzierung via PowerShell bereit.
https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-ps-examples
Um dieses Problem etwas zu entschärfen, habe ich mir die Mühe gemacht einen PRTG Sensor zu erstellen, der die gruppenbasierte Lizensierung überwachen kann.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | <# =================================================================================== Paessler PRTG Sensor to check AAD Group Licensing =================================================================================== Autor: Stefan Redlin Script: Get-GroupLicensesErrors.ps1 Version: 1.0 Date: 20.05.2019 Environment: Windows Server 2016 Scriptpath: C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML Scripttype: EXE/Script Advanced https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-ps-examples #> [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $O365User, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $O365Pass ) #Check for 32 bit environment if ($env:PROCESSOR_ARCHITECTURE -eq "x86") { # Launch script in 64 bit environment $ScriptParameter = "-O365User '$O365User' -O365Pass '$O365Pass' " if ($IncludeSku -ne $null) { $ScriptParameter += "-IncludeSku '$($IncludeSku -join "','")' " } if ($ExcludeSku -ne $null) { $ScriptParameter += "-ExcludeSku '$($ExcludeSku -join "','")' " } if ($ShowMySkus) { $ScriptParameter += "-ShowMySkus " } # Use Sysnative virtual directory on 64-bit machines Invoke-Expression "$env:windir\sysnative\WindowsPowerShell\v1.0\powershell.exe -file '$($MyInvocation.MyCommand.Definition)' $ScriptParameter" Exit } <# Function to raise error in PRTG style and stop script #> function New-PrtgError { [CmdletBinding()] param( [Parameter(Position=0)][string] $ErrorText ) Write-Host "<PRTG> <Error>1</Error> <Text>$ErrorText</Text> </PRTG>" } # Create credential object $O365Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $O365User, ($O365Pass | ConvertTo-SecureString -AsPlainText -Force) # Load Office 365 module try { Import-Module MSOnline -ErrorAction Stop } catch { New-PrtgError -ErrorText "Could not load PowerShell Module MSOnline" } # Connect to Office 365 using provided credential try { Connect-MsolService -Credential $O365Cred -ErrorAction Stop } catch { New-PrtgError -ErrorText "Error connecting to your tenant. Please check credentials" } $xmlOutput = '<?xml version="1.0" encoding="UTF-8" ?><prtg>' $Groups = Get-MsolGroup -All | Where {$_.Licenses} foreach($Group in $Groups){ $Groupmembers =Get-MsolGroupMember -All -GroupObjectId $Group.ObjectId $totalCount = 0; $licenseAssignedCount = 0; $licenseErrorCount = 0; $groupLicenses = $Group.Licenses | Select -ExpandProperty SkuPartNumber foreach($Groupmember in $Groupmembers){ $Users=Get-MsolUser -ObjectId $Groupmember.ObjectId foreach($User in $Users){ $totalCount++ if($user.Licenses | ? {$_.GroupsAssigningLicense -ieq $Group.ObjectId }) { $licenseAssignedCount++ } #check if user has any licenses that failed to be assigned from this group if ($user.IndirectLicenseErrors | ? {$_.ReferencedObjectId -ieq $Group.ObjectId }) { $licenseErrorCount++ } } } $xmlOutput = $xmlOutput + "<result> <channel>$($Group.DisplayName) - TotalUserCount</channel> <value>$($totalCount)</value> </result>" $xmlOutput = $xmlOutput + "<result> <channel>$($Group.DisplayName) - LicensedUserCount</channel> <value>$licenseAssignedCount</value> </result>" $xmlOutput = $xmlOutput + "<result> <channel>$($Group.DisplayName) - LicenseErrorCount</channel> <value>$licenseErrorCount</value> </result>" } $xmlOutput = $xmlOutput + "</prtg>" $xmlOutput |
Eine aktuelle Version des Sensors ist auch auf GitHub zu finden.
Was ist PRTG?
Die Software PRTG von der Firma Paessler ist eine klassische Monitoring Lösung. PRTG eignet sich für die Überwachung der Hardware, Server und der darauf ausgeführten Diensten. Die Software bringt von Haus aus schon ein umfassendes Repertoire an Sensoren mit. Fehlt ein Sensor, so lässt sich dieser mittels Skript hinzufügen.
Sensor importieren
Damit ein selbst erstellter Sensor in PRTG zur Auswahl steht muss dieser zuerst importiert werden. Dazu muss das Skript in den Ordner „C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML“ kopiert werden. Anschließend steht dieser in der Auswahl „EXE/Script Advanced“ zur Verfügung.
Gruppe erstellen
Um die verschiedenen Sensoren logisch aufzuteilen, wird zuerst eine Gruppe erstellt. Die Gruppe wird per Rechtsklick auf „Local Probe“ erstellt. Dies sieht dann wie folgt aus:

Die Gruppen dienen aber nicht nur der Übersicht, auch Einstellungen und Zugangsdaten können hier verwaltet werden.
Zugangsdaten hinterlegen
Damit der Sensor sich gegen den Tenant verbinden kann, werden die Zugangsdaten des globalen Administrators an der zuvor erstellen Gruppe hinterlegt. Dazu müssen die Einstellungen der Gruppe editiert werden. Da PRTG mit Variablen arbeitet, können die Daten zum Beispiel bei den Linux Credentials hinterlegt werden. Somit müssen die Daten nicht im Klartext im Skript verwendet werden.

Gerät erstellen
Nachdem die Gruppe angelegt worden ist, kann ein Gerät erstellt werden unterhalb dieses Gerätes werden die Sensoren angelegt.

Sensor erstellen
Um den Sensor nun hinzuzufügen muss der Sensortyp EXE/Script Advanced ausgewählt werden.

Die folgenden Werte müssen angepasst werden.
Sensorname | Gruppenbasierte Lizenzierung |
Exe/Script | Get-GroupLicensesErrors.ps1 |
Parameters | -O365User %linuxuser -O365pass %linuxpassword |
Die Konfiguration ist nachfolgend dargestellt.

Nachdem der Sensor erstellt wurde werden die lizensierten Gruppen im PRTG dargestellt.

Schwellwerte des Kanals editieren
Für jeden Kanal „<Gruppenname> – LicenseErrorCount“ müssen nun noch die Schwellwerte für den Fehlerstatus konfiguriert werden. In die Einstellungen kommt man indem man auf das Zahnrad hinter dem Kanal klickt. Wie die Einstellungen aussehen müssen wird im nachfolgendem Bild dargestellt.

Nachdem diese Einstellungen vorgenommen wurden zeigt PRTG eine Fehlermeldung an wenn ein Lizenzfehler in einem Kanal vorliegt.

So lässt sich einfach die gruppenbasierte Lizensierung überwachen.
Weitere PowerShell Sensoren für PRTG sind hier zu finden.