When you migrate (or create) a mailbox in Exchange Online, the first time a user goes to open their mailbox they are prompted to select their Timezone and Language. I recently had a client ask for a more automated method of pre-populating these values, so thought I’d have a look into it.
Of course, there’s no global way to define these settings for users before they get a mailbox, so the settings have to be set once the mailbox has been migrated – this really only leaves the option of a custom powershell script – either something you run after each migration (or creation), or on a periodic schedule.
First, to the settings themselves. As it turns out, you can use the same commands that you’d use in on premise Exchange: Get-MailboxRegionalConfiguration and Set-MailboxRegionalConfiguration – which also means this script could be adapted to be used on premise as well. The two settings we’re concerned with here are “Language” and “TimeZone”. Since the client we’re dealing with here is solely based in Australia, we’re going to be setting all users to a language of “en-AU”. For the TimeZone, Microsoft provide a list of valid values here: https://support.microsoft.com/en-us/kb/2779520
Except that they’re missing two Australian time zones. The actual valid values for Australia are:
- AUS Central Standard Time – Darwin
- Cen. Australia Standard Time – Adelaide
- AUS Eastern Standard Time – Canberra, Melbourne, Sydney
- E. Australia Standard Time – Brisbane
- Tasmania Standard Time – Hobart
So with that in mind, we can use the following commands:
Set-MailboxRegionalConfiguration -Language en-AU
Set-MailboxRegionalConfiguration -TimeZone “AUS Eastern Standard Time”
Since we’re talking about a national business with users in different time zones, the time zone value is going to need to change for each user. In order to automate this, we’ll need some source information available that indicates in which state the user is located – ideally, you’re going to be using the ‘Office’ field in the user’s AD account – though obviously you could use any available attribute. The reason I recommend ‘Office’ (or ‘physicalDeliveryOfficeName’) is because it’s synchronised to Office 365 with the user account (and becomes ‘Office’).
Note: You don’t actually need the value in Office 365 – if you’re running the script on premise, you can query your AD directly and ignore the attributes in 365. When I wrote the script I opted to solely use data that was in Office 365 – primarily because I was developing the script remotely and didn’t have direct access to their AD – so if you want to use your local AD instead of values in 365, you’ll need to modify the script!
For this client, the ‘Office’ value for each user is prefixed with the state (ie: SA, NSW, QLD, WA) – so it was relatively simple to use a ‘Switch’ function in Powershell (similar to a ‘Case’ statement in vbscript).
In order to use the script, you need the following:
- Powershell 3.0 or above
- Microsoft Online Services Sign-in Assistant (https://www.microsoft.com/en-us/download/details.aspx?id=41950)
- Windows Azure AD Module (http://go.microsoft.com/fwlink/p/?linkid=236297)
- A password stored in a secure file. In the script I use a file/key file pair – a good guide on this can be found here: http://www.adminarsenal.com/admin-arsenal-blog/secure-password-with-powershell-encrypting-credentials-part-2/
You’ll also need to update the 5 variables at the top of the script (paths, etc), as well as the Time Zones (and criteria) in the Switch statement.
#Log Variables
$LogFile = “D:\Scripts\ExchangeOnline\RegionalConfig_$((Get-Date).ToString(“yyyyMMdd”)).log”
$AuditFile = “D:\Scripts\ExchangeOnline\RegionalConfigAudit.log”
#Credentials
$AdminUser = “admin@office365domain.com”
$PasswordFile = “D:\Scripts\ExchangeOnline\EO_Password.txt”
$KeyFile = “D:\Scripts\ExchangeOnline\EO_AES.key”
Write-Output “$(Get-Date -format ‘G’) ========Script Started========” | Tee-Object $LogFile -Append
#Build the credentials object
Write-Output “$(Get-Date -format ‘G’) Creating credentials object” | Tee-Object $LogFile -Append
$key = Get-Content $KeyFile
$SecurePassword = Get-Content $PasswordFile | ConvertTo-SecureString -Key $key
$Creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AdminUser, $SecurePassword
#Import the MSOnline Module
IMport-Module MSOnline
#Connect to MSOnline.
Write-Output “$(Get-Date -format ‘G’) Connecting to MSOnline” | Tee-Object $LogFile -Append
Connect-MsolService -Credential $Creds
#Connect to Exchange Online
Write-Output “$(Get-Date -format ‘G’) Connecting to Exchange Online” | Tee-Object $LogFile -Append
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
-Credential $Creds -Authentication Basic -AllowRedirection
Import-PSSession $Session
#Grab a list of User Mailboxes from Exchange Online. Only modify synchronised ones.
Write-Output “$(Get-Date -format ‘G’) Getting User Mailbox List” | Tee-Object $LogFile -Append
$UserMailboxes = Get-Mailbox -Filter {RecipientTypeDetails -eq ‘UserMailbox’ -and IsDirSynced -eq $true} –Resultsize Unlimited
#Keep a count for the summary at the end
$TotalCount = 0
$UpdatedCount = 0
$ErrorCount = 0
#Go through each mailbox
Foreach($Mailbox in $UserMailboxes)
{
$Updated = $false
$TotalCount++
#Grab the UPN
$UPN = $Mailbox.UserPrincipalName
Write-Output “$(Get-Date -format ‘G’) Processing Mailbox $UPN” | Tee-Object $LogFile -Append
#Grab the regional Config
$RegionConfig = Get-MailboxRegionalConfiguration $UPN
#From this we need ‘TimeZone’ and ‘Language’.
#Language should be en-AU
#Valid Timezones are:
# AUS Central Standard Time ‘Darwin
# Cen. Australia Standard Time ‘Adelaide
# AUS Eastern Standard Time ‘Canberra, Melbourne, Sydney
# E. Australia Standard Time ‘Brisbane
# Tasmania Standard Time ‘Hobart
#First, do the language – only change if required
If($RegionConfig.Language -ine “en-AU”)
{
Write-Output “$(Get-Date -format ‘G’) – Updating Language to en-AU” | Tee-Object $LogFile -Append
Set-MailboxRegionalConfiguration -Identity $UPN -Language en-AU
$Updated = $True
#Write to the audit log file
Write-Output “$(Get-Date -format ‘G’) $UPN Language changed to en-AU” | Out-File $AuditFile -Append
}
#Next, do the Region
#Grab the Office attribute from the MSOnline Object
$MSOlUser = Get-MsolUser -UserPrincipalName $UPN
$Office = $MSOlUser.Office
#The office attribute will begin with either WA, SA, NSW or QLD
Switch -Wildcard ($Office)
{
“WA*” {$Timezone = “W. Australia Standard Time”}
“SA*” {$Timezone = “Cen. Australia Standard Time”}
“NSW*” {$Timezone = “AUS Eastern Standard Time”}
“QLD*” {$Timezone = “E. Australia Standard Time”}
default {$Timezone = $Null}
}
If($Timezone -ne $Null)
{
#Check if the timezone matches
If($RegionConfig.TimeZone -ine $Timezone)
{
Write-Output “$(Get-Date -format ‘G’) – Updating TimeZone to $TimeZone” | Tee-Object $LogFile -Append
Set-MailboxRegionalConfiguration -Identity $UPN -TimeZone $TimeZone
$Updated = $True
#Write to the audit log file
Write-Output “$(Get-Date -format ‘G’) $UPN TimeZone changed to $TimeZone” | Out-File $AuditFile -Append
}
}
else
{
Write-Output “$(Get-Date -format ‘G’) – Error: Invalid Timezone/Office value” | Tee-Object $LogFile -Append
$ErrorCount++
}
If($Updated) {$UpdatedCount++}
#Clear out the variables for the next run
$UPN = $Null
$RegionConfig = $Null
$MSOlUser = $Null
$Office = $Null
$Timezone = $Null
}
#Write the summary to the log file
Write-Output “$(Get-Date -format ‘G’) ========Summary=======” | Tee-Object $LogFile -Append
Write-Output “$(Get-Date -format ‘G’) Accounts Checked: $TotalCount ” | Tee-Object $LogFile -Append
Write-Output “$(Get-Date -format ‘G’) Accounts Updated: $UpdatedCount ” | Tee-Object $LogFile -Append
Write-Output “$(Get-Date -format ‘G’) Accounts with invalid Office values: $ErrorCount ” | Tee-Object $LogFile -Append
#Remove any remote powershell sessions
Get-PSSession | Remove-PSSession