Creating a Non-Expiring Password Policy in Azure Active Directory

There’s no direct way in Azure Active Directory (Azure AD) to create a Non-Expiring Password Policy for a domain. There’s a PowerShell cmdlet called Set-MsolPasswordPolicy but all it does is allow us to set the number of days a password is valid (until the users have to change). This is the ValidityPeriod in the definition of Set-MsolPasswordPolicy shown below:

Set-MsolPasswordPolicy
-DomainName <String>
[-NotificationDays <UInt32>]
[-ValidityPeriod <UInt32>]
[-TenantId <Guid>]
[<CommonParameters>]

It would have been OK if this number of days can be set to a large value like 10,000 (close to 30 years). Then we just set it once and forget about it. Unfortunately, that’s not the case. The largest value we can set is 1000 (almost 3 years).

On the other hand, Azure AD allows an individual user account to have its password set to never expire. To do so, it’s simple to execute the following PowerShell cmdlet:

PS> Get-MSOLUser | Set-MsolUser -PasswordNeverExpires $true

The problem is hopefully the business can have new users all the time. But when a new user is created, this attribute PasswordNeverExpires of the new user account is not set, or null, or effectively false. To constantly run the cmdlet above when each user account is created is not efficient.

So we can mimically create non-expiring password policy in Azure AD. In English, the plan is to use the cmdlet Set-MsolPasswordPolicy to set the ValidityPeriod to 1000, and every year, let’s say January 1st, we run cmdlet Set-MsolUser to set all new accounts created during the year to have PasswordNeverExpires attribute to true.

So here are the PowerShell cmdlets. To set the password policy for the domain, this only needs to be done once.

PS > Set-MsolPasswordPolicy -ValidityPeriod 1000 -NotificationDays 14 -DomainName [your-domain].onmicrosoft.com

Then on the first of the year, we will find all new accounts created during the previous year and set them to have PasswordNeverExpires value to true. These accounts have their password valid for almost 3 years according to the password policy above. Since they are created at various times during the year, and we set them on the first of the following year, we are completely sure they are nowhere to have their password expire.

PS > $NewUserPrincipals = Get-MsolUser | where {$_.PasswordNeverExpires -eq $null}PS > $NewUserPrincipals | Set-MsolUser -PasswordNeverExpires $truePS >Get-MSOLUser | Select UserPrincipalName, PasswordNeverExpires

So the first PowerShell cmdlet finds all user accounts that still have PasswordNeverExpires unset.

The second cmdlet takes these and set PasswordNeverExpires to true.

The third cmdlet verifies all accounts have PasswordNeverExpires set to true.

So why the trouble of the first cmdlet while we can simply do

PS> Get-MSOLUser | Set-MsolUser -PasswordNeverExpires $true

The answer is simple. We don’t want to all these false positives Update User logs to clutter the Azure AD Audit log.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store