Home > Blockchain >  Set the UserPrincipalName to be the same as PrimarySMTPAddress?
Set the UserPrincipalName to be the same as PrimarySMTPAddress?

Time:04-09

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
  • Related