When Active Directory objects on a domain controller are deleted or become corrupted, you may have to restore them using a system state backup that contains the Active Directory database. You may then have to use the Ntdsutil.exe tool to mark the restored versions of these objects as authoritative.
On a domain controller that is running at least Windows Server 2003 with Service Pack 1 or later Windows versions, the Ntdsutil tool writes back links for the objects that are restored authoritatively into LDF files.
If you have enabled credential roaming for some users which need to be restored, following error may occur:
ldifde -i -k -f ar_xxxx.ldf
Connecting to "dc01.contoso.com"
Logging in as current user using SSPI
Importing directory from file "ar_20090710-084606_links_adb.contoso.com.ldf"
Loading entries...............................
Add error on line <xxx>: Invalid Syntax
The server side error is "The parameter is incorrect."
28 entries modified successfully.
An error has occurred in the program
No log files were written. In order to generate a log file, please specify the log file path via the -j option.
The problem is caused by an incorrect format of the LDF file created when doing the authoritative restore in the Ntdsutil tool.
The LDF file contains a syntax error in line modifying following attributes:
- msPKIDPAPIMasterKeys
- msPKIAccountCredentials
- msPKIRoamingTimeStamp
These attributes can be found on user objects, where credential roaming is enabled.
You can use the following script to remove the msPKI attributes that are causing the problem from the LDF file.
---- remove_msPKI_entries.vbs ----
Const forReading = 1
Const forWriting = 2
Const insideEntry = 0
Const foundNewEntry = 1
Dim deleteEntry
Dim strNextLine
Dim state
Dim state1
Dim strPath
Dim strLdifdeFileName
Dim strLdifdeFileFullPath
Dim strNewLdifdeFileName
Dim strNewLdifdeFileFullPath
Dim strtempFileName
Dim strtempFileFullPath
If wscript.Arguments.Count <> 2 Then
wscript.echo( "=======================================================================================" )
wscript.echo( "Usage: cscript remove-msPKI-attrs.vbs <old_ldifde_back_links_file> <new_ldifde_back_links_file>" )
wscript.echo( "" )
wscript.echo( "Example: cscript remove-msPKI-attrs.vbs ar_20091102-135937_links_mydom.com.ldf new_ar_20091102-135937_links_mydom.com.ldf")
wscript.echo( "" )
wscript.echo( "msPKIDPAPIMasterKeys, msPKIAccountCredentials, msPKIRoamingTimeStamp back links will be deleted from")
wscript.echo( "<old_ldifde_back_links_file> and remaining entries will be written into <new_ldifde_back_links_file>" )
wscript.echo( "" )
wscript.echo( "NOTE: If <new_ldifde_back_links_file> is already existing in current directory... its contents will be overwritten" )
wscript.echo( "=======================================================================================" )
wscript.Quit -1
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
'All the files assumed to be in current directory
strPath = "."
strLdifdeFileName = wscript.Arguments(0)
strLdifdeFileFullPath = objFSO.BuildPath(strPath, strLdifdeFileName)
strNewLdifdeFileName = wscript.Arguments(1)
strNewLdifdeFileFullPath = objFSO.BuildPath(strPath, strNewLdifdeFileName)
strtempFileName = objFSO.GetTempName
strtempFileFullPath = objFSO.BuildPath(strPath, strtempFileName)
'Open the given ldifde file for reading
Set objLdifdeFile = objFSO.OpenTextFile( strLdifdeFileFullPath, forReading )
'Open a temporary file for writing
Set objNewLdifdeFile = objFSO.OpenTextFile( strNewLdifdeFileFullPath, forWriting, true )
state = foundNewEntry
Do Until objLdifdeFile.AtEndOfStream
strNextLine = objLdifdeFile.Readline
If state = foundNewEntry Then
state = insideEntry
set objtempFile = objFSO.OpenTextFile( strtempFileFullPath, forWriting, true)
End If
objtempFile.WriteLine( strNextLine )
If StrComp( strNextLine, "-" ) = 0 Then
state = foundNewEntry
objtempFile.Close
set objtempFile = objFSO.OpenTextFile( strtempFileFullPath, forReading )
state1 = foundNewEntry
deleteEntry = 0
Do Until objtempFile.AtEndOfStream
strNextLine = objtempFile.ReadLine
If state1 = insideEntry Then
state1 = foundNewEntry
If Instr( strNextLine, "msPKIDPAPIMasterKeys") <> 0 Then
deleteEntry = 1
ElseIf Instr( strNextLine, "msPKIAccountCredentials" ) <> 0 Then
deleteEntry = 1
ElseIf Instr( strNextLine, "msPKIRoamingTimeStamp" ) <> 0 Then
deleteEntry = 1
End If
ElseIf InStr( strNextLine, "ChangeType:" ) = 0 Then
state1 = insideEntry
End If
Loop
objtempFile.Close
set objtempFile = objFSO.OpenTextFile( strtempFileFullPath, forReading )
If deleteEntry = 0 Then
Do Until objtempFile.AtEndOfStream
StrNextLine = objtempFile.ReadLine
objNewLdifdeFile.WriteLine( strNextLine )
Loop
End If
objtempFile.Close
objFSO.DeleteFile( strtempFileFullPath )
End If
Loop
objLdifdeFile.Close
objNewLdifdeFile.Close
--------
Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See
Terms of Use
(http://go.microsoft.com/fwlink/?LinkId=151500)
for other considerations.
Article ID: 2014074 - Last Review: March 11, 2010 - Revision: 5.0
APPLIES TO
- Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
- Microsoft Windows Server 2003 R2 Enterprise x64 Edition
- Windows Server 2008 Enterprise
- Windows Server 2008 R2 Enterprise