Migrating SIDHistory without Source AD RPC connectivity

I recently had a very interesting project where Source company was splitting off one of its branches to join Target company, and as such, what we could do with the Source AD was very limited. There was no direct Source AD RPC connectivity, and we could only have AD attributes export of to-be-migrated objects via csv text files. QMM was out of the question (yet, we still managed to find a good use for it!)

The answer was DSInternals PowerShell module and its Add-ADDBSIDHistory command-let. This module has many interesting capabilities of working with ntds.dit AD database file, one of which is direct-injecting SIDHistory into any user or group object. Please note that while this module is fully official (meaning it’s not some sort of “dark world” AD hacking tool) and its author is well-recognized IT Professional specializing in AD Security, the technique itself is not directly supported by Microsoft. Therefore if you use it in production environment and AD gets corrupt down the road, you are out of luck to say it lightly. To address this concern we deployed temporary jump-Domain “CONTOSO” where DSInternals was utilized, and then gracefully introduced AD objects with their SIDHistories into production AD. Here’s how we did it at high level:

  1. Preparing dev environment
    • Deployed jump-domain
    • Created stub-DNS zones for name resolution
    • Installed DSInternals (can go on member server or directly on lump-Domain DC)
      • Ensured PowerShell is at least version 5
      • Install-Module DSInternals Force
  2. Account provisioning into jump-Domain
    • Obtaining Directory exports from Source company for the users and groups to be migrated, just regular text csv files, including objectSID attribute in its string format like S152136238111023361067346-97300842529 and any other relevant attributes
    • Provision objects maintaining samAccountName and other key attributes
    • Don’t forget about group membership. We used “Member” and “MemberOf” to make it more flexible. Originating object’s DN was written into newly provisioned object “AdminDescription” attribute, making cross-references and links resolving easier to handle
    • Stop AD Services which are using / locking ntds.dit database:

      Stop-Service Name ntds Force

    • Run SIDHistory import command, here are few examples:

Add-ADDBSidHistory SamAccountName accounting SidHistory S152136238111023361067346-97300842529 DBPath \\adc1\c$\Windows\NTDS\ntds.dit

import-csv C:\Quest\ADExport.csv | % {write-host “Handling $($_.samAccountName)…”; Add-ADDBSidHistory -SamAccountName $($_.samAccountName) -SidHistory $($_.objectSID) -DBPath \\ADC1\c$\Windows\NTDS\ntds.dit}

    • Start AD Services back up:

Start-Service Name ntds

3. Migrating objects from jump-Domain into production. Here you can use your regular QMM skills.

4. To make it very clean, since QMM also brings over originating jump-Domain’s temp object SID making it 2 SIDHistories as a result, you can also selectively clean redundant SIDHistories. Here’s the command you can start with. It purges all SIDHistories found on the object but you can insert “If” statement to compare it to certain SID pattern and only erase those values. Note that command line it’s taken from the script so some variables are out of context and need to be adjusted.

Get-ADObject -Server $DC -LDAPFilter “(samaccountname=$($object.samAccountName))” -Properties SIDHistory | Select-Object -ExpandProperty SIDHistory | Select-Object -ExpandProperty Value | % {write-host”Erasing $_”; “$($object.samAccountName),$_” | out-file$log -Append; Set-ADgroup -Server $DC -Identity $($object.samAccountName) -Remove @{SIDHistory=”$_”}}

5. Processing resources on user machines or file servers.

    • Can use QMM RUM GUI to process resources based on SIDHistory
    • Can use QMM command-line Vmover.exe with SIDHistory processing capabilities

-Copy locally and then start via this command:

Vmover.exe /c /INI=Vmover.ini /system=localhost 

Or remotely:

Vmover.exe /c /INI=Vmover.ini /system=Win10.Domain.local

Vmover.ini file example, note that highlighted in red lines need to be adjusted per your environment

[dmw7]

[Options]

Clone=Yes

CleanUp=No

Undo=No

LocalGroups=Yes

UserPrivileges=Yes

Services=Yes

ScheduledTasks=Yes

Profiles=Yes

RoamingProfiles=Yes

Registry=Yes

FileSystem=Yes

ProcessFileSystemOwner=Yes

Shares=Yes

Printers=Yes

COMPlus=Yes

DCOM=Yes

IIS=Yes

LogFile=vmover.log

StateFile=vmover.txt

LogMask=15

SharesExtendedLogging=No

InstallProfilesAgent=No

AutoRemove=No

MaxErrors=10

Version=450

MaxCriticalErrors=1

MaxRegUsage=95

ProcessRegGroupOwner=No

UpdateStateSec=1

SetArchiveBit=No

BackupShares=No

DumpMap=No

sidHistory=Yes

hostName=RDC.Domain.LOCAL:389

ldapUser=administrator

ldapDomain=Domain

ldapPsw=Pa$$word12345