You can set the password of an Azure AD user account (= Office 365 user account) easily with PowerShell. First of all, let’s choose the right API for this – modern AzureAD PowerShell module, or old style MSOL (MSOnline) PowerShell module? Well, in this particular case, I prefer the MSOL. I will explain the reasons for this later in this post. So let’s reset a user’s password:
Set-MSOLUserPassword -UserPrincipalName "vanterpo@up-in-the.cloud" -NewPassword "SuperSecretPassword01"
Easy… but wait:
Don’t forget to force the user to change the new password at the first logon:
Set-MSOLUserPassword -UserPrincipalName "vanterpo@up-in-the.cloud" -NewPassword "SuperSecretPassword01" -ForceChangePassword $true
Bulk Password Resets
Now we are set to go for some bulk action. Please imagine that you get a csv list with user data whose passwords you have to set to an initial password. The users should then set their password to their own value when they log in for the first time:
The script to read out that CSV and set the passwords:
$inital = "Initial$4680"
Import-CSV userlist.csv | % {
$upn = $_.UserPrincipalName
Set-MSOLUserPassword -UserPrincipalName $upn -NewPassword $inital -ForceChangePassword $true
}
If you have difficulties importing the CSV, maybe you need the parameter Import-CSV -Delimiter “;” or something like that (if you didn’t separate the columns in the file with commas….). The script assumes that in the CSV file, there is a column header in the first line, specifying the UPN column with “UserPrincipalName” (as shown in the Excel screenshot). Maybe you have to adjust this also. And obviously, this script does not check if the UPNs in the file really exists in the tenant.
Avoid the identical standard Password
It’s time for individualism! Obviously, setting the same inital password for everyone is not the optimal choice to say the least. So let’s use the auto-generation of the Set-MSOLUserPassword (which is active if you omit the -NewPassword parameter). The auto-generated password will be the output of the comdlet. We just have to write it out to a CSV file:
$out = ".\user_passwords.csv"
Set-Content $out "UserPrincipalName,Password"
Import-CSV userlist.csv | % {
$upn = $_.UserPrincipalName
$password = Set-MSOLUserPassword -UserPrincipalName $upn -ForceChangePassword $true
Add-Content $out "$upn,$password"
}
Annotation: Please don’t be disappointed that I didn’t use the more elegant Export-CSV here. That only results in ugly quotation marks in the output file, therefore quick and dirty with Set-Content / Add-Content.
Check the Results
Next thing is to check when the users did actually change their password:
Get-MSOLUser -All | Select UserPrincipalName,LastPasswordChangeTimestamp
Why not the modern AzureAD module ?
I usually prefer the AzureAD Powershell module to the MSOL (MSOnline) module. It is generally faster … and it will be the module on which Microsoft will concentrate on further development in the future. But when it comes to scripting with passwords, I stick to the old module. You can do the same with AzureAD cmdlets, but it’s just a bit more inconvenient:
- AzureAD cmdlets for user manipulation need always ObjectIDs, but if you do bulk password operations, you most probably have a list of UPNs. And then you have to convert this list into ObjectIDs first.
- AzureAD cmdlets for requiring you to first convert passwords to a secure string. This normally is a good thing because it strengthens the security…. but only if you enter a password in an interactive dialog. In our case, the passwords which are to be set, they exist as pure string values anyway, even if they are then converted into secure strings.
So the example for only one user account and an explicite pasword gets much more complicated:
$password = ConvertTo-SecureString 'SuperSecretPassword01' -AsPlainText -Force
$user = Get-AzureADUser -Filter "UserPrincipalName eq 'vanterpo@up-in-the.cloud'"
Set-AzureADUserPassword -ObjectId $user.ObjectID -Password $password -ForceChangePasswordNextLogin $true
- AzureAD cmdlets cannot auto-generate a password for you. You must pass a value for the password, if you do not, a dialog comes up and asks you to enter some string. So, if you need to set bulk passwords with auto-generated values, you have to create your own random passwords. Maybe like this (imitating Office 365’s scheme for auto-generating passwords: 1 capital letter, 2 lowercase letters, 5 digits):
Function RandomPassword() {
$pw = ""
$pw += ([char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | Get-Random)
$pw += $(1..2 | % { [char[]]"abcdefghijklmnopqrstuvwxyz" | Get-Random }) -join ""
$pw += $(1..5 | % { [char[]]"0123456789" | Get-Random }) -join ""
Return $pw
}
- AzureAD do not show the time and date of the last password change. But good old MSOL API shows us this property:
Get-MSOLUser -All | Select UserPrincipalName,LastPasswordChangeTimestamp