web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Automate / Microsoft Password Exp...
Power Automate
Unanswered

Microsoft Password Expiration Notification

(0) ShareShare
ReportReport
Posted on by 20

Microsoft Password Expiration Notification Emails

 

Microsoft Removes 365 Email Notifications

 

There was previously a field named "Days before a user is notified about expiration". You are not going crazy, this used to be an option until Microsoft removed it. 

monro_0-1669683118551.png

 

Solution 1: Microsoft Password Expiration Email Notifications with PowerShell

 

The Password Expiry Email Notification PowerShell Script is commonly used. The script can be loaded onto a domain controller and used with CSS to style the email. 
The emails can look very professional with trial and error and a bit of web tinkering, what engineer doesn't like a bit of web design 😛

 

There are versions of the script which use "new-StoredCredential" which creates a value in credential manager on the domain controller running the script. These can be easily removed by Windows updates and occasionally windows reboot, which can make them frustrating to manage. You are stuck either re-publishing the value manually to credential manager or scripting it and showing the password in plain text.  

 

The link above uses a hashed text file and the New-Object with -typename System.Management.Automation.PSCredential. Although this resolves the problem of plain text passwords, it's still not an ideal solution. 

 

1. When an admin/engineer leaves the business, you are stuck trying to re-hash the password and re-configure the script to accept the new text file. 

 

2. Microsoft continue to push users away from legacy auth. Although they have once again delayed their September 2022 deadline to January 2023, they will make this change eventually. Yes I know SMTP is not part of the change (as long as you have existing SMTP traffic), but it will be changed eventually and they have made their concerns public about SMTP legacy auth. 

 

3. More work when you move to a cloud only AAD

 

Solution 2: Microsoft Password Expiration Email Notifications with PowerAutomate

 

Articles like this have explained this, however the date format didn't work for me. After manipulating it many times, the solution ended up being quite simple. 

 

1. Create a recurring timer:

 

monro_0-1669696178829.png

 


2. For testing, you can use search terms from a Search for Users (V2) which will allow you enter names of test users. *obviously test thoroughly before releasing to prod.

 

monro_1-1669696295299.png

 

 

3. Using a loop, iterate through each of the values you got from the Search for Users (V2) {Note: Once you are done testing, change the checkbox to Is Search Term Required: No}. Each returned value is the full schema data for a user including name, ID, phone number, country etc. Select only User Id 

 

monro_2-1669696505137.png

 

 

4. Log into Azure and create a new App Registration, with a suitable name. Select the prefered account type when you are creating the app registration. Accounts in this organizational directory only is usually preferred. 

 

monro_4-1669697339472.png

 

 

5. Once created, go to API Permissions on the left, add/confirm you have:


User.Read
User.Read.All
If you are missing permissions, click Add a Permission > Microsoft Graph > Application Permission > search for User.Read and click Add Permission. Also do this for User.Read.All. Once complete, click Grant admin consent for <domain name>, you will need administrative permissions for this. 

 

monro_5-1669697889755.png

 

 

6. Go back to your Flow and use the HTTP Get action to call the Microsoft Graph API. The summary of details is below:

 

Method: GET
URI: https://graph.microsoft.com/beta/users/UserPrincipalName?$select=lastPasswordChangeDateTime

Authentication: OAUTH

Authority: https://login.microsoft.com

Tenant: Enter tenant ID from Azure AD Portal.
Audience: https://graph.microsoft.com

Client ID: Get this value from the App Registration > Overview section in the Azure Portal

Secret: Go to the App Registration > Certificates and Secrets > + New Client Secret > give it a name and expiration date > copy the value. The value will be unreadable when you leave the page. If you lose it, just re-create it and delete the old. 

 

monro_7-1669698542904.png

 

 

7. Create a Compose action and use the following as an input body('GetLastPasswordChange')?['lastPasswordChangeDateTime']  

You will notice the GetLastPasswordChange is the name of the HTTP GET. The lastPasswordChangeDateTime is the name of the schema attribute from the user. 

 

monro_8-1669698765881.png

 

 

8. Use a second Compose action and enter the following expression

div(sub(ticks(formatDateTime(utcNow(),'yyyy-MM-ddTHH:mmZ')),ticks(outputs('DateRawFormat'))),864000000000)
This will give you the difference in days between the current time and the last password change date. 
 
monro_9-1669698849821.png

 

9. Depending on your password policy, create a condition for the amount of days needed. You could make this more sophisticated with integration to AAD Groups. If you use Fine Grained Password Policies (FGPP), you could also use on-prem AAD Connect synced groups so users in different groups get different notifications. 

 

monro_0-1669757040930.png

 


10. If Teams notifications are also needed, this is a simple integration. 


Hope this helps some people!

Categories:
I have the same question (0)
  • Verified answer
    v-chengfen-msft Profile Picture
    on at

    Hi @monro ,

    Thanks for sharing, your sharing is awesome!!!

    Please mark this thread as resolved, this will allow more people to see this thread, which will help more people.

     

     

     

    Best Regards

    Cheng Feng

  • monro Profile Picture
    20 on at

    Replying to myself

    If you have hundreds of users and you need to release to UAT users first, step 2 is not correct and you will need to use an array, which realistically means building a separate flow. 

    Steps below should be enough to figure out a UAT flow. Format for the Initialize Array is below (no comma on final array line):
    [

    "UPN 1",

    "UPN 2",

    "UPN 3"

    ]

     

    monro_1-1669956681934.png

  • EmrahGultekin Profile Picture
    13 on at

    Hello Guys

    Can you share this flow please?

    I can not create the same from screehshots

  • bigjoestretch Profile Picture
    6 on at

    I'm running into the same issue as @EmrahGultekin. Would you be able to export this?

  • monro Profile Picture
    20 on at

    Sorry, not without cutting up the json's to remove any sensitive info. 
    Where are you getting stuck?

  • EmrahGultekin Profile Picture
    13 on at

    Can you add screenshots step by step?

    Please we need help 

  • bigjoestretch Profile Picture
    6 on at

    I completely understand not exporting sensitive info. Is there a way you can remove the sensitive info in a way that it can be imported easily? I'm running into an issue during step 7 where I paste in the value specified in the steps above, but it doesn't convert to what the image looks like in step 7.

     

    2023-02-09_08-59-33.jpg

  • bigjoestretch Profile Picture
    6 on at

    I'm not sure if the steps are the same now as we all know Azure updates frequently, but if you can post a screenshot of each step that ultimately reflects testing this notification for one user (or a handful of users), and what steps we would need to update to have the notification for all users, that would be awesome!

  • EmrahGultekin Profile Picture
    13 on at

    I tried to apply all steps but I think some information or screenshots are missing. I can not do it 😞

  • monro Profile Picture
    20 on at

    Ok, images below should help. There has been a recent change to exclude guest users. When a user is added to Azure with a personal email address, they are added in the format <personal_email_address>#EXT#@microsoftdomain.com - because these are "users" it is still sucked up into this flow and fails because guest users don't have a password expiry that we can query. It continues to run but it's not right, so a quick condition was used to get around that error and show a lovely green "successful" message after each run.

     

    The only other item I noticed was if a user does not have a license assigned it will attempt to email a "null" address (no license - no email) and although it will continue perfectly fine, the result at the end of the flow will be "failed". If you only have a few users without licenses it might not be a concern. 

     

    monro_0-1675977756690.png

    monro_1-1675978307181.png

    I couldn't hover mouse over both for the screenshot, the "value" in the loop is outputs('Search_for_Users_(v2)')?['body/value']

     

    monro_3-1675978439645.png

    monro_5-1675978886416.png

    monro_6-1675978939169.png

     

    monro_7-1675978990550.png

     

    monro_8-1675979025500.png

     

     

    Test first using a single user, if you want to test on several users before releasing it to prod you will need to use an array, see my comment from earlier. 

     

    Obviously only release if you are confident with the solution, each environment is different and I can only comment on it working for my environment (approx 460 users in the flow, all licensed etc). If in doubt, do more testing.

     

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Forum hierarchy changes are complete!

In our never-ending quest to improve we are simplifying the forum hierarchy…

Ajay Kumar Gannamaneni – Community Spotlight

We are honored to recognize Ajay Kumar Gannamaneni as our Community Spotlight for December…

Leaderboard > Power Automate

#1
Michael E. Gernaey Profile Picture

Michael E. Gernaey 522 Super User 2025 Season 2

#2
Tomac Profile Picture

Tomac 364 Moderator

#3
abm abm Profile Picture

abm abm 243 Most Valuable Professional

Last 30 days Overall leaderboard