mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2025-01-09 15:49:53 +00:00
Added Install-ADDSForest to RFM.
This commit is contained in:
parent
09c7928c45
commit
b566a075fc
@ -6,8 +6,9 @@ Restores the {DCName} domain controller from ntds.dit.
|
||||
This script should only be executed on a freshly installed {OSName}. Use at your own risk
|
||||
The DSInternals PowerShell module must be installed for all users on the target server.
|
||||
|
||||
.AUTHOR
|
||||
Michael Grafnetter
|
||||
|
||||
Author: Michael Grafnetter
|
||||
|
||||
#>
|
||||
#Requires -Version 3 -Modules DSInternals -RunAsAdministrator
|
||||
|
||||
@ -17,80 +18,97 @@ $vssResult = ([wmiclass] 'Win32_ShadowCopy').Create("$env:SystemDrive\", 'Client
|
||||
|
||||
# All the other operations will be executed by a restartable workflow running in SYSTEM context.
|
||||
$initTask = Register-ScheduledJob -Name DSInternals-RFM-Initializer -ScriptBlock {
|
||||
workflow Restore-DomainController
|
||||
{
|
||||
if ($env:COMPUTERNAME -ne '{DCName}')
|
||||
{
|
||||
# A server rename operation is required.
|
||||
Rename-Computer -NewName '{DCName}' -Force
|
||||
|
||||
# We explicitly suspend the workflow as Restart-Computer with the -Wait parameter does not survive local reboots.
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
}
|
||||
workflow Restore-DomainController
|
||||
{
|
||||
if ($env:COMPUTERNAME -ne '{DCName}')
|
||||
{
|
||||
# A server rename operation is required.
|
||||
Rename-Computer -NewName '{DCName}' -Force
|
||||
|
||||
# We explicitly suspend the workflow as Restart-Computer with the -Wait parameter does not survive local reboots.
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
}
|
||||
|
||||
if ((Get-Service NTDS -ErrorAction SilentlyContinue) -eq $null)
|
||||
{
|
||||
# A DC promotion is required.
|
||||
# Note: In order to mainstain compatibility with Windows Server 2008 R2, the ADDSDeployment module is not used.
|
||||
# Advice: It is recommenced to change the DSRM password after DC promotion.
|
||||
dcpromo.exe /unattend /ReplicaOrNewDomain:Domain /NewDomain:Forest /NewDomainDNSName:"{DomainName}" /DomainNetBiosName:"{NetBIOSDomainName}" /DomainLevel:{DomainMode} /ForestLevel:{ForestMode} '/SafeModeAdminPassword:"{DSRMPassword}"' /DatabasePath:"{TargetDBDirPath}" /LogPath:"{TargetLogDirPath}" /SysVolPath:"{TargetSysvolPath}" /AllowDomainReinstall:Yes /CreateDNSDelegation:No /DNSOnNetwork:No /InstallDNS:Yes /RebootOnCompletion:No
|
||||
Set-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager\Roles\10 -Name ConfigurationStatus -Value 2 -Force
|
||||
}
|
||||
|
||||
# Reboot the computer into the Directory Services Restore Mode.
|
||||
bcdedit.exe /set safeboot dsrepair
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
if ((Get-Service NTDS -ErrorAction SilentlyContinue) -eq $null)
|
||||
{
|
||||
# A DC promotion is required.
|
||||
# Note: In order to mainstain compatibility with Windows Server 2008 R2, the ADDSDeployment module is not used.
|
||||
# Advice: It is recommenced to change the DSRM password after DC promotion.
|
||||
dcpromo.exe /unattend /ReplicaOrNewDomain:Domain /NewDomain:Forest /NewDomainDNSName:"{DomainName}" /DomainNetBiosName:"{NetBIOSDomainName}" /DomainLevel:{DomainMode} /ForestLevel:{ForestMode} '/SafeModeAdminPassword:"{DSRMPassword}"' /DatabasePath:"{TargetDBDirPath}" /LogPath:"{TargetLogDirPath}" /SysVolPath:"{TargetSysvolPath}" /AllowDomainReinstall:Yes /CreateDNSDelegation:No /DNSOnNetwork:No /InstallDNS:Yes /RebootOnCompletion:No
|
||||
Set-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager\Roles\10 -Name ConfigurationStatus -Value 2 -Force
|
||||
|
||||
# Re-encrypt the DB with the new boot key.
|
||||
$currentBootKey = Get-BootKey -Online
|
||||
Set-ADDBBootKey -DBPath '{SourceDBPath}' -LogPath '{SourceLogDirPath}' -OldBootKey {OldBootKey} -NewBootKey $currentBootKey
|
||||
<# Alternative approach for Winows Server 2012+
|
||||
Install-WindowsFeature -Name AD-Domain-Services
|
||||
Install-ADDSForest -DomainName '{DomainName}' `
|
||||
-DomainNetbiosName '{NetBIOSDomainName}' `
|
||||
-ForestMode {ForestModeString} `
|
||||
-DomainMode {DomainModeString} `
|
||||
-DatabasePath "{TargetDBDirPath}" `
|
||||
-LogPath "{TargetLogDirPath}" `
|
||||
-SysvolPath "{TargetSysvolPath}" `
|
||||
-InstallDns `
|
||||
-CreateDnsDelegation:$false `
|
||||
-NoDnsOnNetwork `
|
||||
-SafeModeAdministratorPassword (ConvertTo-SecureString -String '{DSRMPassword}' -AsPlainText -Force)`
|
||||
-NoRebootOnCompletion `
|
||||
-Force
|
||||
#>
|
||||
}
|
||||
|
||||
# Clone the DC account password.
|
||||
$ntdsParams = Get-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
|
||||
InlineScript {
|
||||
# Note: SupplementalCredentials do not get serialized properly without using the InlineScript activity.
|
||||
$dcAccount = Get-ADDBAccount -SamAccountName '{DCName}$' -DBPath $using:ntdsParams.'DSA Database file' -LogPath $using:ntdsParams.'Database log files path' -BootKey $using:currentBootKey
|
||||
Set-ADDBAccountPasswordHash -ObjectGuid {DCGuid} -NTHash $dcAccount.NTHash -SupplementalCredentials $dcAccount.SupplementalCredentials -DBPath '{SourceDBPath}' -LogPath '{SourceLogDirPath}' -BootKey $using:currentBootKey
|
||||
}
|
||||
# Reboot the computer into the Directory Services Restore Mode.
|
||||
bcdedit.exe /set safeboot dsrepair
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
|
||||
# Replace the database and transaction logs.
|
||||
robocopy.exe '{SourceDBDirPath}' $ntdsParams.'DSA Working Directory' *.dit *.edb *.chk *.jfm /MIR /NP /NDL /NJS
|
||||
robocopy.exe '{SourceLogDirPath}' $ntdsParams.'Database log files path' *.log *.jrs /MIR /NP /NDL /NJS
|
||||
# Re-encrypt the DB with the new boot key.
|
||||
$currentBootKey = Get-BootKey -Online
|
||||
Set-ADDBBootKey -DBPath '{SourceDBPath}' -LogPath '{SourceLogDirPath}' -OldBootKey {OldBootKey} -NewBootKey $currentBootKey
|
||||
|
||||
# Replace SYSVOL.
|
||||
$netlogonParams = Get-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -Name SysVol
|
||||
robocopy.exe '{SourceSysvolPath}' (Join-Path -Path $netlogonParams.SysVol -ChildPath '{DomainName}') /MIR /XD DfsrPrivate /XJ /COPYALL /DCOPY:DAT /SECFIX /TIMFIX /NP /NDL
|
||||
# Clone the DC account password.
|
||||
$ntdsParams = Get-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
|
||||
InlineScript {
|
||||
# Note: SupplementalCredentials do not get serialized properly without using the InlineScript activity.
|
||||
$dcAccount = Get-ADDBAccount -SamAccountName '{DCName}$' -DBPath $using:ntdsParams.'DSA Database file' -LogPath $using:ntdsParams.'Database log files path' -BootKey $using:currentBootKey
|
||||
Set-ADDBAccountPasswordHash -ObjectGuid {DCGuid} -NTHash $dcAccount.NTHash -SupplementalCredentials $dcAccount.SupplementalCredentials -DBPath '{SourceDBPath}' -LogPath '{SourceLogDirPath}' -BootKey $using:currentBootKey
|
||||
}
|
||||
|
||||
# Reconfigure LSA policies. We would get into a BSOD loop if they do not match the corresponding values in the database.
|
||||
Set-LsaPolicyInformation -DomainName '{NetBIOSDomainName}' -DnsDomainName '{DomainName}' -DnsForestName '{ForestName}' -DomainGuid {DomainGuid} -DomainSid {DomainSid}
|
||||
# Replace the database and transaction logs.
|
||||
robocopy.exe '{SourceDBDirPath}' $ntdsParams.'DSA Working Directory' *.dit *.edb *.chk *.jfm /MIR /NP /NDL /NJS
|
||||
robocopy.exe '{SourceLogDirPath}' $ntdsParams.'Database log files path' *.log *.jrs /MIR /NP /NDL /NJS
|
||||
|
||||
# Tell the DC that its DB has intentionally been restored. A new InvocationID will be generated as soon as the service starts.
|
||||
Set-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters -Name 'Database restored from backup' -Value 1 -Force
|
||||
Remove-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters -Name 'DSA Database Epoch' -Force
|
||||
# Replace SYSVOL.
|
||||
$netlogonParams = Get-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -Name SysVol
|
||||
robocopy.exe '{SourceSysvolPath}' (Join-Path -Path $netlogonParams.SysVol -ChildPath '{DomainName}') /MIR /XD DfsrPrivate /XJ /COPYALL /DCOPY:DAT /SECFIX /TIMFIX /NP /NDL
|
||||
|
||||
# Disable DSRM and do one last reboot.
|
||||
bcdedit.exe /deletevalue safeboot
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
}
|
||||
# Reconfigure LSA policies. We would get into a BSOD loop if they do not match the corresponding values in the database.
|
||||
Set-LsaPolicyInformation -DomainName '{NetBIOSDomainName}' -DnsDomainName '{DomainName}' -DnsForestName '{ForestName}' -DomainGuid {DomainGuid} -DomainSid {DomainSid}
|
||||
|
||||
# Delete any pre-existing workflows with the same name before starting a new one.
|
||||
Remove-Job -Name DSInternals-RFM-Workflow -Force -ErrorAction SilentlyContinue
|
||||
# Tell the DC that its DB has intentionally been restored. A new InvocationID will be generated as soon as the service starts.
|
||||
Set-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters -Name 'Database restored from backup' -Value 1 -Force
|
||||
Remove-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters -Name 'DSA Database Epoch' -Force
|
||||
|
||||
# Start the workflow.
|
||||
Restore-DomainController -JobName DSInternals-RFM-Workflow
|
||||
# Disable DSRM and do one last reboot.
|
||||
bcdedit.exe /deletevalue safeboot
|
||||
shutdown.exe /r /t 5
|
||||
Suspend-Workflow -Label 'Waiting for reboot'
|
||||
}
|
||||
|
||||
# Delete any pre-existing workflows with the same name before starting a new one.
|
||||
Remove-Job -Name DSInternals-RFM-Workflow -Force -ErrorAction SilentlyContinue
|
||||
|
||||
# Start the workflow.
|
||||
Restore-DomainController -JobName DSInternals-RFM-Workflow
|
||||
}
|
||||
|
||||
$resumeTask = Register-ScheduledJob -Name DSInternals-RFM-Resumer -Trigger (New-JobTrigger -AtStartup) -ScriptBlock {
|
||||
# Resume the workflow after the computer is rebooted.
|
||||
Resume-Job -Name DSInternals-RFM-Workflow -Wait | Wait-Job | where State -In Completed,Failed,Stopped | foreach {
|
||||
# Perform cleanup when finished.
|
||||
Remove-Job -Job $PSItem -Force
|
||||
Unregister-ScheduledJob -Name DSInternals-RFM-Initializer -Force
|
||||
Unregister-ScheduledJob -Name DSInternals-RFM-Resumer -Force
|
||||
}
|
||||
# Resume the workflow after the computer is rebooted.
|
||||
Resume-Job -Name DSInternals-RFM-Workflow -Wait | Wait-Job | where State -In Completed,Failed,Stopped | foreach {
|
||||
# Perform cleanup when finished.
|
||||
Remove-Job -Job $PSItem -Force
|
||||
Unregister-ScheduledJob -Name DSInternals-RFM-Initializer -Force
|
||||
Unregister-ScheduledJob -Name DSInternals-RFM-Resumer -Force
|
||||
}
|
||||
}
|
||||
|
||||
# Configure the scheduled tasks to run under the SYSTEM account.
|
||||
|
@ -94,6 +94,8 @@
|
||||
Replace("{DomainSid}", dc.DomainSid.ToString()).
|
||||
Replace("{DomainMode}", ((int)dc.DomainMode).ToString()).
|
||||
Replace("{ForestMode}", ((int)dc.ForestMode).ToString()).
|
||||
Replace("{DomainModeString}", (dc.DomainMode).ToString()).
|
||||
Replace("{ForestModeString}", (dc.ForestMode).ToString()).
|
||||
Replace("{OSName}", dc.OSName).
|
||||
Replace("{OldBootKey}", this.BootKey.ToHex()).
|
||||
Replace("{SourceDBPath}", this.DirectoryContext.DSADatabaseFile).
|
||||
@ -126,4 +128,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user