Mit Hilfe des Azure Portals können die Passworte von Benutzer-Konten im Azure AD oder Azure AD B2C zurückgesetzt werden (Option “Reset password”, nachdem ein Benutzer-Konto im Portal gewählt wurde). Leider wird dabei nur ein temporäres Passwort erstellt, welches der Benutzer bei der ersten Anmeldung durch ein neues Passwort ersetzen muss. Es ist nicht möglich ein Passwort fix vorzugeben, was aber z.B. für technische Konten nicht nur nützlich sondern auch erforderlich sein kann.

Ein Weg, dieses Problem zu lösen, bietet PowerShell mit dem Modul AzureAD:
https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0

Neben vielen anderen Funktionen, enthält das Modul das Cmdlet Set-AzureADUserPassword, welche die nötige Funktion bereitstellt.

Für ein Automations-Skript, das laufen soll, ohne, dass jedes Mal eine manuelle Anmeldung erforderlich ist, sind jedoch noch einige Vorbereitungen zu treffen:

  • Einrichten eines Service Principal (SP) Kontos, das später für die Anmeldung bei Azure AD verwendet werden kann.
  • Erstellen eines Zertifikats und Zuweisung an den Service Principal: Bei der Anmeldung mit der Service Principal ID dient das Zertifikat als Ausweis gegenüber Azure (anstelle eines Passworts). Daher das Zertifikat gut verwahren und wie ein Admin-Passwort behandeln!
  • Berechtigen des Service Principal als User Administrator im AD.

Im Azure Portal kann zunächst der Service Principal (SP) eingerichtet werden (auch über PowerShell möglich, aber als einmalige Aktion auch gerne im Portal). Zwar lauten die PowerShell-Cmdlets später auf den Begriff “ServicePrincipal”, im Azure AD sind das jedoch die “App registrations”, der SP ist also eine registrierte App:

Auf diesem Blade eine neue App registrieren. Nachdem die App registriert wurde, sind im Overview-Blade zur App die verschiedenen IDs aufgeführt, mit welchen die App (=SP) später identifiziert werden kann:

Die weiteren Schritte erfolgen dann mit PowerShell und müssen einmalig mit einem Konto ausgeführt werden, das die entsprechenden Admin-Berechtigungen im Ziel-AD hat!

Dazu kann innerhalb einer PowerShell-Session das Cmdlet Connect-AzureAD verwendet werden, ohne weitere Parameter. Es wird dann automatisch ein Dialog eingeblendet, der die Anmeldung mit einem Administrator-Konto ermöglicht. Hinweis: Beim Arbeiten mit Visual Studio Code erscheint dieser Dialog oft verdeckt hinter der VSC-Umgebung und muss erst in den Vordergrund geholt werden (z.B. mit Alt+TAB). Nach der Anmeldung können dann innerhalb der Session die nötigen Befehle ausgeführt werden.

Zunächst das Erstellen eines Zertifikats im Certificate-Store auf dem lokalen Computer, das dann sogleich exportiert wird (als DnsName den Namen des Azure AD angeben):

$certPath = "c:\temp\cert.pfx"
$certPass = "myStupidpa$$word"
$certPass = ConvertTo-SecureString -String $certPass -Force -AsPlainText

# Cert gültig bis
$notAfter = (Get-Date).AddYears(1)

# Erzeugen und exportieren
$thumb = (New-SelfSignedCertificate -CertStoreLocation cert:\CurrentUser\my -DnsName "myazuread.onmicrosoft.com" -FriendlyName "User Client Certificate" -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $notAfter).Thumbprint
Export-PfxCertificate -cert "cert:\CurrentUser\my\$thumb" -FilePath $certPath -Password $certPass

Das Zertifikat kann anschließend dem SP zugewiesen werden: Entweder über das Azure Portal (Option “Certificate & secrets” im Blade der App) oder per PowerShell. Hier die PowerShell-Variante:

# Zertifikat laden
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($certPath, $certPass)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

$currentDate = Get-Date
$endDate = $currentDate.AddYears(1)

# Für den Service Principal hochladen. Die $objectId kann im Azure Portal für die App ermittelt werden (siehe oben)
$objectId = "e7a9635b-bc48-461f-ae42-03fcca9a7039"
$app = Get-AzureADApplication -ObjectId $objectId
New-AzureADApplicationKeyCredential -ObjectId $app.ObjectId -CustomKeyIdentifier "PSUserManagement" -StartDate $currentDate -EndDate $endDate -Type AsymmetricX509Cert -Usage Verify -Value $keyValue

Der SP benötigt jetzt noch das Recht zum Administrieren von Benutzer Konten:

$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq "User Account Administrator"}
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $app.ObjectId

Nach diesen vorbereitenden Maßnahmen kann die PowerShell-Session geschlossen werden, welche unter dem administrativen AD-Konto ausgeführt wurde.

Für alle weiteren Aktionen meldet sich das Skript mit der SP ID und dem dafür ausgestellten Zertifikat bei Azure AD an. Die TenantId und die ApplicationId des SP können dort gefunden werden, wo auch bereits die objectId aufgeführt war (siehe oben). Der Thumbprint des Zertifikats ist entweder noch aus der letzten Session bekannt oder kann im lokalen Windows Zertifikats-Speicher ermittelt werden (Zertifikat in der Zertifikatsverwaltung doppel-klicken und dann auf dem Reiter “Details” des Eigenschaftendialogs das Feld “Fingerabdruck” suchen).

Connect-AzureAD -TenantId $tenantId -ApplicationId $appId -CertificateThumbprint $thumb

Jetzt das Konto suchen, dessen Passwort gesetzt werden soll. Hier eine Suche über den Anzeigenamen:

$userDisplayName = "Anton Vergesslich"
$users = Get-AzureADUser
$user = $users|Where-object DisplayName -eq $userDisplayName

Zu guter Letzt das Setzen des neuen Passworts:

$userPass = "dasNeuePW!"
$userPass = ConvertTo-SecureString -String $userPass -Force -AsPlainText
Set-AzureADUserPassword -ObjectId $user.ObjectId -Password $userPass -EnforceChangePasswordPolicy $false -ForceChangePasswordNextLogin $false

Mit den beiden Optionen -EnforceChangePasswordPolicy und -ForceChangePasswordNextLogin kann eingestellt werden, ob das Passwort den Änderungsregeln unterworfen sein soll und/oder ob es bei der nächsten Anmeldung durch den Benutzer geändert werden muss.

Auch viele andere Operationen zur AD- und Benutzer-Verwaltung sind jetzt natürlich unter Verwendung der SP-Anmeldung unter PowerShell möglich!