As you can see, it is tripping over the fact that the parameter cannot be converted to the type Microsoft.Exchange.Data.ProxyAddressCollection. Let's take a look at the script and see what's happening. The command that generates the error is this one:Set-MailUser : Cannot convert 'x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=account-name-redacted' to the type 'Microsoft.Exchange.Data.ProxyAddressCollection' required by parameter'EmailAddresses'. The value 'X500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=account-name-redacted' is already present in the collection.At C:\scripts\Exchange2007MBtoMEU.ps1:70 char:60+ Set-MailUser -Identity $UserInfo.Identity -EmailAddresses <<<< $UserInfo.ProxyAddresses -WindowsEmailAddress $UserInfo.Mail -DomainController $DomainController+ CategoryInfo : InvalidArgument: (:) [Set-MailUser], ParameterBindingException+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.Exchange.Management.RecipientTasks.SetMailUser
Set-MailUser -Identity $UserInfo.Identity -EmailAddresses $UserInfo.ProxyAddressesIt doesn't seem to like the $UserInfo.ProxyAddresses parameter. Let's trace back and see where that's created:
$ProxyAddresses = @()
foreach($Address in $Mailbox.EmailAddresses)
{
$ProxyAddresses += $Address
}
$UserInfo | Add-Member -Type NoteProperty -Name ProxyAddresses -Value $ProxyAddressesAh, so the $ProxyAddresses object is a generic array which has been populated with the email address objects from the $Mailbox.EmailAddresses. The object $Mailbox.EmailAddresses is of the type Microsoft.Exchange.Data.ProxyAddressCollection, but $ProxyAddresses is not. That could be an issue. Rather than doing that, I changed the script to this:
Look at that! Since I created a ProxyAddressCollection Object, I was able to copy the $Mailbox.EmailAddresses object rather than iterate through the items in the collection. No foreach loop for me! I also now have all the Method and Attributes associated with the ProxyAddressCollection. That includes the contains/notcontains operator and the Add method. That will be helpful in a moment. Let's look at how those X500 addresses are added:$ProxyAddresses = New-Object Microsoft.Exchange.Data.ProxyAddressCollection$ProxyAddresses = $Mailbox.EmailAddresses
$CloudLegacyDNPresent = $false
$LegacyDNPresent = $false
foreach($Proxy in $UserInfo.ProxyAddresses)
{
if(("x500:$UserInfo.CloudLegacyDN") -ieq $Proxy)
{
$CloudLegacyDNPresent = $true
}
if(("x500:$UserInfo.LegacyDN") -ieq $Proxy)
{
$LegacyDNPresent = $true
}
}
if(-not $CloudLegacyDNPresent)
{
$X500Proxy = "x500:" + $UserInfo.CloudLegacyDN
Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
$UserInfo.ProxyAddresses += $X500Proxy
}
if(-not $LegacyDNPresent)
{
$X500Proxy = "x500:" + $UserInfo.LegacyDN
Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
$UserInfo.ProxyAddresses += $X500Proxy
}Woof. That's not pretty at all. So we're looking through the $ProxyAddresses array to try and find an X500 address for the CloudLegacyDN and LegacyDN values. If we don't find it, we need to add it. There's got to be a better way, like this:
if($UserInfo.ProxyAddresses -notcontains ("X500:"+$UserInfo.CloudLegacyDN))
{
$X500Proxy = "x500:" + $UserInfo.CloudLegacyDN
Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
$UserInfo.ProxyAddresses.Add($X500Proxy)
}
if($UserInfo.ProxyAddresses -notcontains ("X500:"+$UserInfo.LegacyDN))
{
$X500Proxy = "x500:" + $UserInfo.LegacyDN
Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
$UserInfo.ProxyAddresses.Add($X500Proxy)
}Boom. Use the notcontains operator for the logic test and use the Add method to add the X500 address. Using the Add method ensures that the address is added as the correct object type. You don't really need to create an $X500Proxy variable either, but's it's nice to have for the Write-Host output. Now when we pass the $ProxyAddresses object to the Set-MailUser command, it is of the correct type and the objects inside it are as well. After making these changes, the script ran like a charm and those X500 addresses were added.
Labels: Exchange, exchange 2007, exchange online, Microsoft, migration, office 365, powershell, Scripts