In most cases you uninstall your local Exchange server after migrating your e-mail to Exchange Online. If you also choose to implement DirSync you place the administration in your local domain instead of the Office 365 Administration Portal.
This means that there is no longer a GUI tool to handle some of the settings related to your mailboxes. Of course you can keep a machine with your old Exchange 2010 Management Console, but often the reason for moving to the cloud is to reduce the complexity and minimize the number of machines.
We don’t have the same problem with other attributes, for example displayname or phone numbers that you’ll find in Users and Computers or the Administrative Center introduced in Windows Server 2008. It does get a bit trickier when you are about to modify primary email address or add alias addresses.
Currently there are no available GUI tools from Microsoft to handle these types of updates easy (but keep your eyes open, things might change 😉 ). However, there are a few third-party tools to achieve this, unless you want to use the Attribute Editor in Users and Computers, or Adsiedit.
Since I’m a big fan of PowerShell I wanted to build a small set of tools to handle simple changes of email addresses. These functions are easy for you to use in your own scripts.
First of all, a function that lists all email addresses of a user:
function Get-O365AliasAddress { <# .SYNOPSIS Displays all email addresses assigned to a user. .PARAMETER Identity The user to query. .EXAMPLE Get-O365AliasAddress -Identity user01 .EXAMPLE Get-ADUser user01 | Get-O365AliasAddress .NOTES Author: Andreas Lindahl Blog: 365lab.net Email: andreas.lindahl[at]jsc.se The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights. #> [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName=$true,Mandatory=$True,ValueFromPipeline=$True, HelpMessage="The name of the user to get addresses of")] [string]$Identity ) Import-Module ActiveDirectory $result = @() (Get-ADUser -Identity $Identity -Properties proxyAddresses).proxyAddresses | foreach { $proxy = $_.split(":") $object = New-Object System.Object $object | Add-Member –Type NoteProperty –Name Type –Value $proxy[0] $object | Add-Member –Type NoteProperty –Name Address –Value $proxy[1] $object | Add-Member –Type NoteProperty –Name IsPrimary –Value ($proxy[0] -ceq $($proxy[0].ToUpper())) $result += $object } return $result }
Next, a function that adds an alias to an existing user
function Add-O365AliasAddress { <# .SYNOPSIS Adds an alias address to a user. .PARAMETER Identity The user to modify. .PARAMETER Address The address to add. .PARAMETER Type The type of address. Default is smtp. .PARAMETER SetAsDefault Indicates if the address should be de default address of the user .EXAMPLE Add-O365AliasAddress -Identity user01 -Address test@365lab.net -SetAsPrimary .NOTES Author: Andreas Lindahl Blog: 365lab.net Email: andreas.lindahl[at]jsc.se The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights. #> [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName=$true,Mandatory=$True,ValueFromPipeline=$True, HelpMessage="The name of the user")] [string]$Identity, [Parameter(Mandatory=$True, HelpMessage="The address to add")] [string]$Address, [Parameter( HelpMessage="The type of the address to add")] [string]$Type="smtp", [Parameter( HelpMessage="Indicates that the address will be set as the default address")] [switch]$SetAsDefault ) Import-Module ActiveDirectory $Type = $Type.ToLower() $defaultaddress = '' $proxyaddresses = '' $proxyaddress = '' #Get all existing proxyAddresses of the same type $proxyaddresses = (Get-ADUser -Identity $Identity -Properties proxyAddresses).proxyAddresses | where-object { $_ -like "$Type*" } #Get current default address of this type foreach ($proxyaddress in $proxyaddresses) { $pa = $proxyaddress.split(':') if ($pa[0] -ceq $pa[0].ToUpper()) { $defaultaddress = $proxyaddress } } #If this is the first address, it will be the default if ($proxyaddresses.count -eq 0) { $SetAsDefault = $true } if ($SetAsDefault) { #New default address to set. Start by removing the old one, but keep it as alias. if ($defaultaddress) { $pa = $defaultaddress.split(':') $newdefaultaddress = "$($pa[0].ToLower()):$($pa[1])" Set-ADUser -Identity $Identity -Remove @{proxyaddresses=$defaultaddress} -Add @{proxyaddresses=$newdefaultaddress} } #Set new default address. In case it already exists, remove it first (it might already be used as alias) if ($Type -eq 'SMTP') { Set-ADUser -Identity $Identity -Remove @{proxyaddresses="$($Type.ToLower()):$Address" } -Add @{proxyaddresses="$($Type.ToUpper()):$Address" } -EmailAddress $Address } else { Set-ADUser -Identity $Identity -Remove @{proxyaddresses="$($Type.ToLower()):$Address" } -Add @{proxyaddresses="$($Type.ToUpper()):$Address" } } } else { #Just add the new address Set-ADUser -Identity $Identity -Add @{proxyaddresses="$($Type):$Address" } } }
Finally we also need a script to delete addresses
function Remove-O365AliasAddress { <# .SYNOPSIS Removes an alias address from a user. .PARAMETER Identity The user to modify. .PARAMETER Address The address to remove. .PARAMETER Type The type of address. Default is smtp. .EXAMPLE Remove-O365AliasAddress -Identity user01 -Address test@365lab.net .NOTES Author: Andreas Lindahl Blog: 365lab.net Email: andreas.lindahl[at]jsc.se The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights. #> [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName=$true,Mandatory=$True,ValueFromPipeline=$True, HelpMessage="The name of the user")] [string]$Identity, [Parameter(Mandatory=$True, HelpMessage="The address to remove")] [string]$Address, [Parameter( HelpMessage="The type of the address to remove")] [string]$Type="smtp" ) Import-Module ActiveDirectory $Type = $Type.ToLower() $defaultaddress = '' $newdefaultaddress = '' $proxyaddresses = '' #Get all existing proxyAddresses of the same type $proxyaddresses = (Get-ADUser -Identity $Identity -Properties proxyAddresses).proxyAddresses | where-object { $_ -like "$Type*" } #Get current default address of this type foreach ($proxyaddress in $proxyaddresses) { $pa = $proxyaddress.split(':') if ($pa[0] -ceq $pa[0].ToUpper()) { $defaultaddress = $proxyaddress } } if ($defaultaddress -eq "$($Type):$Address") { #We are trying to remove the default address. Now it becomes a bit tricky... #First, find the next address of the same type that we can use as default address foreach ($proxyaddress in $proxyaddresses) { if ($proxyaddress -ne "$($Type):$Address") { $newdefaultaddress = $proxyaddress break } } } #Now we can remove the address Set-ADUser -Identity $Identity -Remove @{proxyaddresses="$($Type):$Address"} if ($Type -eq 'smtp' -and $defaultaddress -eq "$($Type):$Address") { Set-ADUser -Identity $Identity -Clear mail } if ($newdefaultaddress) { #Set $newdefaultaddress as new default address Write-Warning "New default address set: $newdefaultaddress" Add-O365AliasAddress -Identity $Identity -Address $newdefaultaddress.split(":")[1] -Type $Type -SetAsDefault } }
Now we can play with these functions:
I have put together a PowerShell Module for you to import. Just load it with the Import-Module cmdlet.
Import-Module O365ProxyAddresses
The module can be downloaded here.
I hope that you will find these functions useful in your daily user administration tasks. Please leave your comments below and feel free to suggest improvements.
Happy coding!
/ Andreas
Nice!
Are there prerequisites that must be meet before running the script successfully?
Hi, as seen in the beginning of each script, you need to run it on a machine that have the ActiveDirectory PowerShell module.
Let me ask another way. If that specific module is already installed (as it seems to be by default) and the script command “get-o365aliasaddress ” is run from an Exchange 2010 server (or dirsync server) hosted on Windows 2008 R2, how does one avoid getting “unable to connect to server” or “unable to find default server with active directory web services running” as the results?
Hi. The script uses the Set-ADUser cmdlet, which requires a Windows Server 2008 R2 Domain Controller or newer.
Okay. So the prerequisite is a Windows 2008 R2 or newer domain controller. Thank you. That helps a lot.
Pingback: The UC Architects » Episode 33: Managing, Migrating, and Moving
Thanks for the script… I have been looking for a way to make this easier for my lower-level admins. This will definitely help. I was planning to try to wrap something like this up in a GUI. Any chance of something like that showing up?
Thanks for reading! We don’t have a gui wrapper planned as of right now, but the more requests we get on specific features, the easier it will be for us to prioritize what to do first. 🙂
HI,
Thanks for this, its very useful. A GUI wrapper would be really handy too – just asking!
Thanks
Great work, Thanks a lot! 🙂
I have made a small function to this that I thought I would share.
It is a simple function that reads each line in a .txt file containing my company’s domains and pipes that into a foreach loop, this way I only have to run one command to add all the default addresses that we normaly add to a new user.
I am not sure if this is the best way to go about doing this, but I am just starting out learning Powershell and it works for me.
The file shout only have one domaine per line and shout start white a “@”, Like so;
@leolab.com
@leolab.dk
@dom.leolab.com
Remember that the first line/domaine in the file will be the primary SMTP address by the “Add-O365AliasAddress” command, unless the user already have an SMTP address, in which case you must do this manually if needed.
The script:
Thanks for sharing! Always good to hear that our blog posts are helpful to you.
Pingback: Minimum Exchange Hybrid Server Requirements for Managing On-Premises Users | The Cloud Technologist
I made a GUI for this mate to make it easier for some of my clients who are less good at scripting. Just extract all to somewhere (with powershell 3, .net 4 and admin tools installed) then run the “O365 email address management gui.ps1” file.
http://1drv.ms/1FL1HU4
You will also need to set your execution policy to allow it to run.
The GUI stuff was borrowed from here http://blogs.technet.com/b/heyscriptingguy/archive/2014/08/01/i-39-ve-got-a-powershell-secret-adding-a-gui-to-scripts.aspx if anyone wants to have a go or improve my design.
Also there is a try, catch in there for wrong usernames, this will stop it showing error messages if its not running right comment out the try and catch lines then try again.
Hope its of use to someone.
Hi Josh – the GUI just errors for me
PS C:\nx\O365 email management GUI> & ‘.\Office 365 Email address manageme
nt GUI.ps1’
Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful,
this script can potentially harm your computer. Do you want to run
C:\nx\O365 email management GUI\Office 365 Email address management
GUI.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is “D”): r
Hi Steve, Sorry I didnt get an email to say there was a reply. you might need to set the execution policy for powershell to allow unsigned scripts, run (as administrator in powershell) Set-ExecutionPolicy unrestricted then try again. Do so at own risk etc etc etc.
Pingback: References: Managing Office 365 through Directory Synchronization without Exchange | ODDYTEE
Pingback: Minimum Exchange Hybrid Server Requirements for Managing On-Premises Users | Catapult Systems
In my environment I got an error in the Add-O365AliasAddress function. A type mismatch in the line:
Set-AdUser -Identity $Identity -Remove @{proxyaddresses=$defaultaddress} -Add @{proxyaddresses=$newdefaultaddress}
I fixed it by adding some double quotes like this:
Set-AdUser -Identity $Identity -Remove @{proxyaddresses=”$defaultaddress”} -Add @{proxyaddresses=”$newdefaultaddress”}
I hope this helps someone else who may have the same problem.
Pingback: Decommission or Maintain Exchange Hybrid? It Depends | ODDYTEE