Using Powershell to Set User UPN’s in Active Directory

Today, in doing further work on Office 365 migrations we had a client that has 5 different domains and we needed to set the UPN on each user to their primary domain prior to syncing with AD Connect. This client had hundreds of users so manual was not an option nor should it have been in my opinion even with 10.

First there were a few steps that we had to perform to get this setup and ready to go. This particular client already had OU’s in the SBSUsers OU for each of the domains. We had to go through each OU and create another OU inside called ‘No SYNC’. We had to do this because some users had mailboxes on each of these domains and we did not want to sync the non-primary domains to Azure AD as user accounts but instead will do DL’s. That will be another article.

The second thing that we did was to go into each of the OU’s for the domains and set the Description attribute to the domain. This will allow us to match up the OU for each domain in Powershell.

The first thing we will do is import the Active Directory module and set the $verbosepreference variable to continue so that the Write-Verbose cmdlet will output to console. After that we are creating an array of strings containing each domain.

# import the Active Directory module to get the cmdlets
import-module activedirectory
# set verbose preference for the Write-Verbose cmdlet
$VerbosePreference = 'continue'
# first step is to go to each OU and set the description attribute to the domain and add the users
# listing all of the domains that are needing to change
$domains = 'domain1.com','domain2.com','domain3.com','domain4.com','domain5.com'

 

In the next section, we are getting the OU’s from the SBSUsers OU and placing them as an array in the $OUs variable.

# get the the list of OUs from the root SBSUsers OU
$SBSUsersOU = Get-ADOrganizationalUnit -Identity 'OU=SBSUsers,OU=Users,OU=MyBusiness,DC=domain,DC=local'
$OUs = Get-ADOrganizationalUnit -LDAPFilter "(name=*)" -Properties * -SearchBase $SBSUsersOU -SearchScope OneLevel

 

Now we will loop through the $domains array and add each domain to the $domain variable one at a time

# loop through each domain
foreach ($domain in $domains){
    $domain
    # loop through each OU 

 

Now we will loop through each of the OU’s in the $OUs array and place the current OU in the $OU variable

    foreach ($OU in $OUs){
        # match the previously set description field to the domain

 

If the current domain matches the description attribute of the current OU then we will get a list of all of the users in that OU and place them as an array in $Users. Then we will loop through each user one at a time and place them in the $User variable.

        if ($OU.Description -match $domain){
            # get a list of all users in the OU
            $users = Get-Aduser -filter * -SearchBase $OU -SearchScope OneLevel
            # loop through each user one at a time
            foreach ($user in $users){

 

Now I am outputting to the console the name of the user and its current UPN. I am doing this so that I can watch for what users we are acting on at the current time. We will then create the UPN by concatenating the users logon from the UserPrincipleName property and the current domain in the domain loop.

                $name = $user.Name
                Write-Verbose "$name has a UPN of $($user.UserPrincipalName)"
                # create the new UPN from the user's login and the domain
                $upn = $user.SamAccountName + '@' + $domain
                # check to see if it is already correct

In the next section, we will first check to see if the user's UPN is already set correctly and set it if not or output that it is already correct if it is set.
                if ($($user.UserPrincipalName) -ne $upn){
                    # set the UPN to the new UPN
                    Write-Verbose "Setting $name to $upn"
                    Set-ADUser $user -UserPrincipalName $upn
                } else {
                    # no need to do anything as it is already correct
                    Write-Verbose "$name already has the correct UPN of $($user.UserPrincipalName)"
                }
            }
        } 
    }
}

Here is the full code for the script….

# import the Active Directory module to get the cmdlets
import-module activedirectory
# set verbose preference for the Write-Verbose cmdlet
$VerbosePreference = 'continue'
# first step is to go to each OU and set the description attribute to the domain and add the users
# listing all of the domains that are needing to change
$domains = 'domain1.com','domain2.com','domain3.com','domain4.com','domain5.com'
# get the the list of OUs from the root SBSUsers OU
$SBSUsersOU = Get-ADOrganizationalUnit -Identity 'OU=SBSUsers,OU=Users,OU=MyBusiness,DC=domain,DC=local'
$OUs = Get-ADOrganizationalUnit -LDAPFilter "(name=*)" -Properties * -SearchBase $SBSUsersOU -SearchScope OneLevel
# loop through each domain
foreach ($domain in $domains){
    $domain
    # loop through each OU 
    foreach ($OU in $OUs){
        # match the previously set description field to the domain
        if ($OU.Description -match $domain){
            # get a list of all users in the OU
            $users = Get-Aduser -filter * -SearchBase $OU -SearchScope OneLevel
            # loop through each user one at a time
            foreach ($user in $users){
                $name = $user.Name
                Write-Verbose "$name has a UPN of $($user.UserPrincipalName)"
                # create the new UPN from the user's login and the domain
                $upn = $user.SamAccountName + '@' + $domain
                # check to see if it is already correct
                if ($($user.UserPrincipalName) -ne $upn){
                    # set the UPN to the new UPN
                    Write-Verbose "Setting $name to $upn"
                    Set-ADUser $user -UserPrincipalName $upn
                } else {
                    # no need to do anything as it is already correct
                    Write-Verbose "$name already has the correct UPN of $($user.UserPrincipalName)"
                }
            }
        } 
    }
}

Leave a Reply

Your email address will not be published.