I need your help in fixing the below script where the goal here is to set the UserprincipalName to the same as the ProxyAddress SMTP: (PrimarySMTP) entry.
$paramGetADUser = @{
Filter = "Enabled -eq 'True'"
Properties = 'EmailAddress', 'UserPrincipalName', 'SamAccountName'
SearchBase = 'OU=Users,DC=Domain,DC=com'
SearchScope = 'Subtree'
}
$ADUsers = Get-ADUser @paramGetADUser |
Where-Object { $_.UserPrincipalName -ne $_.EmailAddress } |
Select-Object Name, EmailAddress, UserPrincipalName, SamAccountName
foreach ($ADuser in $ADUsers)
{
Write-Host "Processing $($ADuser.Name)" -ForegroundColor Yellow
$paramSetADUser = @{
Identity = $ADuser.SamAccountName
UserPrincipalName = $_.EmailAddress
}
Set-ADUser @paramSetADUser
Get-ADUser -Identity $ADuser.SamAccountName |
Select-Object Name, EmailAddress, UserPrincipalName |
Format-Table -AutoSize
}
The script above somehow will reset or set the UserPrincipalName to be empty when there is no EmailAddress value, this is dangerous and NOT what I wanted.
How to prevent the issue above and achieve the standardization of UPN = PrimarySMTPAddress?
Thank you in advance.
CodePudding user response:
A minor modification to your current code, instead of using EmailAddress
, use mail
and use AD Filter / LDAP Filter to query only for those user that have this attribute set:
$paramGetADUser = @{
LDAPFilter = "(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))"
Properties = 'mail', 'UserPrincipalName', 'SamAccountName'
SearchBase = 'OU=Users,DC=Domain,DC=com'
SearchScope = 'Subtree'
}
foreach ($ADuser in Get-ADUser @paramGetADUser) {
if($ADUser.UserPrincipalName -eq $ADuser.mail) {
continue
}
Write-Host "Processing $($ADuser.Name)" -ForegroundColor Yellow
$paramSetADUser = @{
Identity = $ADuser.SamAccountName
UserPrincipalName = $ADuser.mail
}
Set-ADUser @paramSetADUser
Get-ADUser -Identity $ADuser.SamAccountName |
Select-Object Name, EmailAddress, UserPrincipalName |
Format-Table -AutoSize
}
CodePudding user response:
Your question is correctly talking about getting the primary email address from the users ProxyAddress
attribute (that is where Exchange also gets it from).
AFAIK, you should not rely on the users mail
attribute, which may have a totally different value than the one that is actually used for emailing.
I would suggest something like below:
# Get-ADUser by default already returns objects with these properties:
# DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
$paramGetADUser = @{
Filter = "Enabled -eq 'True'"
Properties = 'ProxyAddresses', 'EmailAddress'
SearchBase = 'OU=Users,DC=Domain,DC=com'
SearchScope = 'Subtree'
}
$result = Get-ADUser @paramGetADUser | ForEach-Object {
$primaryMail = ($_.ProxyAddresses | Where-Object { $_ -clike 'SMTP:*' }) -replace '^SMTP:'
if ([string]::IsNullOrWhiteSpace($primaryMail)) {
Write-Warning "User $($_.SamAccountName) does not have a Primary Email Address.."
continue
}
if ($_.UserPrincipalName -eq $primaryMail) {
Write-Host "User $($_.SamAccountName) already has a correct UPN"
# output unchanged
$_ | Select-Object Name, EmailAddress, UserPrincipalName, SamAccountName, @{Name = 'IsUpdated'; Expression = {'No'}}
}
else {
Write-Host "Setting UPN for user $($_.SamAccountName) to '$primaryMail'"
$_ | Set-ADUser -UserPrincipalName $primaryMail
# refresh and output
Get-ADUser -Identity $_.DistinguishedName |
Select-Object Name, EmailAddress, UserPrincipalName, SamAccountName, @{Name = 'IsUpdated'; Expression = {'Yes'}}
}
}
# output on screen
$result | Format-Table -AutoSize
# output to CSV file
$result | Export-Csv -Path 'X:\somewhere\UserPrincipalNames.csv' -NoTypeInformation