<< A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

–A–

–B–

bounced emails (NDRs) do not return when you send from (send on behalf of) a distribution list (which means the sender never finds out his email didn't arrive to where he wanted) - see distribution list bounce backs - no one sees

–C–

contact, find by email

Get-ADObject -LDAPFilter "objectClass=Contact" -Properties Name,mail | Where-Object{$_.mail -like "ac*"} | ft Name, mail, distinguishedName

See also

contacts, add all in an OU to a distribution list - see OU, add all contacts therein to a distribution list

contacts, display proxyAddresses (actually, this is only local AD contacts - need to get better command for O365 contacts.)

Set a variable for the file name. If all we want is to output to the console.

Get-ADObject -filter {objectclass -eq "contact" } -SearchBase 'OU=someOU,DC=yourCompany,DC=com' `
    -property DisplayName,mail,proxyAddresses,co,department | `
    sort DisplayName | `
    select DisplayName,mail, @{Name= 'proxyAddresses';Expression={[string]::join(";", $($_.proxyAddresses))}}, co, department | ft

If we want to export results in Excel.

$datesuffix = get-date -Format yyy-MM-dd_HHmmss

use Get-ADObject rather than Get-Contact

Get-ADObject -filter {objectclass -eq "contact" } -property DisplayName,targetAddress,proxyAddresses | `

  select DisplayName,targetAddress, @{Name= 'proxyAddresses';Expression={[string]::join(";", $($_.proxyAddresses))}} | `

  export-csv -delimiter ";" -notype allContacts_$($datesuffix).csv

Open up in Excel. Text-to-columns on 1st 2 colums. use ";" as delimiter.

contact email, replace

Set-ADObject -Identity $contact.objectGUID -Replace @{mail=$newMail}

contacts in one OU

This shows all the proxyAddresses for each user and some other fields

Get-ADObject -filter {objectclass -eq "contact"} -SearchBase 'OU=someOU,DC=yourCompany,DC=com' -Properties objectGUID,DisplayName,sn,givenName,mail,proxyAddresses,co,department | sort sn,givenName | select givenName,sn,DisplayName,mail,@{Name='proxyAddresses';Expression={[string]::join(";", $($_.proxyAddresses))}},co,department,objectGUID | ogv

If you have a some sub-OU's you want to sort on and need country & language

Get-ADObject -filter {objectclass -eq "contact" } -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' -Properties objectGUID,sn,givenName,DisplayName,mail,proxyAddresses,c,co, language,canonicalname | select @{Label = "OU";Expression = {($_.canonicalname -Split "/")[-2]}},givenName,sn,DisplayName,c,co,language,mail,@{Name= 'proxyAddresses';Expression={[string]::join(";", $($_.proxyAddresses))}} | sort OU, sn | ogv

contacts, replace domain portion of all proxyAddresses for an OU

$contacts = Get-ADObject -filter {objectclass -eq "contact" } -SearchBase 'OU=someOU,DC=yourCompany,DC=com' `
    -Properties objectGUID, DisplayName,mail,proxyAddresses,co,department | `
    sort DisplayName | `
    select DisplayName,mail, @{Name= 'proxyAddresses';Expression={[string]::join(";", $($_.proxyAddresses))}}, co, department, objectGUID
$contacts | ft
 
foreach ($contact in $contacts)
{
    $proxyAddresses = $contact | select -ExpandProperty ProxyAddresses
    foreach ($address in $proxyAddresses)
    {
        $proxyPrefix = $address -Split "@"
        $newAddress = "$($proxyPrefix[0])@otherDomain.com"
        "old is $address, prefix is $($proxyPrefix[0]), new is $newAddress ($i)"
        Set-ADObject -Identity $contact.objectGUID -remove @{proxyAddresses = $address}
        Set-ADObject -Identity $contact.objectGUID -add @{proxyAddresses = $newAddress}
    }
}

contact targetAddress, change - see also targetAddress, bulk change in place (contacts)

Set-ADObject -Identity $contact.objectGUID -Replace @{targetAddress=$targetAddress}

or Remove or Add. But normally contacts wouldn't have targetAddresses. So you'll probably just stick with Remove.

–D–

distribution list, add all contacts in an OU to - see OU, add all contacts therein to a distribution list

distribution list bounce backs - no one sees

If you send as a distribution group, if an email bounces (either all by itself or as one email in a bunch you send out), you may find that no one gets a Non Delivery Report (NDR) or bounce back. It turns out that you have to have two properties reversed from their defaults.

Two steps

Assign owner

The distribution group must have an owner assigned. Who owns this now? It's likely blank. But for this to work, it must be filled.

Get-ADGroup -Filter {(name -eq 'GID Orders')} -Properties managedBy | select name, ManagedBy

Change it to whoever should get the bounce backs (NDRs)

Get-ADGroup -Filter {(name -eq 'Some DistrGroup')} -Properties managedBy | Set-ADGroup -ADD @{ManagedBy=(Get-ADUser -Filter {(name -eq 'Some User')}).distinguishedname}

Change a couple properties

in Local AD

Get-ADGroup -Filter {(name -eq someDistrGroup)} -Properties reportToOriginator, reportToOwner | ft reportToOriginator, reportToOwner

will likely return something like

reportToOriginator reportToOwner
------------------ -------------
                            True

or, in AAD (cloud)

Get-DistributionGroup someDistGroup@yourDomain.com | FL Report*rEnabled

will likely return something like

ReportToManagerEnabled            : False
ReportToOriginatorEnabled         : True

run these two commands to reverse these settings

Get-ADGroup -Filter {(name -eq 'someDistrGroup )} | Set-ADGroup -clear reportToOriginator
Get-ADGroup -Filter {(name -eq 'someDistrGroup')} -Properties reportToOriginator, reportToOwner | Set-ADGroup  -ADD @{ReportToOwner=$true}

And then sync.

or, if you don't sync local AD to AAD and it's AAD only (cloud only)

Set-DistributionGroup -Identity "someDistrGroup" -ReportToManagerEnabled $true
Set-DistributionGroup -Identity "someDistrGroup " -ReportToOriginatorEnabled $false

so that they end up reversed (in AAD after syncing with AD or after running AAD-only command to set in AAD)

ReportToManagerEnabled            : True
ReportToOriginatorEnabled         : False

distribution groups bounce for outside users - see outside users can't send to distribution lists

distribution group, find

find by name

Get-ADGroup -Filter {(GroupCategory -eq "Distribution") -and (Name -like "Accounting*")} -Properties name, mail, distinguishedName | ft name, mail, distinguishedName

or, to find distribution group corresponding to a certain email

Get-ADGroup -Filter {(GroupCategory -eq "Distribution") -and (mail -like "Accounting*")} -Properties name, mail, distinguishedName | ft name, mail, distinguishedName

See also

distribution group, list members

Get-DistributionGroupMember someDistGroup

distribution group permissions

(Get-ACL "AD:$((Get-ADGroup -Filter {(name -eq 'GID Orders')}).distinguishedname)").access | `
    Sort-Object IdentityReference | `
    ft -Wrap -Property IdentityReference, AccessControlType, InheritanceType, ActiveDirectoryRights

–E–

email, find contact with a specific - see contact, find by email

–F–

–G–

GAL (Global Address Book), suppressed? - see msExchHideFromAddressLists property, Offline Address Book, add or remove many users from showing up using one command for many users in an OU

–H–

–I–

–J–

–K–

–L–

–M–

msExchHideFromAddressLists property - see also Offline Address Book, add or remove many users from showing up using one command for many users in an OU

(this local AD attribute is equivalent to HiddenFromAddressListsEnabled in the cloud.)

Security groups with mailboxes, show msExchHideFromAddressLists status

Get-ADGroup -Filter {(GroupCategory -eq "Security")} -Properties msExchHideFromAddressLists,mail -SearchBase 'OU=YourOU,DC=yourDomain,DC=com' | ?{$_.mail -ne $null} | Sort-Object msExchHideFromAddressLists,mail,name | ft name, mail, msExchHideFromAddressLists

Distribution groups

Get-ADGroup -Filter {(GroupCategory -eq "Distribution")} -Properties msExchHideFromAddressLists,mail -SearchBase 'OU=YourOU,DC=yourDomain,DC=com' | ?{$_.mail -ne $null} | Sort-Object msExchHideFromAddressLists,mail,name | ft name, mail, msExchHideFromAddressLists

–N–

Non Delivery Reports (NDRs aka bounced emails) do not return when you send from (send on behalf of) a distribution list (which means the sender never finds out his email didn't arrive to where he wanted) - see distribution list bounce backs - no one sees

null, filter on property

In this example, we want to find all ADUsers whose msExchHideFromAddressLists property is not set. So we quite reasonably attempt to filter on that filter not equal to the $null variable:

Get-ADuser -filter {msExchHideFromAddressLists -eq $null} -Properties msExchHideFromAddressLists | ft Name, msExchHideFromAddressLists

But that fails with:

Get-ADuser : Variable: 'null' found in expression: $null is not defined.

So, instead filter on -notlike "*":

Get-ADuser -filter {msExchHideFromAddressLists -notlike "*"} -properties msExchHideFromAddressLists | ft Name, msExchHideFromAddressLists

You can actually still filter on the $null variable. Just not in the very first part of the command where you're using the -filter. Instead, use later after a pipe:

Get-ADuser -filter * -properties msExchHideFromAddressLists | ? {$_.msExchHideFromAddressLists -eq $null} | ft Name, msExchHideFromAddressLists

I like to think that the first method of filtering on -notlike "*" is more efficient and elegant.

–O–

object's targetAddress, change - see also targetAddress, bulk change in place (contacts)

Set-ADObject -Identity $contact.objectGUID -Replace @{targetAddress=$targetAddress}

or Remove or Add. But normally contacts (which is probably why you're dealing with objects instead of users in the first place) wouldn't have targetAddresses. So you'll probably just stick with Remove.

Offline Address Book, add or remove many users from showing up using one command for many users in an OU see also msExchHideFromAddressLists property, GAL (Global Address Book) suppressed

Need to alter the msExchHideFromAddressLists property. By default, this property is not set at all to begin with. So filter on this property not being set. (-notlike *)

Get-ADUser -Filter {msExchHideFromAddressLists -notlike "*"} -Properties msExchHideFromAddressLists -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Set-ADUser -Replace @{msExchHideFromAddressLists=$false}

Orphaned users, show which have permissions on a distribution group

(Get-ACL "AD:$((Get-ADGroup -Filter {(name -eq 'GID Orders')}).distinguishedname)").access | `
    Where{$_.IdentityReference  -match 'S-1-5-21'} | `
    Sort-Object IdentityReference | `
    ft -Wrap -Property IdentityReference, AccessControlType, InheritanceType, ActiveDirectoryRights

Outside users can't send to distribution lists

look at the msExchRequireAuthToSendTo attribute. Those who can't have it set to true:

Get-ADGroup -Properties mail,displayName,msExchRequireAuthToSendTo -Filter {(msExchRequireAuthToSendTo -eq $true)} | Sort-Object displayName,Name | ft Name,displayName,mail

Those who can either don't have it set at all or have it set to false:

Get-ADGroup -Properties mail,displayName,msExchRequireAuthToSendTo  -Filter {(msExchRequireAuthToSendTo -notlike "*") -or (msExchRequireAuthToSendTo -eq $false)} | Sort-Object displayName,Name | ft Name,displayName,mail,msExchRequireAuthToSendTo

OU, add all contacts therein to a distribution list

This works for users, but not contacts

Get-ADUser -SearchBase 'OU=contractor,OU=it,OU=TopOrgContacts,OU=TopOrg,DC=yourDomain,DC=com' -Filter {EmailAddress -like "*"} | `

    % { Add-ADGroupMember 'contractors TopOrg IT' -Members $_ }

But trying to do the same thing for contacts fails:

Get-ADObject -SearchBase 'OU=contractor,OU=it,OU=TopOrgContacts,OU=TopOrg,DC=yourDomain,DC=com' -filter {objectclass -eq "contact"} | `

    % { Add-ADGroupMember 'contractors TopOrg IT' -Members $_ }

The problem is that the cmdlets for managing AD group objects only allow you to add objects that have a SamAccountName (and therefore a SID) to a group. This is fine for user and group objects. But Contact objects to not have SIDs. So now what do you do?  The answer? Use ADSI.

$Group = [ADSI]"LDAP://CN=contractors TopOrg IT,OU=contractor,OU=it,OU=TopOrgContacts,OU=TopOrg,DC=yourDomain,DC=com"

$contacts = Get-ADObject -SearchBase 'OU=contractor,OU=it,OU=TopOrgContacts,OU=TopOrg,DC=yourDomain,DC=com' -filter {objectclass -eq "contact"}

And then:

$contacts | %{$Group.Member.Add($_.DistinguishedName)}

$Group.psbase.CommitChanges()

I had to refresh my view of the OU in question in ADUC before these additions took.

Or, to tie everything up into one tidy bundle:

$groupName = "yourDistributionGroup"
$OU = "OU=yourOU,DC=yourDomain,DC=com"
$Group = [ADSI]"LDAP://cn=$($groupName),$OU"
$contacts = Get-ADObject -SearchBase "$OU" -filter {objectclass -eq "contact"}
$contacts | %{$Group.Member.Add($_.DistinguishedName)}
$Group.psbase.CommitChanges()

OU, list all contacts - see contacts in one OU

–P–

proxyAddresses, bulk change in place

contacts

$contacts = Get-ADObject -filter {objectclass -eq "contact"} -Properties name, givenName, sn, mail, ProxyAddresses -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Sort-Object givenName, sn
$contacts | %{Set-ADObject  -Identity $_.objectGUID -add @{ proxyAddresses = "smtp:" + $_.mail.split("@")[0] +"@foodchainid.com"}}

users

Populate variable $localUsers with those who have proxyAddresses like your domain and are in the correct OU

$localUsers = Get-ADUser -Filter {(proxyAddresses -like "*yourDomain.com")} -Properties proxyAddresses,mail,SamAccountName -SearchBase 'OU=YourOU,DC=yourDomain,DC=com'

Verify that the users you have match what you think the existing proxyAddresses should be

$localUsers | ft Name, mail, SamAccountName, proxyAddresses

Add new proxyAddresses. In this case, corresponding with a new tenant.

$localUsers | %{Set-ADUser -Identity $_.SamAccountName -add @{ proxyAddresses = "smtp:" + $_.mail.split("@")[0] +"@YourNewTenant.onmicrosoft.com"}}

Verify that the new proxyAddresses have, indeed, been added.

Get-ADUser -Filter { (proxyAddresses -like "*yourDomain.com")} -Properties proxyAddresses,mail -SearchBase 'OU=YourOU,DC=yourDomain,DC=com' | ft Name, proxyAddresses

Now, take away proxyAddresses. In this case, corresponding with our old tenant.

$localUsers | %{Set-ADUser -Identity $_.SamAccountName -remove @{ proxyAddresses = "smtp:" + $_.mail.split("@")[0] +"@YourOldTenant.onmicrosoft.com"}}

Verify that the old proxyAddresses have been removed.

Get-ADUser -Filter {(proxyAddresses -like "*yourDomain.com")} -Properties proxyAddresses,mail -SearchBase 'OU=YourOU,DC=yourDomain,DC=com' | ft Name, proxyAddresses

proxyAddresses, categorize

contacts

split out main email, primary proxy, all other proxy addresses:

Get-ADObject -filter {objectclass -eq "contact"} -Properties name, givenName, sn, mail, ProxyAddresses -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | `
    Sort-Object givenName, sn | Select Name, givenName, sn, mail, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'SMTP')}}}, `

    @{Name="OtherEmailAddresses";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'smtp')}}} | ft

A query similar to the last one below for users that also

but instead for contacts:

Get-ADObject -LDAPFilter "objectClass=Contact" -Properties proxyAddresses,mail,name,targetAddress -SearchBase 'OU=YourOU,DC=yourDomain,DC=com' | Sort-Object name | Select name, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'SMTP') -and ($_ -notmatch '500*')}}}, @{Name="OtherEmailAddresses";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'smtp') -and ($_ -notmatch 'onmicrosoft') -and ($_ -notmatch '500')}}}, @{Name="onMicrosoftAddresses";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'smtp') -and ($_ -match 'onmicrosoft') -and ($_ -notmatch '500')}}}, targetAddress | Out-GridView

users

all "real" proxy addresses and suppress those containing "500"

Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName,targetAddress -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Select SamAccountName , @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{$_ -notmatch '500*'}}}

or this would also work:

Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName,targetAddress -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Sort-Object SamAccountName | Select SamAccountName, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{$_ -match 'SMTP*'}}}

although it doesn't only get capital SMTP. To do that, use -cmatch instead of -match:

Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName,targetAddress -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Sort-Object SamAccountName | Select SamAccountName, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{$_ -cmatch 'SMTP*'}}}

Sometimes just specifying the "SMTP" without omitting "500" gets you a stray "500" or two. So, combining both seems to work best:

Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName,targetAddress -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Sort-Object SamAccountName | Select SamAccountName, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'SMTP*') -and ($_ -notmatch '500*')}}}

finally, let's split out these proxyAddresses into 3 groups of interest

plus targetAddress:

Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName,targetAddress -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | Sort-Object SamAccountName | Select SamAccountName, @{Name="PrimaryEmailAddress";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'SMTP') -and ($_ -notmatch '500*')}}}, @{Name="OtherEmailAddresses";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'smtp') -and ($_ -notmatch 'onmicrosoft') -and ($_ -notmatch '500')}}}, @{Name="onMicrosoftAddresses";Expression={$_.ProxyAddresses | ?{($_ -cmatch 'smtp') -and ($_ -match 'onmicrosoft') -and ($_ -notmatch '500')}}}, targetAddress | ft

With the greater complexity of the last query, leaving off the "*" wildcard seems to work better - even though it seemed to work OK when only looking for "SMTP*"

proxyAddresses, find

Get-ADUser -filter * | where-Object {$_.ProxyAddresses -match "user@yourDomain.com" } | fl

proxyAddresses, save to CVS

Normally, when you attempt to save proxyAddresses to CVS, they don't show up right. You get something like, Microsoft.ActiveDirectory.Management.ADPropertyValueCollection for that field.

Get-ADUser -Filter * -SearchBase 'CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,dc=yourDomain,dc=colo' -Properties proxyAddresses | `
Select-Object Name, @{L = "proxyAddresses"; E = { $_.proxyAddresses -join ";"}} | Export-Csv "C:\Users\someuser\Documents\HealthMailBoxes.csv"

proxyAddresses, pass as an argument to a function and return an array

proxyAddresses acts as if it's a hash. But if you try to declare the receiving parameter ( say, userProxyAddresses) as a hash, the system complains:

Cannot process argument transformation on parameter 'userProxyAddresses'. Cannot convert the Microsoft.ActiveDirectory.Management.ADPropertyValueCollection value of type Microsoft.ActiveDirectory.Management.ADPropertyValueCollection to type System.Collections.Hashtable.

And there are no built-in data types that I could ever find that correspond to ADPropertyValueCollection for me to declare that parameter type as. Similarly, if we want to do something to the proxyAddresses (like get rid of X500 and the like) and return the processed collection of proxyAddresses as a cleaned up array, it insists on converting your array back into a string which you can't really use back outside:

Cannot convert the SMTP:someUser@yourDomain.com value of type System.String to type System.Collections.ArrayList.

Fix these two problems by:

  1. Use [CmdletBinding()] for the incoming parameter
  2. Add an extra comma when returning the results

like this:

function populateUsefulProxyAddresses
{
    [CmdletBinding()] param ($proxyAddresses)
    [System.Collections.ArrayList]$usefulProxyAddresses = @()
    foreach ($address in $proxyAddresses)
    {
        if (($address -notmatch "x500") -and ($address -notmatch "x400") -and ($address -notmatch "onmicrosoft.com") )
        {
            $usefulProxyAddresses += $address
        }
    }
    return , $usefulProxyAddresses # that extra comma is how we tell this function to return an array
}  

And invoke it like this:

[System.Collections.ArrayList]$usefulUserProxyAddresses = @()
$usefulUserProxyAddresses = populateUsefulProxyAddresses -proxyAddresses ($user.$property)

proxyAddresses, suppress X500 from view - see proxyAddresses, categorize

–Q–

–R–

rooms, show a list of

When you use the Scheduling Assistant in Outlook to schedule a meeting and want to show a list of available rooms, you have to manually add all the possible rooms to see which one is available. This isn't always obvious to the end user. But you can create a room list that will show up in the Show a room list pick list in Outlook.

Create a room list called room list name:

New-DistributionGroup -Name "room list name" –RoomList

Find some likely candidates:

Get-MailBox | where {$_.ResourceType -eq "Room"}

Add a couple rooms:

Add-DistributionGroupMember -Identity "room list name" -Member "ConfRoom1"

Add-DistributionGroupMember -Identity "room list name" -Member "ConfRoom1"

Now when you go to your Outlook scheduling assistant you'll see this in the Show a room list pick list off to the right.

Curiously, though, I have yet to be able to find this new room list name either in local AD or as a cloud-only group (through the graphical interface).

–S–

security group, find email-enabled

Get-ADGroup -Filter {(GroupCategory -eq "Security") -and (mail -like "*")} -Properties name, mail, distinguishedName | Sort-Object mail | ft name, mail, distinguishedName

See also

–T–

targetAddress, bulk change in place

Users

Populate variable $localUsers with those who have targetAddress like your domain and are in the correct OU

$localUsers = Get-ADUser -Filter {(TargetAddress -like "*onmicrosoft.com")} -Properties TargetAddress,mail,SamAccountName -SearchBase 'OU=yourOU,DC=yourDomain,DC=com'

Verify that the users you have match what you think the existing targetAddress should be

$localUsers | ft Name, mail, SamAccountName, targetAddress

Replace targetAddresses.

$localUsers | %{Set-ADUser -Identity $_.SamAccountName -replace @{targetAddress = "SMTP:" + $_.mail.split("@")[0] + "@yourtenant.onmicrosoft.com"}}

Verify that the old targetAddress have been removed.

Get-ADUser -Filter { (TargetAddress -like "*onmicrosoft.com")} -Properties TargetAddress,mail,SamAccountName -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | ft Name, mail, SamAccountName, TargetAddress

Contacts

Let's say we want to replace all targetAddress that begins with "smtp" to instead begin with "SMTP". Start by finding all contacts that contain the lower-case "smtp". We can't rely on SamAccountName the way we can with users but instead must stash objectGUID because, unlike users, contacts don't have SamAccountName. Find the lower case "smtp" by using the case-sensitive version of -match which is -cmatch

$localUsers = Get-ADObject -LDAPFilter "objectClass=Contact" -Properties TargetAddress,mail,objectGUID -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | ?{($_.TargetAddress -cmatch 'smtp*')}

If, instead, we want to find any target addresses that end with ".onmicrosoft.com", better to omit the "*" if you want search using "-cmatch" below:

$localUsers = Get-ADObject -LDAPFilter "objectClass=Contact" -Properties TargetAddress,mail,objectGUID -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' | ?{($_.TargetAddress -cmatch '.onmicrosoft.com')}

because the "*" must have something preceding it; it'll barf if it's at the beginning of a "-cmatch" search string. Contrary to what one (I, for one) would expect, this actually finds anything ending with ".onmicrosoft.com"

Verify that we selected records that begin with "smtp" and also with displaying our proposed replacement "SMTP" version in the last column with which we plan to replace targetAddress in the column before.

$localUsers | Sort-Object Name | ft Name, objectGUID, mail, targetAddress, @{Name="NewTarget";Expression={"SMTP:" + $_.targetAddress.split(":")[1]}}

Or, perhaps this is we merely want to replicate the mail to target address:

$localUsers | Sort-Object Name | ft Name, objectGUID, mail, targetAddress, @{Name="NewTarget";Expression={"SMTP:" + $_.mail}}

Now we actually replace:

$localUsers | %{Set-ADObject -Identity $_.objectGUID -replace @{targetAddress = "SMTP:" + $_.targetAddress.split(":")[1]}}

Verify that the replace went as planned. Get all the objects in this OU and display their targetAddress:

Get-ADObject -LDAPFilter "objectClass=Contact" -Properties TargetAddress,mail -SearchBase 'OU=yourTenant,DC=yourDomain,DC=com' | Sort-Object Name | ft Name,mail,TargetAddress

There should no longer be any "smtp" left, only "SMTP".

Email-enabled security groups

Find all Email-enabled security groups that don't have a corresponding targetAddress:

$localSecurityGroups = Get-ADGroup -Filter {(GroupCategory -eq "Security") -and (Mail -like "*") -and (targetAddress -notlike "*") } -Properties TargetAddress,mail

Look to see what comes up:

$localSecurityGroups | ft Name, Mail, TargetAddress

$localSecurityGroups | %{Set-ADObject -Identity $_.objectGUID -replace @{targetAddress = "SMTP:" + $_.Mail.split("@")[0] + "@yourTenant.onmicrosoft.com"}}

Get-ADGroup -Filter {(GroupCategory -eq "Security") -and (mail -like "*")} -Properties TargetAddress,mail | ft Name, Mail, TargetAddress

–U–

user, find by email

Get-ADUser -Filter {mail -like "ac*"} -Properties UserPrincipalName, mail, distinguishedName | ft UserPrincipalName, mail, distinguishedName

See also

user, find by proxyAddresses

Get-ADObject -Properties mail, proxyAddresses -Filter {(proxyAddresses -like "*yourDomain.com") -and (ObjectClass -eq "user")} | sort-object name | ft Name, mail, proxyAddresses, distinguishedName

user, find by proxyAddresses and OU

Get-ADObject -Properties mail, proxyAddresses -SearchBase 'OU=yourOU,DC=yourDomain,DC=com' -Filter {(proxyAddresses -like "*yourDomain.com") -and (ObjectClass -eq "user")} | sort-object name | ft Name, mail, proxyAddresses, distinguishedname

–V–

–W–

WARNING: An error caused a change in the current set of domain controllers - whenever I get this:

WARNING: An error caused a change in the current set of domain controllers.

I've found that simply killing off my current session and starting up a new session seems to fix the problem.

–X–

X500 proxyAddresses, delete all such from all contacts in an OU

# delete all X500 proxyAddresses from contacts in an OU
$OU = "OU=someOU,DC=yourCompany,DC=com"
$localContacts = Get-ADObject -filter {objectclass -eq "contact"} -Properties proxyAddresses,objectGUID -SearchBase $OU
foreach ($contact in $localContacts)
{
    $proxyAddresses = $contact | select -ExpandProperty ProxyAddresses
    foreach ($address in $proxyAddresses)
    {
        if ($address -match "x500*")
        {
            Set-ADObject -Identity $contact.objectGUID -remove @{proxyAddresses = $address}
       }
    }
}

X500 proxyAddresses, delete all such from all users in an OU

# delete all X500 proxyAddresses from users in an OU
$OU = "OU=someOU,DC=yourCompany,DC=com"
$localUsers = Get-ADUser -Filter * -Properties proxyAddresses,mail,SamAccountName -SearchBase $OU
foreach ($user in $localUsers)
{
    $proxyAddresses = $user | select -ExpandProperty ProxyAddresses
    foreach ($address in $proxyAddresses)
    {
        if ($address -match "x500*")
        {
            Set-ADUser -Identity $user.SamAccountName -remove @{proxyAddresses = $address}
        }
    }
}

X500 proxyAddresses, suppress from view - see proxyAddresses, categorize

–Y–

–Z–