Wednesday, October 24, 2012

Duplicate SPNs in Active Directory can be serious and prevent the object from using Kerberos authentication. This may mean that access or an application my fail depending on it's ability and willingness to fall back to NTLM authentication. I run this script occasionally to gauge the health of the directory or sometimes to verify a report from Operations Manager. The script should be run using CSCRIPT so save it as (say) 'DuplicateSPN.VBS' and the run it on an admin cmd window on your domain controller thus:

script duplicatespn.vbs

When you get the result you will have to determine which SPN you wish to keep and delete the other.

*****************
Warning
*****************

Do not delete any KRBTGT records, they are MEANT TO BE duplicates

I may get around to converting this to PowerShell one day.

Cheers!


'==========================================================================
' NAME: Report Duplicate SPNS
' DATE  : 10/24/2012
'==========================================================================

Option Explicit
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strDN
Dim arrSPNs, strSPN, objList

Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
Set objRootDSE = GetObject("GC://RootDSE")
strDNSDomain = objRootDSE.Get("rootDomainNamingContext")
strBase = ""
strFilter = "(servicePrincipalName=*)"
strAttributes = "distinguishedName,servicePrincipalName"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF

   strDN = adoRecordset.Fields("distinguishedName").Value
   arrSPNs = adoRecordset.Fields("servicePrincipalName").Value
   If (TypeName(arrSPNs) = "String") Then
      If (objList.Exists(arrSPNs) = True) Then
         Wscript.Echo "Duplicate: " & arrSPNs
         Wscript.Echo " DN: " & strDN
         Wscript.Echo " DN: " & objList(arrSPNs)
      Else
         objList(arrSPNs) = strDN

      End If
      Else
      For Each strSPN In arrSPNs
         If (objList.Exists(strSPN) = True) Then
            Wscript.Echo "Duplicate: " & strSPN
            Wscript.Echo " DN: " & strDN
            Wscript.Echo " DN: " & objList(strSPN)
         Else
            objList(strSPN) = strDN
         End If
      Next

   End If
   adoRecordset.MoveNext
Loop
adoRecordset.Close
adoConnection.Close

No comments:

Post a Comment