Forcing password change seems to be a frequent request, so here’s how to do it in Office 365. To force a user to change his password on next login, without actually changing the password on his behalf:
Set-MsolUserPassword -UserPrincipalName user@domain.com -ForceChangePasswordOnly $true -ForceChangePassword $true
To force all users to change their password:
Get-MsolUser -All | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
To force a group of users to change their passwords:
Get-MsolUser -All | ? {$_.Country -eq "USA"} | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
Or use any other criteria, as appropriate. Note that you have to use both the ForceChangePassword and ForceChangePasswordOnly parameters. If you skip the ForceChangePasswordOnly, a new password will be generated for the user and you will need to distribute it.
Speaking of this scenario, here’s an old script I used to reset passwords in the format used by Office 365 (i.e. 8 char password, starting with a Capital letter, three lowercase letters and four numbers):
$users = Get-MsolUser –All $arrMsolUserData = @() foreach ($user in $users) { if ($user.UserPrincipalName -eq "user@tenant.onmicrosoft.com") { continue; } $objProperties = New-Object PSObject $Password = "" $Password += ([char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | Get-Random) $Password += $(1..3 | % { [char[]]"abcdefghijklmnopqrstuvwxyz" | Get-Random }) -join "" $Password += $(1..4 | % { [char[]]"0123456789" | Get-Random }) -join "" Set-MsolUserPassword -UserPrincipalName $user.UserPrincipalName -NewPassword $Password -ForceChangePassword $false Add-Member -InputObject $objProperties -MemberType NoteProperty -Name "UserPrincipalName" -Value $user.UserPrincipalName Add-Member -InputObject $objProperties -MemberType NoteProperty -Name "Password" -Value $Password $arrMsolUserData += $objProperties } $arrMsolUserData $arrMsolUserData | Export-Csv -Path "C:\passwords.csv" –NoTypeInformation
You can exclude the admin account or just filter out the users you need instead of using All. The list of users and new passwords will be exported to CSV, which you can use to redistribute them. Have fun 🙂
P.S. An updated version of the script that uses the Graph SDK for PowerShell can be found here.
Do you know a way in Graph that will force a password change at the next login but I don’t have to reset the password to something new with the command?
You can find examples of that in the linked article.
Thanks you the steps were really simple and helpful.
Vasil, thank you for this post!
Use your second cmdlet to force a password reset for everyone the next time they log in. Is there a way to find users who must change their password on next logon but haven’t run through the process yet?
Not seeing a property from MsolUser or AzureAdUser jump out as the ‘must change password on next logon’ flag, so looking for something similar to AD that I can use.
You can get this via the Azure AD Module:
Or Graph:
I am not sure if this forum is still active, but is there a way to force a password change for all users of a sub-domain only?
Could I maybe use this and change the Get-MsolUser -All to only get sub-domain users?
Get-MsolUser -All | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
Try using Get-MsolUser -DomainName sub.domain.com. Or filter the users in any other way.
Hello Vasil,
I know this topic is old but I am trying to see how can I force users in a specific group to change their password at next logon through PowerShell. Would appreciate some guidance.
Thanks
Simply replace the first two lines in the sample code, Get-MsolGroupMember should do in your case.
Thank you for the information exactly what I Needed
I’ve tested this and there seems a 10 minute lag before the force password change kicks in which is weird. Tested using the Set-MsolUserPassword -serprincipalname bob@test.net -ForceChangePassword $true -ForceChangePasswordOnly $True
Thanks for the post, very helpful.
I was wondering if there’s a way to force a password reset on users who still use a default password? for example forcing those who use a 12345123 to reset theirs?
Ignore this comment please as it’s repetitive. just noticed your reply to the last comment.
ThanksVasil.
Hi,
Thanks for the amazing post, Large number of users in my tenant still use a default password which is related to their upn, i want to warn them by forcing a temporary block of accounts for say 2 or 4 hours on certain day if they keep using the default password. how should i do that? how to get users who are still using the default password and how to block them based on this criteria.
Thanks
Nothing in O365 can do this afaik.
Good Luck Haitham, I think Force change password is very good now.
Hi,
We have an issue whereby users are able to access O365 with expired passwords. I investigated and found this explanation from a Microsoft forum: “if a user is in the scope of password synchronization, the cloud account password is set to Never Expire. Which means users can continue to sign in to their cloud services by using a synchronized password that is expired in your on-premises environment. Their cloud passwords are updated the next time you change the password in the on-premises environment –> https://answers.microsoft.com/en-us/msoffice/forum/msoffice_o365admin-mso_password-mso_o365b/office-365-hybrid-log-in-after-password-expired/ac61216d-85fd-44f5-911f-a76c35fb4a94
My question is: How can we ensure that expired passwords are not able to be used on O365?
Thanks.
ST
You can use a solution such as the one detailed here: https://www.undocumented-features.com/2017/09/15/use-aad-connect-to-disable-accounts-with-expired-on-premises-passwords/
Truly a solution written by a programmer, for a programmer, with no empathy for how a non-programmer will receive. Where does one even go to paste this code? I guess if you’re a programmer you just know.
Without wanting to sound like an a*hole, if you don’t recognise PowerShell commands, and basic understanding of a PowerShell script…. you probably shouldn’t be here, This should be the bread and butter of all System Admins and if you’re not comfortable with it, it’s high time you got comfortable with it cause PowerShell is amazing, and is well worth investing your time in getting your head around it.
Not a programmer, yet I understand it.
Great Post
Well I am a programmer but work more on the linux side.
And I am working in a small company that uses o367 so that we don’t have technical hazzles.
As one of my colleages was breached I would like to reset the passwords of my 15 colleagues.
I can start powershell. But I wonder already how/where I sign in so that powershell knows which users to list.
But already entering
GET-MsolUser
the shell tells me
“The term ‘Get-MsolUser’ is not recognized as the name of a cmdlet,”
No disrespect folks, but it takes a lot less time to do a simple google search for said error, than to enter comments here…
Here’s the module you need: https://www.powershellgallery.com/packages/MSOnline/1.1.183.57
I used this description to get powershell set up:
https://docs.microsoft.com/en-us/microsoft-365/enterprise/connect-to-microsoft-365-powershell?view=o365-worldwide.
With this link and the link Vasil provided as well in answer to my post, this should be doable for everybody 🙂
Thanks a lot, Vasil!
Just a quick note, if you have “PasswordNeverExpires” set to “True” this won’t do a damn thing.
In my case I had to first run:
> Get-MsolUser -All | Set-MsolUser -PasswordNeverExpires $false
Then run
> Get-MsolUser -All | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
I’ve had opposite experience.
Coupled with Revoke-AzureADUserAllRefreshToken it does what is intended. User sessions are disrupted and next sign in forces password change. Worked for my tenant even though Get-MsolUser property PasswordNeverExpires is indeed $True.
Hi Tom, did you run the Revoke-AzureADUserAllRefreshToken separately or included it as part of Get-MsolUser -All | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
thanks,
Krisen
Not familiar with all these cmdlet, but Revoke-AzureADSignedInUserAllRefreshToke would be easier than Revoke-AzureADUserAllRefreshToken ? We don’t have to prepare an account CSV list ? Right ?
Could you provide a script that is going to force such change for all the members of a specific groups?
Get-MsolUser -All | ? {$_.Country -eq “USA”} | Set-MsolUserPassword -ForceChangePasswordOnly $true -ForceChangePassword $true
if a group is 1234@contoso.org….. how the script should look like
See the comment by Daniel above…
Hey Vasil,
I’m trying to execute a script that will force a specific Group in Azure to change their passwords upon next login, however, after executing it against a test group that just includes myself, it doesn’t seem to be doing anything.
Can you assist in identifying what I may be doing wrong?
$users = Get-MsolGroupMember -GroupObjectID “”xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx””
foreach ($users in $user) {
Set-MsolUserPassword -UserPrincipalName “$users@domain.com” -ForceChangePasswordOnly $true -ForceChangePassword $true
}
Any & all input would be greatly appreciated!
Your loop is all wrong, try something like this:
foreach ($user in $users) {
Set-MsolUserPassword -UserPrincipalName $user.UserPrincipalName -ForceChangePasswordOnly $true -ForceChangePassword $true
}
hey there
trying to get this working but im getting error when running this. Need to force the password change for users in a group. ive copied what you have here but no joy
cannot bind argument to parameter userprincipalname because it is null
a powershell virgin meself, ive done just a copy of what you have in your reply to Daniel.
Did you set the $users variable first?
The error was saying the upn is null. There is no UPN field being populated when you run the command.
the group doesnt seem to have this column of upn. i got it working by setting it to use the email
$users = Get-MsolGroupMember -GroupObjectID “”xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx””
foreach ($user in $users) {
Set-MsolUserPassword -UserPrincipalName $user.EmailAddress -ForceChangePasswordOnly $true -ForceChangePassword $true
Is there a risk in using the email address rather than the UPN for this?
Oh you’re right, it should be using EmailAddress. That’s what happens when I try to write some script sample from memory 🙂
haha all good Vasil, appreciate your help. Last one for ye
i know upn and email can be different. Could i make a mess by running it with the email, is there a risk using the emailaddress instead of UPN?
Should be fine, as they are all unique within the tenant.
Hello Vasil, do you know if this will work for a hybrid environment?
Define Hybrid? If passwords are managed/synced from on-premises, you need to change them there.
You can deactivate the option to require a user to change the password when starting the first time, by powershell and in bulk. ?????
Yes, just use the -ForceChangePassword $false switch
Is there a way to schedule the force password change in Office 365 to be every six months?
Just configure the password policy: https://docs.microsoft.com/en-us/powershell/module/msonline/set-msolpasswordpolicy?view=azureadps-1.0
Thanks for the response! If people change their passwords outside of the 6th month interval, will that stagger the forced password changes per user? If so that is my dilemma.
It’s a rolling window, the period gets reset every time the user changes his password.
You can deactivate the option to require a user to change the password when starting the first time, by powershell and in bulk. ?????
How can I set the flag for password reset on all users on next logon EXCEPT a few I want to name?
Simply provide a suitable list of users for the $user variable.
Dave, you have to use Set-MsolUserPassword command, not Set-MsolUser
I’ve got the MSOnline module installed but I’m getting an error message:
A parameter cannot be found that matches parameter name ‘ForceChangePasswordOnly’
Which version of the module though?
Can this be done in powershell if not using Azure AD? I use powershell to set mailbox permissions, etc. but when I attempt these commands I get an error that states ‘Set-MsolUserPassword’ in is not recognized as the name of a cmdlet… ObjectNotFound, CommandNotFoundException.
Any help would be appreciated.
Thank you.
You need the MSOnline module (Install-Module MSOnline).
Great work, thank you. Has anyone managed to do this from a CSV file for force password change on next logon?
Hi John, I see you already got the answer on EE, but for any future enquiries:
Assuming you have a blabla.csv with a column UPN to designate the users:
Improt-CSV blabla.csv | % { Set-MsolUserPassword -UserPrincipalName $_.UPN -ForceChangePasswordOnly $true -ForceChangePassword $true }
Vasil,
can we force notification (standard one like 14 days) for password change for a user or groups?
thanks
There is no built-in functionality for that, usually it will rely on the AD expiration notifications. If your users are cloud-only, you can use a PowerShell script such as the one here: https://windowsserveressentials.com/2015/01/23/office-365-email-password-reminder/
No password writeback.
For the three users that were not prompted immediately:
User1 was prompted about 3 hours later within Outlook. Changed his password on the O365 portal. Outlook accepted the new password. He did not change the password on his phone yet it continued to work with the old password.
User2’s email stopped working. He logged onto webmail and was prompted to change password. He started his MacBook laptop and the Outlook application. He was not prompted to change the Outlook for MAC password yet mail flowed to and from the application.
User3 didn’t attempt to access email via Outlook till the next morning at which time he was prompted to reset the password.
We do not use federation nor do we sync Azure passwords locally but this link enables users to change their own password. https://account.activedirectory.windowsazure.com/ChangePassword.aspx
I don’t really expect you to troubleshoot my problems, I just wanted to get them out there in case you or someone else had any quick idea why they were happening. The delay in triggering the change is a problem but the inconsistency is the real issue.
OK, I get it now, and this is pretty much expected. There’s a lot of caching happening on the backend and the middle-tier, so it’s normal that credentials don’t expire immediately. It’s one of the reasons why simply changing the password for a “leaver” is not a complete solution.
In addition, the applications themselves can store credentials and even cause issues by trying to reuse the old password.
M$ have blown security right out of the water with 365. Once a user is comprised in your business you are fucked. That user sends out an email to all other users who then may enter their password to what looks like a 365 login screen sent by your ceo. Fucked. Try disabling all users and prompting for password resets “immediately”. User credentials are signed and last for as long as the default 365 setting is, which is generally an hour. In that hour, I can tell you, the hackers run rampant and gather as much of your data as possible before they are finally closed out. Users get comprised left and right in a large organisation long before you can log into mso or other portal where the process of “security” is so obfuscated in the typical M$ garbage that it is impossible to gather what has been done, shut if off by pulling a plug immediately and to take back control. This is a massive fuck around and M$ is to blame. I mean remote powershell active by default for ALL users? Seriously wtf?!?
An addendum to my question.
The directions above say that it will force a password change at next login.
Does that mean Office 365 login or PC login?
For the two of us who had our passwords expired, it was logoff / login to Office 365 but I can believe that there could be something cached requiring a PC logoff / login.
The other test subjects couldn’t logoff their PC till the end of the day so I’ll see then.
It means O365 login. Do you have the password writeback feature enabled?
This is beating the crap out of me, I’ve tried both:
Set-MsolUserPassword -UserPrincipalName username@our-domain.com -ForceChangePasswordOnly $true -ForceChangePassword $true
AND
Set-MsolUserPassword -ObjectID -ForceChangePasswordOnly $true -ForceChangePassword $true
It worked for two users (myself included) but not for three others.
I get no error, it looks like the command was issued.
When I run:
Get-MsolUser -userprincipalname username@our-domain.com | select DisplayName, LastPasswordChangeTimeStamp,@{Name=”PasswordAge”;Expression={(Get-Date)-$_.LastPasswordChangeTimeStamp}}
It returns valid information (user / last changed / pw age) so I’ve got the correct user principal name.
Get-MsolUser returns the entire user list so it’s not an authentication issue with me.
I’m stumped… any thoughts would be appreciated.
this can only be done through scripts? why doesn’t microsoft have an easy way to do something so important!
Which part exactly? Bulk changing passwords is available in the Admin portal. If you just want to toggle the reset password flag, you have to use PowerShell.
Really good post! For a newbie to Exchange administration (forced really), this is very helpful.
Curious if there is a way to reverse the force all users to reset their password. Replacing True with False creates new passwords.
Thank you!
No, once the flag is set, you cannot unset it.
How do you specify all the users of a specific security group? I’ve been reading powershell articles all morning and haven’t found the answer.
You will have to use the Get-MsolGroupMember or the Get-DistributionGroupMember cmdlets. That’s assuming you are talking about group that exists in O365.
Did you manage to script this? I know it is going back a while.
Thanks
It would be nice if you would show where these scripts are utilized within the Office 365 Admin environment.
Ricky, if you want to run any of the cmdlets or the script above, you will need the WAAD PowerShell module: https://technet.microsoft.com/en-us/library/dn975125.aspx