I have provided a script below that has worked for this issue in the past.
This is something that is is provided "AS IS" with no warranties, and
confers no rights. You will need to test this in a lab environment before
you use the script but it should do the trick.
const ForReading = 1
const ForWriting = 2
const ForAppending = 8
set fso = createobject("scripting.filesystemobject")
set logf = fso.OpenTextFile("schchk.log", ForAppending, True)
schemafilename = WScript.Arguments(0)
filetocheck = WScript.Arguments(1)
' target domain will derive from the first object found in the schema ldif
'targetdomain = WScript.Arguments(2)
LogWriteLine ""
LogWriteLine String(80, "=")
LogWriteLine "schchk run at " & now
LogWriteLine "schema file " & schemafilename
LogWriteLine "schema addition file " & filetocheck
set oplist = CreateObject("scripting.dictionary")
set attrlist = createobject("scripting.dictionary")
set attrlistoid = createobject("scripting.dictionary")
set attrlistldap = createobject("scripting.dictionary")
set classlist = createobject("scripting.dictionary")
set classlistoid = createobject("scripting.dictionary")
set f = fso.OpenTextFile(schemafilename, 1)
LogWrite "Reading schema:"
start = Timer
nl = ""
do while not f.atendofstream
' read an operation in...
if nl <> "" Then
l = nl
nl = ""
else
l = f.readline
end if
l = ltrim(rtrim(l))
If left(l, 1) = "#" Then
' Ignore comments
ElseIf l = "" Then
If oplist.Count > 0 Then
' process oplist...
op = LCase(oplist("changetype"))
oplist("dn") = LCase(oplist("dn"))
If op = "add" Or op = "ntdsschemaadd" Then
If lcase(oplist("objectclass")) = "attributeschema" Then
attrlist(oplist("dn")) = array(oplist("attributeid"),
oplist("ldapdisplayname"))
attrlistoid(oplist("attributeid")) = array(oplist("dn"),
oplist("ldapdisplayname"))
attrlistldap(oplist("ldapdisplayname")) = array(oplist("dn"),
oplist("attributeid"))
ElseIf lcase(oplist("objectclass")) = "classschema" Then
classlist(oplist("dn")) = array(oplist("governsid"),
oplist("ldapdisplayname"))
classlistoid(oplist("governsid")) = array(oplist("dn"),
oplist("ldapdisplayname"))
End If
Else
LogWriteLine ""
LogWriteLine "Unexpected schema operation: " & op & " for " &
oplist("dn")
End If
If IsEmpty(targetdomain) And oplist("dn") <> "" Then
' assume this is not the nc head so there must be something before
dc=...
i = instr(oplist("dn"), ",dc=")
targetdomain = mid(oplist("dn"), i + 1)
End If
oplist.removeall
End If
else
' Add it
i = instr(l, ":")
if i <> 0 Then
op = lcase(ltrim(rtrim(left(l, i - 1))))
data = ltrim(rtrim(mid(l, i + 1)))
if left(data, 1) = ":" Then
' base 64 encoded...
base64enc = True
data = ltrim(mid(data, 2))
else
base64enc = False
end if
if data = "" Then
' read the data on subsequent lines...
do while not f.atendofstream
l = f.readline
if left(l, 1) <> " " Then
nl = l
exit do
end if
data = data & mid(l, 2)
loop
end if
if oplist.exists(op) Then
if (vartype(oplist(op)) and 8192) = 0 Then
oplist(op) = array(oplist(op), data)
else
a = oplist(op)
redim preserve a(ubound(a) + 1)
a(ubound(a)) = data
oplist(op) = a
end if
else
oplist(op) = data
end if
end if
End If
loop
LogWriteLine " done (" & Timer - start & ")."
LogWriteLine attrlist.Count & " attributes and " & classlist.Count & "
classes."
LogWriteLine ""
LogWrite "Processing file to check:"
start = Timer
set f = fso.OpenTextFile(filetocheck, 1)
nl = ""
do while not f.atendofstream
' read an operation in...
if nl <> "" Then
l = nl
nl = ""
else
l = f.readline
end if
l = ltrim(rtrim(l))
If left(l, 1) = "#" Then
' Ignore comments
ElseIf l = "" Then
If oplist.Count > 0 Then
' process oplist...
op = LCase(oplist("changetype"))
' substitute DC=X for the target domain
if lcase(right(oplist("dn"),4)) = "dc=x" Then
oplist("dn") = lcase(left(oplist("dn"), len(oplist("dn")) - 4) &
targetdomain)
else
oplist("dn") = lcase(oplist("dn"))
end if
if op = "add" or op = "ntdsschemaadd" Then
if lcase(oplist("objectclass")) = "attributeschema" Then
' verify that oid does not exist or if it does that the dn matches
' verify that dn does not exist or if it does exist that the oid
matches
' if everything checks out then add it to the list...
bError = False
If attrlistoid.exists(oplist("attributeid")) Then
If attrlistoid(oplist("attributeid"))(0) <> oplist("dn") Then
' oid already exist for a different dn
LogWriteLine ""
LogWriteLine "Oid " & oplist("attributeid") & " used in schema
addition " & _
oplist("dn") & " already exists for " & _
attrlistoid(oplist("attributeid"))(0)
LogWriteLine "Adding this attribute would result in duplicate oids
which is not allowed."
bError = True
End If
End If
If attrlist.exists(oplist("dn")) Then
If attrlist(oplist("dn"))(0) <> oplist("attributeid") Then
' dn already exists and is using a different oid
LogWriteLine ""
LogWriteLine "DN " & oplist("dn") & " is attempting to change oid
from " & _
attrlist(oplist("dn"))(0) & " to " & oplist("attributeid")
LogWriteLine "Oid will not be changed resulting in probable failure
to add a new class."
bError = True
End If
End If
If Not bError Then
attrlist(oplist("dn")) = array(oplist("attributeid"),
oplist("ldapdisplayname"))
attrlistoid(oplist("attributeid")) = array(oplist("dn"),
oplist("ldapdisplayname"))
attrlistldap(oplist("ldapdisplayname")) = array(oplist("dn"),
oplist("attributeid"))
End If
elseif lcase(oplist("objectclass")) = "classschema" Then
bError = False
If classlistoid.exists(oplist("governsid")) Then
If classlistoid(oplist("governsid"))(0) <> oplist("dn") Then
' oid already exist for a different dn
LogWriteLine ""
LogWriteLine "Oid " & oplist("governsid") & " used in schema
addition " & _
oplist("dn") & " already exists for " & _
classlistoid(oplist("governsid"))(0)
LogWriteLine "Adding this class would result in duplicate oids which
is not allowed."
bError = True
End If
End If
If classlist.exists(oplist("dn")) Then
If classlist(oplist("dn"))(0) <> oplist("governsid") Then
' dn already exists and is using a different oid
LogWriteLine ""
LogWriteLine "DN " & oplist("dn") & " is attempting to change oid
from " & _
classlist(oplist("dn"))(0) & " to " & oplist("governsid")
LogWriteLine "Oid will not be changed resulting in probable failure
to add child classes."
bError = True
End If
End If
' verify that all schema maycontain/mustcontain are valid...
If oplist.exists("systemmustcontain") Then
If (VarType(oplist("systemmustcontain")) And 8192) = 0 Then
oplist("systemmustcontain") = array(oplist("systemmustcontain"))
End If
For each attr in oplist("systemmustcontain")
' could be an oid or an ldap name...
if not attrlistldap.Exists(attr) and not attrlistoid.Exists(attr)
Then
LogWriteLine ""
LogWriteLine "Class " & oplist("ldapdisplayname") & " has a
systemMustContain attribute that is not present " & attr
End If
Next
End If
If oplist.exists("systemmaycontain") Then
If (VarType(oplist("systemmaycontain")) And 8192) = 0 Then
oplist("systemmaycontain") = array(oplist("systemmaycontain"))
End If
For each attr in oplist("systemmaycontain")
' could be an oid or an ldap name...
if not attrlistldap.Exists(attr) and not attrlistoid.Exists(attr)
Then
LogWriteLine ""
LogWriteLine "Class " & oplist("ldapdisplayname") & " has a
systemMayContain attribute that is not present " & attr
End If
Next
End If
If oplist.exists("mustcontain") Then
If (VarType(oplist("mustcontain")) And 8192) = 0 Then
oplist("mustcontain") = array(oplist("mustcontain"))
End If
For each attr in oplist("mustcontain")
' could be an oid or an ldap name...
if not attrlistldap.Exists(attr) and not attrlistoid.Exists(attr)
Then
LogWriteLine ""
LogWriteLine "Class " & oplist("ldapdisplayname") & " has a
MustContain attribute that is not present " & attr
End If
Next
End If
If oplist.exists("maycontain") Then
If (VarType(oplist("maycontain")) And 8192) = 0 Then
oplist("maycontain") = array(oplist("maycontain"))
End If
For each attr in oplist("maycontain")
' could be an oid or an ldap name...
if not attrlistldap.Exists(attr) and not attrlistoid.Exists(attr)
Then
LogWriteLine ""
LogWriteLine "Class " & oplist("ldapdisplayname") & " has a
mayContain attribute that is not present " & attr
End If
Next
End If
If Not bError Then
classlist(oplist("dn")) = array(oplist("governsId"),
oplist("lDAPDisplayName"))
classlistoid(oplist("governsId")) = array(oplist("dn"),
oplist("lDAPDisplayName"))
End If
End If
elseif op = "modify" or op = "ntdsschemamodify" Then
if oplist("dn") = "" Then
' ignore schema modify op
else
end If
else
LogWriteLine ""
LogWriteLine "Unexpected schema operation: " & op & " for " &
oplist("dn")
End If
oplist.removeall
End If
else
' Add it
i = instr(l, ":")
if i <> 0 Then
op = lcase(ltrim(rtrim(left(l, i - 1))))
data = ltrim(rtrim(mid(l, i + 1)))
if left(data, 1) = ":" Then
' base 64 encoded...
base64enc = True
data = ltrim(mid(data, 2))
else
base64enc = False
end if
if data = "" Then
' read the data on subsequent lines...
do while not f.atendofstream
l = f.readline
if left(l, 1) <> " " Then
nl = l
exit do
end if
data = data & mid(l, 2)
loop
end if
if oplist.exists(op) Then
if (vartype(oplist(op)) and 8192) = 0 Then
oplist(op) = array(oplist(op), data)
else
a = oplist(op)
redim preserve a(ubound(a) + 1)
a(ubound(a)) = data
oplist(op) = a
end if
else
oplist(op) = data
end if
end if
End If
loop
LogWriteLine " done (" & Timer - start & ")."
logf.Close
'
****************************************************************************
**
Function LogWrite(s)
logf.Write s
WScript.StdOut.Write s
End Function
'
****************************************************************************
**
Function LogWriteLine(s)
logf.WriteLine s
WScript.StdOut.WriteLine s
End Function
'
****************************************************************************
**
Function LogWriteBlankLine
logf.WriteLine
WScript.StdOut.WriteLine
End Function