Reputation: 293
I have a list of users with several values in their ProxyAddresses
attribute e.g.
SMTP:[email protected] smtp:[email protected] smtp:[email protected] smtp:[email protected]
and many other unknown ones.
What I want to do is:
I've not got very far, running this just strips all proxyaddresses out and adds the one specified:
$userou = "OU=test2,OU=Test,OU=Users,DC=Corp,DC=Local"
$users = Get-ADUser -Filter * -SearchBase $userou -Properties SamAccountName, ProxyAddresses
foreach ($user in $users) {
Get-ADUser $user | Set-ADUser -Replace @{'ProxyAddresses'="SMTP:[email protected]"}
}
How do I enumerate through each value in a multivalue attribute?
Upvotes: 0
Views: 1884
Reputation: 61068
The below code should do what you need. It updates the ProxyAddresses multivalue property so that all 'smtp/SMTP' addresses will become lowercase and the new Primary emailaddress is computed and inserted in the list.
I have added a small helper function to replace diacritic characters that may appear in the users first or last name because especially Outlook 365 does not handle these characters very well.
$userou = "OU=test2,OU=Test,OU=Users,DC=Corp,DC=Local"
$users = Get-ADUser -Filter * -SearchBase $userou -Properties SamAccountName, ProxyAddresses, EmailAddress
function Replace-Diacritics {
# helper function to replace characters in email addresses that especially Outlook365 does not like..
Param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[string] $EmailAdress
)
$chars = @()
$normalized = $EmailAdress.Normalize( [Text.NormalizationForm]::FormD )
$normalized.ToCharArray() | ForEach-Object {
if( [Globalization.CharUnicodeInfo]::GetUnicodeCategory($_) -ne [Globalization.UnicodeCategory]::NonSpacingMark) {
$chars += $_
}
}
$chars -join ''
}
foreach ($user in $users) {
# create the new primary emailaddress
# remove invalid characters and replace diacritics ("Frédérique.Étrangé[email protected]" --> "[email protected]")
$newPrimary = ($("{0}.{1}@Domain2.com" -f $user.GivenName, $user.Surname) -replace '[\s()<>,;:''"{}/[\]\\]+', '').ToLower()
$newPrimary = "SMTP:" + (Replace-Diacritics ($newPrimary -replace '\.+', '.'))
# get all email addresses and convert them to lowercase. At the same time dedupe this array.
# this will also replace 'SMTP:' of the former Primary email address to become an alias ('smtp:')
$emailAliases = @($user.ProxyAddresses | Where-Object { $_ -match '^smtp:.*' -and $_ -ne $newPrimary } |
ForEach-Object { $_.ToLower() } |
Sort-Object -Unique)
# read all other existing stuff
$otherAddresses = @($user.ProxyAddresses | Where-Object { $_ -notmatch '^smtp:.*' })
# now merge all addresses into one array, the Primary email address on top for easier reading in ADUC
$newProxies = (@($newPrimary) + $emailAliases) + $otherAddresses
# finally replace the users ProxyAddresses property. I like:
$user | Set-ADUser -Clear ProxyAddresses
$user | Set-ADUser -Add @{'proxyAddresses'=$newProxies }
# but you could also do
# $user | Set-ADUser -Replace @{'proxyAddresses' = $newProxies}
# finally, put the new primary email address in the users 'mail' property
$user | Set-ADUser -EmailAddress $($newPrimary -replace 'SMTP:', '')
}
Upvotes: 2
Reputation: 200293
Untested, because I don't have an AD at my disposal here, but I'd expect something like this to work, since multivalued attributes should be returned as collections.
$addr = $user.ProxyAddresses -creplace '^SMTP:', 'smtp:'
$addr += 'SMTP:[email protected]'
$user | Set-ADUser -Replace @{ 'ProxyAddresses' = $addr }
To assign the correct new primary address to each user you could map the addresses to usernames in a hashtable and then do a lookup rather than assign the new primary address as a static value:
$addr += $newPrimaryAddress[$user.SamAccountName]
Upvotes: 0