Een ADMT migratie Howto - IT-professional Community Blog
Zoeken binnen blogs.microsoft.nl

IT-professional Community Blog

Een ADMT migratie Howto

Feb 25 2009, 08:45 PM

Bij een klant  doe ik op dit moment een AD migratie van twee domainen naar één domain. We hebben er voor gekozen om de Users te migreren met een ADMT script. In deze blog wil ik eens stil staan bij de script die ik geschreven heb voor mijn klant.

VOORWERK


Voordat het script uitgevoerd kan worden moeten de volgende zaken geregeld zijn:

  1. Opzetten “two way trust” tussen de oude domainen, old1.local en old2.local, en het nieuwe domain nieuwe.local om toegang te krijgen tot alle user accounts.
  2. ADMT installeren,
  3. Het aanmaken van de gebruiker miguser in alle domainen,
  4. Het installeren van de PEN servers op één van de domain controllers in het old1.local domain en in het old2.local domain,


SETUP ADMT

ADMT kan gedownload worden van: Http://www.microsoft.com/downloads/details.aspx?FamilyID=6f86937b-533a-466d-a8e8-aff85ad3d212&displaylang=en
Installeren ADMT 3.0

  • Ga naar de locatie waar je ADMT 3.0 gedownload hebt en start ADMTSetup.exe op.
  • Op de Active Directory Migration Tool Installation Wizard scherm klik next
  • Kies I Agree, Next

MS SQL Server Desktop Engine wordt geïnstalleerd

  • Op de Database Selection, next
  • Op de Active Directory Migration Tool v2 Database Import klik next
  • Klik Finish


Aanmaken Migratie user account

Om users te kunnen migreren moet er in beide domains een account aanwezig zijn met dezelfde naam en wachtwoord. Op die manier is het mogelijk om vanuit het nieuwe domain in te loggen op de oude domain

  1. Maak in alle domeinen (nieuwe.local, old2.local, old1.local) de volgende user aan: Username: Miguser Password: **************
  2. Maak deze user lid van domain admins. Hij moet alle accounts kunnen aanmaken en heeft dus de juiste rechten nodig. Je kunt ook kiezen om te werken met delegation of control en de account alleen rechten geven op de juiste OU.  Disable of verwijder dit account na de migratie.
  3. Maak de user nieuwe.local\miguser lid van de old1.local\administrators groep en old2.local\administrators groep. Net als bij 2 moet het account bij alle user in het oude domain kunnen

Setup Password Export Server

De Password Export Server (PES) zorgt er voor dat het ADMT script de wachtwoorden van alle users kan migreren naar het nieuwe domain. Hiervoor moet service dus als super-super-super  user toegang hebben tot het AD. Dit maakt het dus security technisch een zeer gevaarlijke service die pas gestart mag worden als de migratie begint.
Als eerste zul je een key moeten maken voor het oude domain in het nieuwe domain
1.    Log aan op de DC waarop ADMT 3.0 is geïnstalleerd
2.    Open een CMD
3.    Ga naar de directory c:\Windows\Admt\PES
4.    Run het volgende commando voor het Old2.local domain: Admt key /option:create /sourcedomain:old2.local/keyfile:c:\windows\admt\pes\geminikey /pwd:*<enter>
5.    Hij vraagt nu om een wachtwoord. Deze heb je zo weer nodig dus noteer hem
6.    Kopieer de inhoud van de directory c:\windows\admt\pes naar een domain controller van het old2.localdomain onder c:\pes.
7.    Log nu aan op een domain controller van het old2.localdomain
8.    Open een CMD
9.    Ga naar de directory c:\pes
10.    Run Pwdmig.msi
Nu ga je PES service installeren in het oude domain.
11.    Klik Next
12.    Op de Encryption File browse naar c:\pes en selecteer geminikey.pes bestand
13.    Klik Open
14.    Klik Next
15.    Voer het wachtwoord in.
16.    Klik Next
17.    Op de ADMT Password Migration DLL kies je als service account old2.local\miguser
18.    Herstart de domain controller.
19.    Na de restart moet je de Password Export Server Service starten. Deze staat standaard op manual.
Herhaal fase voor elke domain dat je migreerd naar het nieuwe domain


MIGRATIE SCRIPT


Voor de migratie van de user wordt er gebruik gemaakt van een script. Aan het einde van de blog staat de uitdraai van het script.  Maar eerst wordt er een uitleg gegeven over het script en hoe het script gedraaid dient te worden.

SCRIPT UITLEG


Het script is bedoeld om de user account vanuit het source domain te migreren naar een nieuwe target domain inclusief de wachtwoorden van user accounts. In de onderstaande tabel staat een uitleg van het script per regel.
!!! LET OP!!! Alleen daar aanpassing doen als er in de tabel staat dat het mag. In elke ander situatie kan dit leiden tot een niet werkend script.
regel    Uitleg

Regel Uitleg
1 Option Explicit zorgt er voor dat elke variabel gedefinieerd MOET worden, voordat hij gebruikt mag worden. Hierdoor worden eventuele tik fouten voorkomen
3 t/m 105 In deze regels staan een aantal constanten gedefinieerd. Aanpassing in deze regels kunnen er voor zorgen dat het script niet langer werkt.
106-122 Variables definities
123-166   Aanmaken en openen van de logfiles
De migratie log is terug te vinden onder  C:\Scripts\Reports\Miglog.csv
De Error log is terug te vinden onder C:\Scripts\Reports\MigErrorlog.csv
166-189  Aanmaken van het Migratie object. Dit object is noodzakelijk om te kunnen migreren. De volgende waardes mogen worden aangepast:
objMigration.SourceDomain = Source domain
objMigration.SourceDomainController = Source DC
objMigration.SourceOU = Source OU waar de te migreren gebruikersaccount in staan. Ook eventuele users in child OUs zullen meegenomen worden.
objMigration.PasswordServer = De DC waar de PES service op geïnstalleerd is
190-207 Aanmaken van het user migratie object. Je hebt in regel 166 t/m 189 het migratie object gemaakt. Je defineert nu een child om de user te migreren. Op dezelfde manier kun je ook groepen en een computer migreren.
208-209 Deze regel start de daadwerkelijke migratie.
212-230 Aanmaken van een HTML report. Deze is terug te vinden in c:\Scripts\Reports
231-237 Deze regels copiëren de password vanuit het source domain naar de target domain
238-268 Afsluiten van de logfiles
269-einde Migratie event handling.

DRAAIEN VAN HET SCRIPT

Als het script aan je wensen is aangepast kun je beginnen met het draaien van het script
1.    Maak de directory c:\scripts en c:\scripts\reports aan op de DC waarop ADMT is geïnstalleerd.
2.    Kopieer de regels aan het einde van de blog naar notepad.
3.    Pas de regels 166-189 aan, zodat het juiste source domain, source ou en target ou vermeld staat.
4.    Sla dit bestand op als Migusersourcedomain.vbs
5.    Open een CMD
6.    Run het volgende commando: runas /user:miguser cmd.exe <enter> en voer het juiste wachtwoord in.
7.    Je krijgt nu een nieuwe CMD. Voer de volgende stappen uit in deze CMD
8.    Ga naar c:\scripts
9.    Voer het volgende commando in cscript migusersourcedomain.vbs <enter>
De migratie wordt nu uitgevoerd. Afhankelijk van de grote van het domain kan dit wel even duren. Pak rustig een bak koffie of twee of drie of …….  Bestudeer na afloop de logfiles in c:\script\reports voor eventuele accounts die niet goed gegaan zijn.

SCRIPT

Vanaf NU vind je HET script. Copieren en in notepad plakken. Veel plezier met het script.

Martijn Bellaard


1.    Option Explicit
2.    '----------------------------------------------------------------------------
3.    ' ADMT Scripting Constants
4.    ' Niet aanpassen en niet aankomen
5.    '----------------------------------------------------------------------------
6.    ' PasswordOption constants
7.    Const admtComplexPassword        = &H0001
8.    Const admtCopyPassword                         = &H0002
9.    Const admtDoNotUpdatePasswordsForExisting       = &H0010
10.    ' ConflictOptions constants
11.    Const admtIgnoreConflicting                  = &H0000
12.    Const admtMergeConflicting                        = &H0001
13.    Const admtRemoveExistingUserRights            = &H0010
14.    Const admtRemoveExistingMembers               = &H0020
15.    Const admtMoveMergedAccounts                  = &H0040
16.    ' DisableOption constants
17.    Const admtLeaveSource                    = &H0000
18.    Const admtDisableSource                  = &H0001
19.    Const admtTargetSameAsSource             = &H0000
20.    Const admtDisableTarget                  = &H0010
21.    Const admtEnableTarget                   = &H0020
22.    ' SourceExpiration constant
23.    Const admtNoExpiration = -1
24.    ' Translation Option
25.    Const admtTranslateReplace     = 0
26.    Const admtTranslateAdd         = 1
27.    Const admtTranslateRemove      = 2
28.    ' Report Type
29.    Const admtReportMigratedAccounts      = 0
30.    Const admtReportMigratedComputers = 1
31.    Const admtReportExpiredComputers      = 2
32.    Const admtReportAccountReferences     = 3
33.    Const admtReportNameConflicts        = 4
34.    ' Option constants
35.    Const admtNone             = 0
36.    Const admtData             = 1
37.    Const admtFile             = 2
38.    Const admtDomain           = 3
39.    Const admtRecurse               = &H0100
40.    Const admtFlattenHierarchy      = &H0000
41.    Const admtMaintainHierarchy     = &H0200
42.    ' Event related constants
43.    ' Progress type
44.    Const admtProgressObjectMigration      = 0
45.    Const admtProgressntDispatch         = 1
46.    Const admtProgressntOperation    = 2
47.    Const admtProgressMailboxMigration  = 3
48.    ' Event type
49.    Const admtEventNone                             = 0
50.    Const admtEventObjectInputPreprocessed          = 1
51.    Const admtEventTaskStart                        = 2
52.    Const admtEventTaskFinish                       = 3
53.    Const admtEventObjectProcessed                  = 4
54.    Const admtEventGroupMembershipProcessed         = 5
55.    Const admtEventntStatusUpdate              =6
56.    Const admtEventntNotStarted         = 7
57.    Const admtEventntFailedToStart         = 8
58.    Const admtEventntWaitingForReboot     = 9
59.    Const admtEventntRunning         = 10
60.    Const admtEventntCancelled         = 11
61.    Const admtEventntPassed         = 12
62.    Const admtEventntFailed         = 13
63.    Const admtEventntWaitingForRetry     = 14
64.    Const admtEventntSuccessful         = 15
65.    Const admtEventntCompletedWithWarnings     = 16
66.    Const admtEventntCompletedWithErrors     = 17
67.    Const admtEventTaskLogSaved         = 18
68.    Const admtntPreCheckPhase         = &H100
69.    Const admtntntOperationPhase     = &H200
70.    Const admtntPostCheckPhase         = &H300
71.    Const admtntStatusMask         = &HFF
72.    Const admtntPhaseMask         = &H300
73.    ' Status type
74.    Const admtStatusSuccess       = 0
75.    Const admtStatusWarnings     = 1
76.    Const admtStatusErrors        = 2
77.    'Extra Const made by Martijn Bellaard PQR
78.    Const strLogFile     = "C:\Scripts\Reports\Miglog.csv"
79.    Const strErrorLogFile     = "C:\Scripts\Reports\MigErrorlog.csv"
80.    Const Forwriting     = true
81.    '----------------------------------------------------------------------------
82.    ' Declarations
83.    '----------------------------------------------------------------------------
84.    Dim objMigration
85.    Dim objUserMigration
86.    Dim objGroupMigration
87.    Dim objComputerMigration
88.    Dim objSecurityTranslation
89.    Dim objServiceAccountEnumeration
90.    Dim objPasswordMigration
91.    Dim objFSO
92.    Dim objLogfile
93.    Dim objErrorLogFile
94.    Dim lngStatusType
95.    lngStatusType = 0
96.    '----------------------------------------------------------------------------
97.    ' Create Logfile
98.    ' Add by Martijn Bellaard PQR
99.    '----------------------------------------------------------------------------
100.    'create instance of file system object
101.    Set objFSO = CreateObject("Scripting.FileSystemObject")
102.    'Create Log file
103.    Set objLogFile = objFSO.CreateTextFile(strLogFile, Forwriting)
104.    Set objErrorLogFile = objFSO.CreateTextFile(strErrorLogFile, Forwriting)
105.    'Set time and date in logfile and screen
106.    Objlogfile.write "========================================="
107.    objLogfile.writeline
108.    Objlogfile.write "Start date:" & Date & "Start Time:"& Time
109.    objLogfile.writeline
110.    Objlogfile.write "OLD  to NEW log "
111.    objLogfile.writeline
112.    Objlogfile.write "========================================="
113.    objLogfile.writeline
114.    Objlogfile.write "Progress,Started,Finished,Failed,"
115.    objLogfile.writeline
116.    ObjErrorlogfile.write "========================================="
117.    objErrorLogfile.writeline
118.    ObjErrorlogfile.write "Start date:" & Date & "Start Time:"& Time
119.    objErrorLogfile.writeline
120.    ObjErrorlogfile.write "OLD to NEW log "
121.    objErrorLogfile.writeline
122.    ObjErrorlogfile.write "========================================="
123.    objErrorLogfile.writeline
124.    ObjErrorlogfile.write "Object, Statusnummer,"
125.    objErrorLogfile.writeline
126.    wscript.echo "========================================="
127.    wscript.echo "Start date:" & Date & "Start Time:"& Time
128.    wscript.echo "OLD to NEWlog" & strLogfile
129.    wscript.echo "========================================="
130.    '----------------------------------------------------------------------------
131.    ' ADMT Migration Class
132.    '----------------------------------------------------------------------------
133.    ' create instance of migration object
134.    Set objMigration = wscript.CreateObject("ADMT.Migration", "Task_")
135.    ' set options
136.    objMigration.IntraForest = False
137.    objMigration.SourceDomain = "old1.local"
138.    objMigration.SourceDomainController = "SourceDC.old1.local"
139.    objMigration.SourceOU = "Medewerkers"
140.    objMigration.TargetDomain = "nieuwe.local"
141.    objMigration.TargetDomainController = "TargetDC.nieuwe.local"
142.    objMigration.TargetOU = "Import "
143.    objMigration.PasswordOption = AdmtCopyPassword
144.    objMigration.PasswordServer = "SourceDC.old1.local"
145.    objMigration.ConflictOptions = admtMergeConflicting + admtRemoveExistingUserRights + admtRemoveExistingMembers
146.    objMigration.AdmtEventLevel = admtStatusErrors
147.    '----------------------------------------------------------------------------
148.    ' UserMigration Class
149.    '----------------------------------------------------------------------------
150.    ' create instance of user migration object
151.    Set objUserMigration = objMigration.CreateUserMigration
152.    'set options
153.    objUserMigration.DisableOption = admtDisableTarget
154.    objUserMigration.SourceExpiration = admtNoExpiration
155.    objUserMigration.MigrateSIDs = False
156.    objUserMigration.TranslateRoamingProfile = False
157.    objUserMigration.UpdateUserRights = False
158.    objUserMigration.MigrateGroups = False
159.    objUserMigration.UpdatePreviouslyMigratedObjects = False
160.    objUserMigration.FixGroupMembership = False
161.    objUserMigration.MigrateServiceAccounts = False
162.    ' migrate user accounts
163.    objUserMigration.Migrate admtDomain + admtRecurse + admtMaintainHierarchy
164.    '----------------------------------------------------------------------------
165.    ' ReportGeneration Class
166.    '----------------------------------------------------------------------------
167.    ' create instance of report generation object
168.    DIM objReportGeneration
169.    Set objReportGeneration = objMigration.CreateReportGeneration
170.    ' set options
171.    objReportGeneration.AutoPreCheckRetry = True
172.    objReportGeneration.AutoPreCheckRetryInterval = 30
173.    objReportGeneration.AutoPreCheckRetryNumber = 48
174.    ' generate report
175.    objReportGeneration.Type = admtReportMigratedAccounts
176.    objReportGeneration.Folder = "C:\scripts\Reports\"
177.    objReportGeneration.Generate admtNone
178.    '----------------------------------------------------------------------------
179.    ' PasswordMigration Class
180.    ' - Note: The source domain and OU will be used if not explicitly specified
181.    '----------------------------------------------------------------------------
182.    ' create instance of password migration object
183.    Set objPasswordMigration = objMigration.CreatePasswordMigration
184.    'Last line
185.    'Set time and date in logfile and screen
186.    Objlogfile.write "========================================="
187.    objLogfile.writeline
188.    Objlogfile.write "End date:" & Date & "End Time:"& Time
189.    objLogfile.writeline
190.    Objlogfile.write "End logfile "
191.    objLogfile.writeline
192.    Objlogfile.write "========================================="
193.    objLogfile.writeline
194.    ObjErrorlogfile.write "========================================="
195.    objErrorLogfile.writeline
196.    ObjErrorlogfile.write "End date:" & Date & "End Time:"& Time
197.    objErrorLogfile.writeline
198.    ObjErrorlogfile.write "End logfile "
199.    objErrorLogfile.writeline
200.    ObjErrorlogfile.write "========================================="
201.    objErrorLogfile.writeline
202.    wscript.echo "========================================="
203.    wscript.echo "End date:" & Date & "End Time:"& Time
204.    wscript.echo "Finish OLD to OLD"
205.    wscript.echo "========================================="
206.    Objlogfile.close
207.    objerrorLogFile.close
208.    ' -----------------------------------------------------------------------------
209.    ' Progress event handler
210.    '   lngProgressType: progress type (admtProgress*)
211.    '   lngStarted:      the number of started operations
212.    '   lngFinished:     the number of finished operations
213.    '   lngFailed:       the number of failed operations
214.    ' -----------------------------------------------------------------------------
215.    Sub Task_Progress(lngProgressType, lngStarted, lngFinished, lngFailed)
a.    wscript.echo  "Progress: " & lngProgressType & " Started: " & lngStarted & " Finished: " & lngFinished & " Failed:" & lngFailed
b.    Objlogfile.write lngProgressType & "," & lngStarted & "," & lngFinished & "," & lngFailed & ","
c.    objLogfile.writeline
216.    End Sub
217.    ' -----------------------------------------------------------------------------
218.    ' Status event handler
219.    '   lngEventType:    event type (admtEvent*)
220.    '   strObjName:      the name of the object
221.    '   lngStatusType:   status (admtStatus*)
222.    '   objMesss:     an array of messs
223.    ' -----------------------------------------------------------------------------
224.    Sub Task_Status(lngEventType, strObjName, lngStatusType, objMesss)
225.    Dim strMess
a.    wscript.echo "Object: " & strObjName  & " Status nummer: " & lngstatusType
b.    if lngStatusType > 0 then
i.    ObjErrorlogfile.write strObjName  & "," & lngstatusType & ","
ii.    objErrorLogfile.writeline
c.    end if
226.    End Sub
227.    '   Einde Script
228.    ' ----------------------------------------------------------------------------

Als je nog vragen hebt hoor ik ze graag.
Martijn Bellaard

Commentaar:

Arian van der Pijl zei:

Bedankt!

Altijd mooi zoiets goed uitgeschreven te vinden.

# March 13, 2009 9:00 AM
Wat denkt u?

(Verplicht) 

(Verplicht) 

(Optioneel)

(Verplicht) 
CaptchaCube Vraag:


Antwoord: