SOLVED

Modify users addresses via powershell

Brass Contributor

I need to make the following:

- from a list of domains to be removed from email addresses in a csv file load them.

- for each user compare all his email addresses and if anyone is from the list of domain to be removed, then remove it from the user's email addresses

 

How can I do that in powershell ?

thanks

 

14 Replies
Hi @StefanoC66 check this:
# Path to the CSV file containing the domains to be removed
$domainsCsvPath = "C:\path\to\domains.csv"

# Path to the CSV file containing user email addresses
$usersCsvPath = "C:\path\to\users.csv"

# Load the domains to be removed
$domainsToRemove = Import-Csv -Path $domainsCsvPath | Select-Object -ExpandProperty domain

# Load the user email addresses
$users = Import-Csv -Path $usersCsvPath

foreach ($user in $users) {
# Split email addresses by comma (assuming they are stored in a comma-separated list in the 'EmailAddresses' field)
$emailAddresses = $user.EmailAddresses -split ","

# Filter out the email addresses that belong to the domains to be removed
$filteredEmailAddresses = $emailAddresses | Where-Object {
$domain = $_.Split("@")[-1]
-not ($domainsToRemove -contains $domain)
}

# Update the user's email addresses
$user.EmailAddresses = ($filteredEmailAddresses -join ",")
}

# Export the updated user email addresses back to a CSV file
$users | Export-Csv -Path "C:\path\to\updated_users.csv" -NoTypeInformation
hello @chrisslroth
thanks for your help, just a note regarding the users that they're not extracted from a csv file but from a get-mailbox command so they need to be updated directly and not exported to a csv file.
Could you help with it ?
best response confirmed by StefanoC66 (Brass Contributor)
Solution
Hi @StefanoC66 please check this:
# Path to the CSV file containing the domains to be removed
$domainsCsvPath = "C:\path\to\domains.csv"

# Load the domains to be removed
$domainsToRemove = Import-Csv -Path $domainsCsvPath | Select-Object -ExpandProperty domain

# Get all mailboxes
$mailboxes = Get-Mailbox -ResultSize Unlimited

foreach ($mailbox in $mailboxes) {
# Get all email addresses for the mailbox
$emailAddresses = $mailbox.EmailAddresses | Where-Object { $_ -like 'SMTP:*' } | ForEach-Object { $_.SmtpAddress }

# Filter out the email addresses that belong to the domains to be removed
$filteredEmailAddresses = $emailAddresses | Where-Object {
$domain = $_.Split("@")[-1]
-not ($domainsToRemove -contains $domain)
}

# Update the mailbox with the filtered email addresses
if ($filteredEmailAddresses.Count -ne $emailAddresses.Count) {
Set-Mailbox -Identity $mailbox.Identity -EmailAddresses ($filteredEmailAddresses -join ",")
Write-Host "Updated email addresses for mailbox: $($mailbox.Identity)"
}
}

@chrisslrothhi

It seems that there's some issue with the "domain filtering part"

to test the script I did the following

 

$NeedsNew = get-mailbox -identity  "email address removed for privacy reasons" -ResultSize Unlimit

foreach ( $user in $NeedsNew ) {

# Split email addresses by comma (assuming they are stored in a comma-separated list in the 'EmailAddresses' field)
$emailAddresses = $user.EmailAddresses -split ","

# Filter out the email addresses that belong to the domains to be removed
$filteredEmailAddresses = $emailAddresses | Where-Object {
$domain = $_.Split("@")[-1]
-not ($Domtoremove -contains $domain)
}

# Update the user's email addresses
$user.EmailAddresses = ($filteredEmailAddresses -join ",")

but received the error

Exception setting "EmailAddresses": "Cannot convert value "smtp:email address removed for privacy reasons ....."

is not a valid SMTP address.""
At line:23 char:3
+ $user.EmailAddresses = ($filteredEmailAddresses -join ",")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting

Please check your csv-file.

# Load the domains to be removed
$domainsToRemove = Import-Csv -Path $domainsCsvPath | Select-Object -ExpandProperty domain

-> the property-name in the first line in csv-file must be domain, to import the correct values for the mailaddresses
It seems that this test is not working as it doesn't filter any email address
# Filter out the email addresses that belong to the domains to be removed
$filteredEmailAddresses = $emailAddresses | Where-Object {
$domain = $_.Split("@")[-1]
-not ($domainsToRemove -contains $domain)
}

got it
Actually my domains csv file is like
DomainA,DomainB
xxx.com,yy.com
Because I'm using the same file to filter domains from two separate ORG.
and I loaded the domains to be removed as the following
$Domto remove = Import-Csv -Path $Domainfile | select DomainA | where {$_.DomainA -ne ""}
I've solved it. THANKS SO MUCH for your help
Hi @chrisslroth
Actually is failing setting back the email addresses
Set-Mailbox : Cannot convert 'ccci@xx.local,email address removed for privacy reasons' to the type 'Microsoft.Exchange.Data.ProxyAddressCollection' required by parameter
'EmailAddresses'. The address xx@xxx.local,email address removed for privacy reasons' is invalid: "xx@xxx.local,email address removed for privacy reasons" isn't a valid SMTP address. The domain name can't contain spaces and it has to have a prefix and a suffix, such as example.com.
At line:28 char:57
+ ... $mailbox.Identity -EmailAddresses ($filteredEmailAddresses -join ",")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Mailbox], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.Exchange.Management.RecipientTasks.SetMailbox

Hi @chrisslroth
Actually is failing setting back the email addresses
Set-Mailbox : Cannot convert 'ccci@xx.local,email address removed for privacy reasons' to the type 'Microsoft.Exchange.Data.ProxyAddressCollection' required by parameter
'EmailAddresses'. The address xx@xxx.local,email address removed for privacy reasons' is invalid: "xx@xxx.local,email address removed for privacy reasons" isn't a valid SMTP address. The domain name can't contain spaces and it has to have a prefix and a suffix, such as example.com.
At line:28 char:57
+ ... $mailbox.Identity -EmailAddresses ($filteredEmailAddresses -join ",")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Mailbox], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.Exchange.Management.RecipientTasks.SetMailbox
Hi @StefanoC66,

try this in your script, to convert the addresses separated by comma in a ProxyAddressCollection:
# Create a ProxyAddressCollection from the filtered email addresses
$newEmailAddresses = New-Object Microsoft.Exchange.Data.ProxyAddressCollection
foreach ($address in $filteredEmailAddresses) {
$proxyAddress = New-Object Microsoft.Exchange.Data.SmtpProxyAddress($address, $true)
$newEmailAddresses.Add($proxyAddress)
}
With this you set the mailaddresses:
# Update the mailbox with the filtered email addresses
if ($newEmailAddresses.Count -ne $emailAddresses.Count) {
Set-Mailbox -Identity $mailbox.Identity -EmailAddresses $newEmailAddresses
Write-Host "Updated email addresses for mailbox: $($mailbox.Identity)"
}

@chrisslroth 

Thanks for your continuous support.

I'm facing this issue right now.

In the script I'm testing if the new filtered list of email addresses we created with your code does include the original primary smtp address, which could have been removed if was in the domains to be removed.

In the case the old primary was removed we have to set the new primary being like "oldname@newdefaultdomain"
So I tried the following


 $OldPrimary = $mailbox.PrimarySmtpAddress.Address
if($filteredEmailAddresses -notcontains $OldPrimary){
"MIssing primary"
$NewPrimary="SMTP:"+$OldPrimary.Split("@")[0]+"@newdomain.com"
$proxyAddress = New-Object Microsoft.Exchange.Data.SmtpProxyAddress($NewPrimary, $true)
$filteredEmailAddresses.Add($proxyAddress)

}

 

however i got this error

New-Object : Exception calling ".ctor" with "2" argument(s): "Specified argument was out of the range of valid values.
Parameter name: The address 'SMTP:email address removed for privacy reasons' is not a valid SMTP address."
At D:\Scripts\\Test-AliasModify2-NEW.ps1:42 char:21
+ ... xyAddress = New-Object Microsoft.Exchange.Data.SmtpProxyAddress($NewP ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Method invocation failed because [Microsoft.Exchange.Data.SmtpProxyAddress] does not contain a method named 'Add'.
At D:\Scripts\Test-AliasModify2-NEW.ps1:43 char:5
+ $filteredEmailAddresses.Add($proxyAddress)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

1 best response

Accepted Solutions
best response confirmed by StefanoC66 (Brass Contributor)
Solution
Hi @StefanoC66 please check this:
# Path to the CSV file containing the domains to be removed
$domainsCsvPath = "C:\path\to\domains.csv"

# Load the domains to be removed
$domainsToRemove = Import-Csv -Path $domainsCsvPath | Select-Object -ExpandProperty domain

# Get all mailboxes
$mailboxes = Get-Mailbox -ResultSize Unlimited

foreach ($mailbox in $mailboxes) {
# Get all email addresses for the mailbox
$emailAddresses = $mailbox.EmailAddresses | Where-Object { $_ -like 'SMTP:*' } | ForEach-Object { $_.SmtpAddress }

# Filter out the email addresses that belong to the domains to be removed
$filteredEmailAddresses = $emailAddresses | Where-Object {
$domain = $_.Split("@")[-1]
-not ($domainsToRemove -contains $domain)
}

# Update the mailbox with the filtered email addresses
if ($filteredEmailAddresses.Count -ne $emailAddresses.Count) {
Set-Mailbox -Identity $mailbox.Identity -EmailAddresses ($filteredEmailAddresses -join ",")
Write-Host "Updated email addresses for mailbox: $($mailbox.Identity)"
}
}

View solution in original post