Resetting Azure AD User Passwords

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 "" -NewPassword "SuperSecretPassword01"

Easy… but wait:

One does not simply reset a password meme

Don’t forget to force the user to change the new password at the first logon:

Set-MSOLUserPassword -UserPrincipalName "" -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:

CSV file with a list of Azure AD user accuont with properties, opened in Excel

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
Screenshot with the Get-MSOLUser PowerShell cmdlet to get the password change timestamp of the AzureAD users

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 ''"
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
Screenshot which demonstrates how to use the RandomPassword function which auto-generates a password.
  • 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

Leave a Reply

Your email address will not be published. Required fields are marked *