Find duplicated SPNs in Active Directory

Today’s script will help you to in easy way find duplicated SPNs in Active Directory.

What is SPN?

SPN (Service Principal Name) according to Microsoft definition is unique identifier of service instance. To better understand it we can compare it to alias (CNAME record) in DNS.
A Service Principal Name is a pointer to account created in Active Directory domain. It can be either created for service account or computer object account.
E.g.
HTTP/TestWebSite is an alias for the account Contoso.com\TestWebSiteAccount.

Below screenshot from Active Directory attribute of Service Principal.

How script works?

Script is gathering all users and computers account from Active Directory where Service Principal Name attribute is not empty.
In next section it is analyzing all service principal names and looks for duplicated.
If the script will find Service Principal Names with different SamAccountNames it will notify user that duplicated SPN has been found.

Script:
$AllSPNsObjects = Get-ADObject -Filter "(objectClass -eq 'user') -and (objectClass -eq 'computer')" -Properties sAMAccountName, servicePrincipalName | Where-Object servicePrincipalName -ne $null
$SPNArray = @()
 
foreach ($SPNObject in $AllSPNsObjects)
{
   $SamAccountName = $ADObject.SamAccountName
   $ServicePrincipalNames = $ADObject.ServicePrincipalName
 
   foreach ($ServicePrincipalName in $ServicePrincipalNames)
   {
		if ($SPNArray.ServicePrincipalName -like "$ServicePrincipalName")
		{
			$MatchedSPNs = $SPNArray -like "$ServicePrincipalName"
			foreach ($MatchSPN in $MatchedSPNs)
			{
				$MatchSamAccountName = $MatchSPN.SamAccountName
				if ($MatchSamAccountName -ne $SamAccountName)
				{
				   Write-Error "Duplicated SPN has been found for $ServicePrincipalName!!!"
                }
			}
		}
		else
		{
			$Properties =  @{
                "SamAccountName" = $SamAccountName
                "ServicePrincipalName" = $ServicePrincipalName
            }
      
             $SPNArrayRow = New-Object PSObject -Property $Properties
             $SPNArray += $SPNArrayRow
		}
   }
}

Please note that script can be running for a while in bigger environments as filtering all objects with SPNs takes some time.
Script is not using standard SPN cmdlet setspn as it is always better to use PowerShell command instead of command line tool (at least in my humble opinion ;).

Hope it will be usefull for some of you 😉
Enjoy!

Leave a Reply

Your email address will not be published. Required fields are marked *