Password reminder mail in Office 365

In modern days maybe you do not want any on premises server infrastructure at all.
So how does your users get a reminder that their password is about to expire within the next few days. Especially for your roardwarriors which are only using just a tablet and a phone as well.

There comes a solution, Azure Automation!
The Script runs on Azure on a daily base and searches for users whose password is about to expire within your threshold.

Since we are using a mail template you can completely customize the mails.
In my example I use a HTML mail template, since my customer wants to include some nice looking screenshots, banners, etc.

I already enabled the self service password reset portal (SSPR) in my tenant. So I can redirect my users to https://myapps.microsoft.com. From this portal they can change their password.

Requirements:

  • Azure Automation
  • Azure subscription
  • User with a Mailbox which you can use in Azure Automation
  • Portal to change the password (to provide a link in the user reminder mail)

Azure automation

On Azure automation you can simply run some scheduled task to do something. Yes, it is so really so generic. You can do anything you want to do in an Azure Automation job. For Example crawl through your tenant and get a report over used licenses, use this password reminder script, wait for a file change event, wait for an event log entry, remove old users and so on…

Licensing

With Azure Automations there are two different things that may cost something. Job run time and Watchers.

Job run time is simply the time your Azure Automation jobs take to run.
Watchers are for nodes which are running on a machine and waiting for an event, like file change, event log entry and so on.

For Europe you get the following pricing

 free units included (per month)  Price
 Job run time  500 minutes $0.002/minute
 Watchers  744 hours  $0.002/hour

https://azure.microsoft.com/en-us/pricing/details/automation/

The Job

Azure Automation Account

If you do not have an Azure Automation Account you have to create one first.


We want to run this script under a specific account so we add credentials. (this account has to be exist in your tenant)
This user account need the permission to read the password policy. For Example you can use the built-in Directory Role “Security reader”


The main job is running as a Runbook so we are going to add one.


As we are going to use the MSOnline module we need to make this module available to our script.

The Script

	
$credentials = Get-AutomationPSCredential -Name 'PasswordNotifier'
connect-msolservice -cred $credentials

$ThresholdDays = 21
$PasswordPolicyList = @{}
$users = Get-MsolUser -All | ? {$_.UserType -ne "Guest"}

  
function Send-Usernotification {
    param($mail, $username, $surname, $age, $expire, $credentials)

    $MailTemplate = @"
<p>Hello $surname,</p>
<p>Your Userpassword ($usrname) is $age days old and is going to expire in $expire days.<br />
	You can change your password by hit &bdquo;Ctrl-Alt-Del&ldquo; on your keyboard while you are using windows,
	or you can use <a href="https://myapps.microsoft.com/">https://myapps.microsoft.com/</a> (Click on your Name and &bdquo;Profil&ldquo;).</p>
<p>Further information can be found at <a href="https://webserver.de/passwordchangeinfo">HELP</a></p>
<p><img src="https:/webserverwithpicture/picture.jpg" alt="image">
<p>&nbsp;</p>
<p>Your</p>
<p>IT Department</p>
"@
    $Subject = "Password expiration reminder"
    $Body = $Mailtemplate
    Send-MailMessage -To $mail -Subject $subject -body $body -UseSSL -Port 587 -SmtpServer 'smtp.office365.com' -from 'Mailadress from AutomationAccount' -Credential $credentials -bodyashtml
}


foreach ($user in $users) {
   
    $Domain = $user.UserPrincipalName.Split("@")[1]
    if(-not $PasswordPolicyList.$domain) {
        $PasswordPolicyList.Add($Domain , (Get-MsolPasswordPolicy -DomainName $Domain))
    }
    
    if($($PasswordPolicy.$Domain).ValidityPeriod) {
        $period = $($PasswordPolicy.$Domain).ValidityPeriod
    }
    else {
        $period = 90
    }
    
    
    $PasswordExpirationDate = $user.LastPasswordChangeTimestamp.AddDays($period)    
    if($PasswordExpirationDate -le (Get-Date).AddDays($ThresholdDays)) {
        $PwdAge = New-TimeSpan -Start $user.LastPasswordChangeTimestamp -End (Get-Date)
        $PwdRemainingTime = New-TimeSpan -Start (Get-Date) -End $PasswordExpirationDate
        if($user.Proxyaddresses) {
            $smtpaddress = $null
            $smtpaddress = $($user.Proxyaddresses).split(',') | Where-Object {$_ -cmatch "^SMTP:"} | ForEach-Object {$_ -replace "^SMTP:(.*)$",'$1' }
            if($smtpaddress) {
                Send-Usernotification -mail $smtpaddress -username $user.userprincipalname -age $PwdAge.days -surname $user.Firstname -expire $PwdRemainingTime.days -credentials $credentials
            }
    }
        
    }
    

}

Implementation

We also have to add an schedule to this Azure Automation Job

Implementation

What we did:

  1. Create Azure Automation Account
  2. Add Credentials to Azure Automation Account (required to read Azure AD Password Policy and to send mail to users)
  3. Create a Runbook
  4. Add the Script to the Runbook
  5. Add a schedule to the script

Summary

With Azure Automation you are able to run your scheduled tasks serverless in the cloud. You only need a schedule, an account as with the task run and a job that needs to be done.

You can do many other things like maintaining your intune instance, gather reports from your O365. You are also able to run scripts on demand with so called webhooks.

Please let me know what you think about Azure Automation

Stay tuned

Simon