Migration : Cleanup SIDHistory
One of the last steps in an Actiove Directory migration is the removal of SIDHistory from migrated users, computers and groups. This will help reduce the size of the directory database.
Before cleanup of SIDHistory domain-wide, you should perform cleanup on a single OU and analyse the effects on applications such as AzMan and Sharepoint. Watch out for DCOM remote launch pernmissions. It is possible to modify the script to target individual users for this purpose.
The following VBScript will perform a SIDHistory cleanup of all user objects (this can be altered) within a particular OU. It is possible to change the LDAP filter and OU string to suit testing and cleanup of various object classes. Alternately, by changing the line strOU = “OU=UK,” to strOU = “” willl perform SIDHistory cleanupon all objects within every OU.
Remember to perform cleanup on the following objectClass types, changing the code in RED will allow you to perform cleanup of different objectClass’: User, Computer, Contact, Group.
Const ADS_PROPERTY_DELETE = 4
Const ADS_PROPERTY_UPDATE = 2Dim strFilter ‘As String
Dim oConnection ‘As ADODB.Connection
Dim oRecordSet ‘As ADODB.RecordSet
Dim strQuery ‘As String
Dim strDomainNC ‘As String
Dim oRootDSE ‘As IADs
Dim vArray ‘As Variant()
Dim vSid ‘As Variant
Dim oDirObject ‘As Variant
Dim strOU ‘As String‘ Find the domain naming context
set oRootDSE = GetObject(“LDAP://RootDSE”)
strDomainNC = oRootDSE.Get(“defaultNamingContext”)
set oRootDSE = Nothing‘ Setup the ADO connection
Set oConnection = CreateObject(“ADODB.Connection”)
oConnection.Provider = “ADsDSOObject”
oConnection.Open “ADs Provider”
‘Target OrganizationalUnit
strOU = “OU=UK,”
‘Target objectClass
strFilter = “(&(objectClass=user))”
strQuery = “;” & strFilter & “;distinguishedName,objectClass,name,sidHistory;subtree”‘Execute the query
set oRecordSet = oConnection.Execute(strQuery)if oRecordSet.Eof then
WScript.Echo “No objects were found”
WScript.Quit(0)
Else
Dim vClasses ‘As Variant
Dim strClass ‘As StringWScript.Echo “Name, Class, DN, SIDHistory”
‘ Iterate through the objects that match the filter
While Not oRecordset.Eof
vClasses = oRecordset.Fields(“objectClass”).Value
strClass = vClasses(UBound(vClasses))
If IsNull(oRecordSet.Fields(“sIDHistory”).Value ) Then
WScript.Echo “This object does not have a sidHistory”
Else
set oDirObject = GetObject(“LDAP://” & oRecordset.Fields(“distinguishedName”).Value)
vArray = oDirObject.GetEx(“sIDHistory”)
For Each vSid in vArray
If OctetToHexStr(vSid) > “” Then
WScript.Echo chr(34) & oRecordset.Fields(“name”).Value & chr(34) & “,” & _
chr(34) & strClass & chr(34) & “,” & chr(34) & _
oRecordset.Fields(“distinguishedName”).Value & chr(34) & “,” & chr(34) & _
OctetToHexStr(vSid) & chr(34)
End If
NextoDirObject.SetInfo
WScript.Echo “The sidHistory has been cleared for this object!”
End if
WScript.Echo
oRecordset.MoveNext
Wend
End if‘Clean up
Set oRecordset = Nothing
Set oConnection = NothingFunction OctetToHexStr(sOctet)
Dim k
OctetToHexStr = “”
For k = 1 To Lenb(sOctet)
OctetToHexStr = OctetToHexStr _
& Right(“0” & Hex(Ascb(Midb(sOctet, k, 1))), 2)
Next
End Function