Hello folks,
Recently i have defined with colleagues a specifications document for deploy new domain controllers in existing forest.
For this deploy, first constraint is fixed replication ports between domain controllers, please see KB Microsoft .
Second constraint is to check the minimal hardware system configuration.
Third constraint is verify if flux networks are open between the new DC and the replicate source DC.
The fourth constraint is to validate the installation of new DC is good.
And the last constraint is set the replication port of DFSR.
Because the delay of deployement is short, i have write this script to deploy automaticly and check all prerequisites.
The script wrote steps informations in registry key. You need to launch several times the script to install domain controler. I do these steps for look the result of differents steps.
You can use this script to create yours, to simplify the deployement of a lot domain controlers in an international infrastructure.
Please enjoy 😉
#Function TCPPort Test
function Test-Port($hostname, $port){
# This works no matter in which form we get $host - hostname or ip address
try {
$ip = [System.Net.Dns]::GetHostAddresses($hostname) |
select-object IPAddressToString -expandproperty IPAddressToString
if($ip.GetType().Name -eq "Object[]")
{
#If we have several ip's for that address, let's take first one
$ip = $ip[0]
}
} catch {
Write-Host "Possibly $hostname is wrong hostname or IP"
return
}
$t = New-Object Net.Sockets.TcpClient
# We use TryCatch to remove exception info from console if we can't connect
try
{
$t.Connect($ip,$port)
} catch {}
if($t.Connected)
{
$t.Close()
$msg = "Port $port is operational"
return $true
}
else
{
$msg = "Port $port on $ip is closed, "
$msg += "You may need to contact your IT team to open it. "
}
#Write-Host $msg
return $false
}
$ports =
#('137','NetBios Session'),
#('138','NetBios'),
('139','NetBios NetLogon and Browsing'),
('389','LDAP'),
('636','LDAPS'),
('3268','LDAP GC'),
('3269','LDAPS GC'),
('53','DNS'),
('88','KERBEROS'),
('445','SMB'),
#('123','W32Time'),
('135','RPC EndPoint'),
('464','KERBEROS Password Change')
#Main script
Import-Module ServerManager
clear
$OS = ""
$Type = ""
$memory = ""
$cpu = ""
$nbrdisk = ""
$DisqueC = ""
$DisqueD = ""
$DisqueE = ""
$ipAddress = @((Get-NetIPAddress | where {$_.AddressFamily -eq "IPv4" -and $_.InterfaceAlias -notlike "Loopback*"}).IPAddress)
if ((Get-Host).Version.Major -lt "2") {
Write-Host "Sorry, install Powershell V2 minimum, exit ..." -ForegroundColor Yellow
return
}
Else {
$computername=$env:COMPUTERNAME
#Ckeck installation status
#Define the variable to hold the location of Currently Installed Programs
$Path="HKLM:SOFTWAREMicrosoft"
$key = "DCInstall"
$fullpathkey = $Path+''+$key
Set-Location $Path
if (-not (Test-Path .$Key)) {
New-Item -Name $Key -Force
Set-ItemProperty -Path .$key -Name Status -Value 1 -Type DWord -Force
Set-Location c:
}
Set-Location c:
$keyValue = (Get-ItemProperty -Path $fullpathkey -Name Status).Status}
If ($keyValue -eq 5) {Write-Warning "Server is a Domain Controler, please don't run this script"
Start-Sleep 7
return
}
Else {
if ($keyValue -eq 1) {
#Add FireWall Rules
Clear
Write-Host "ADD Rules FireWall" -ForegroundColor Yellow
Invoke-Expression "netsh advfirewall firewall add rule name='AD 2012 [TCP]' dir=in action=allow protocol=TCP localport=6504-6506" -Verbose
Invoke-Expression "netsh advfirewall firewall add rule name='AD 2012 [UDP]' dir=in action=allow protocol=UDP localport=6504-6506"
Invoke-Expression "netsh advfirewall firewall add rule name='DNS Socket [UDP]' dir=in action=allow protocol=UDP localport=6599-6699"
Invoke-Expression "netsh advfirewall firewall add rule name='DFSR [UDP]' dir=in action=allow protocol=UDP localport=49155"
Invoke-Expression "netsh advfirewall firewall add rule name='DFSR [TCP]' dir=in action=allow protocol=TCP localport=49155"
Clear
$intdom = (Get-WmiObject Win32_Computersystem).Domain
$OS = if ((gwmi -Class Win32_OperatingSystem -ComputerName $env:COMPUTERNAME -Property Version).version -eq "6.3.9600") {"Microsoft Windows Server 2012R2"} else {"Wrong OS"}
$Type = (gwmi -class win32_Bios).Manufactured
$memory = [math]::round((gwmi -class Win32_ComputerSystem).TotalPhysicalMemory/1024/1024/1024, 0)
$cpu = (gwmi -class Win32_PerfFormattedData_PerfOS_Processor).count -1
$nbrdisk = (gwmi Win32_DiskDrive).count
$DisqueC = (Get-Wmiobject win32_logicaldisk -ComputerName $env:COMPUTERNAME | where {$_.drivetype -eq 3 -and $_.DeviceID -eq "C:"}).size
$DisqueC = [math]::round($DisqueC/1gB, 0)
$DisqueD = (Get-Wmiobject win32_logicaldisk -ComputerName $env:COMPUTERNAME | where {$_.drivetype -eq 3 -and $_.DeviceID -eq "D:"}).size
$DisqueD = [math]::round($DisqueD/1gB, 0)
$DisqueE = (Get-Wmiobject win32_logicaldisk -ComputerName $env:COMPUTERNAME | where {$_.drivetype -eq 3 -and $_.DeviceID -eq "E:"}).size
$DisqueE = [math]::round($DisqueE/1gB, 0)
$model = (Get-WmiObject -Class Win32_computersystem -ComputerName $env:COMPUTERNAME -Property Model -ErrorAction SilentlyContinue).model
$Serial= (gwmi -Class Win32_SystemEnclosure -Property SerialNumber -ComputerName $env:COMPUTERNAME -ErrorAction SilentlyContinue).SerialNumber
clear
Write-Host "System Check" -ForegroundColor Yellow
Write-Host ""
Write-Host "Domain AD-DS :" $intdom -ForegroundColor Yellow
Write-Host ""
Write-Host "Name Server :" $computername -ForegroundColor Yellow
Write-Host ""
Write-Host "Operating System :" $OS -ForegroundColor Yellow
Write-Host ""
Write-Host "Memory :" $memory "GB" -ForegroundColor Yellow
Write-Host ""
Write-Host "CPU numbers cores :" $cpu -ForegroundColor Yellow
Write-Host ""
Write-Host "Number of disks :" $nbrdisk -ForegroundColor Yellow
Write-Host "Disk size C: :" $DisqueC "GB" -ForegroundColor Yellow
if ($DisqueD -eq 0) {Write-Warning "Pas de disque D:"}
Else {Write-Host "Disk size D: :" $DisqueD "GB" -ForegroundColor Yellow}
if ($DisqueE -ne 0) {Write-Host "Disk size E: :" $DisqueE "GB" -ForegroundColor Yellow}
Write-Host ""
Write-Host "IP Address :" $ipAddress -ForegroundColor Yellow
Write-Host ""
Write-Host "Model :" $model -ForegroundColor Yellow
Write-Host ""
Write-Host "Serial Number :" $Serial -ForegroundColor Yellow
Write-Host ""
Write-host "The information above are correct? Y(Yes) N(No)" -ForegroundColor Yellow
$choice = Read-Host
If ($choice -eq "N") {
Clear
Write-Warning "Please update the machine with the requirements defined in the document of detailed specifications"
Start-Sleep 5
return
}
else {Set-ItemProperty -Path $fullpathkey -Name Status -Value 2 -Type DWord -Force
Write-Warning "To Install components AD-DS and DNS Server, please run the script again"
Start-Sleep 5
return}
}#Fin 1
Elseif ( $keyValue -eq 2) {
Write-Host "Add Windows roles and features on" $env:COMPUTERNAME", please wait" -ForegroundColor Yellow
$ADDSInstall = (Get-WindowsFeature AD-Domain-Services).Installed
$DNSInstall = (Get-WindowsFeature DNS).Installed
if (!$ADDSInstall -and !$DNSInstall) {
$InstallRole = Add-WindowsFeature -Name AD-Domain-Services,RSAT-ADDS,RSAT-ADDS-Tools,DNS,RSAT-DNS-Server -Source D:Sourcessources -Restart:$true
if (!$InstallRole.Success) {
Write-Warning "Unable to install AD-DS installation package due of the following error:"
Write-Warning $InstallRole.ExitCode
return
}
Else {
Set-ItemProperty -Path $fullpathkey -Name Status -Value 3 -Type DWord -Force
Write-Warning "Components AD-DS and DNS Server are installed, please run the script again"
Start-Sleep 5
}
}
Else {
Set-ItemProperty -Path $fullpathkey -Name Status -Value 3 -Type DWord -Force
Write-Warning "Components AD-DS and DNS Server are installed, please run the script again"
Start-Sleep 5
}
}#Fin 2
Elseif ($keyValue -eq 3) {
$DCinSiteArray = ""
$DCinSite=""
Import-Module ActiveDirectory
$F = Get-WmiObject Win32_Computersystem
$siteAD = Get-ADReplicationSite -Server $F.Domain
$DCinSiteArray = Get-ADDomainController -Server $F.Domain -filter {Site -eq $siteAD.Name}
$DCinsiteCount = $DCinSiteArray | Measure-Object
if ($DCinsiteCount.Count -eq 1) {$DCinSite = $DCinSiteArray.HostName}
Else {
foreach ($DC in $DCinSiteArray) {
[array]$DCinSite += $DC.HostName
} # Fin Foreach
}
$DCinSite = $DCinSite | Sort | Select-Object -First 5
#Clear
Write-Host "Site Name :" $siteAD.Name -ForegroundColor Yellow
Write-Host ""
Write-Host "Dc in same Site :" $DCinSite -ForegroundColor Yellow
Set-Location c:
Write-Host ""
Write-Host "Settings before promote DC" -ForegroundColor Yellow
Write-Host ""
$Dcreplica = read-Host "please indicate the FQDN name of replicate domain controller "
Write-Host $Dcreplica -ForegroundColor Yellow
If ($Dcreplica -eq " ") {
Write-Host "Error Name empty" -ForegroundColor Red
Start-Sleep 5
return}#Fin IF
Else {
if (! (Test-Connection $Dcreplica -Count 2 -Quiet)) { Write-Host "ICMP Error on $Dcreplica"}
Else {
Clear
Write-Host "Test ICMP OK" -ForegroundColor Green
Write-Host ""
Write-Host "Start check open ports Active Directory"
foreach ($port in $ports) {
if (! (Test-Port $Dcreplica $port[0])) {
Write-Warning "Unable to check connection on port : $port on $Dcreplica"
}
Else {Write-host "Port " $port[0] $port[1] "OK" -ForegroundColor Green}
}#Fin Foreach
}#Fin Else
} #Fin Else
Write-Host ""
Write-host "The information above are correct? Y(Yes) N(No)"
$choice = Read-Host
If ($choice -eq "N") {
Write-Warning "Please check the openings of flow (Firewall Server and firewall network) with the requirements defined in the document of detailed specifications"
Start-Sleep 5
return
}
Else {
$intdom = (Get-WmiObject Win32_Computersystem).Domain
$intdomntb = $intdom.ToUpper().Split(".")[0]
Write-Host "Promote DC" -ForegroundColor Yellow
New-Item -Path D:AD -ItemType Directory -Value AD -Force -Confirm:$false
Import-Module ADDSDeployment
$RootAD = $((Get-ADForest).RootDomain)
If ($intdom -eq $RootAD) {
$promote = Install-ADDSDomainController `
-NoGlobalCatalog:$false `
-Credential (Get-Credential -Message "$RootAD Domain Admin Account") `
-CriticalReplicationOnly:$false `
-DatabasePath "D:ADNTDS" `
-DomainName $intdom `
-InstallDns:$true `
-LogPath "D:ADNTDS" `
-NoRebootOnCompletion:$false `
-ReplicationSourceDC $Dcreplica `
-SiteName $siteAD.Name `
-SysvolPath "D:ADSYSVOL" `
-Force:$true
#-CreateDnsDelegation:$true `
#-DnsDelegationCredential (Get-Credential -Message "Account with privileges or Domain Admin") `
}
Else {
$promote = Install-ADDSDomainController `
-NoGlobalCatalog:$false `
-CreateDnsDelegation:$true `
-Credential (Get-Credential -Message "$intdomntb Domain Admin Account" -UserName $intdomntb"") `
-CriticalReplicationOnly:$false `
-DatabasePath "D:ADNTDS" `
-DnsDelegationCredential (Get-Credential -Message "GRS Enterprise Admin for DNS Delegation" -UserName "GRS") `
-DomainName $intdom `
-InstallDns:$true `
-LogPath "D:ADNTDS" `
-NoRebootOnCompletion:$false `
-ReplicationSourceDC $Dcreplica `
-SiteName $siteAD.Name `
-SysvolPath "D:ADSYSVOL" `
-Force:$true
}
if ($promote.Status -eq "Error") {
Write-Warning "Unable to promote DC due of the following error:"
Write-Warning $promote.Message
Start-Sleep 7
return
}
Else {
Set-ItemProperty -Path $fullpathkey -Name Status -Value 4 -Type DWord -Force
Write-Warning "Promote OK, Check after reboot the DC health"
Write-Warning "launch script another time to set different configuration"
Start-Sleep 7
return
}
}#Fin Else Promote DC
}#Fin 3
#DEbut 4 Validation share and IS global ++ installation et configuration DFSR
Elseif ($keyValue -eq 4) {
Clear
Write-Host "Validation IS Global Catalog and Share SYSVOL & NETLOGON" -ForegroundColor Yellow
while ($true) {
if (Get-EventLog -LogName 'Directory Service' -Newest 10 | Where-Object {$_.EventID -eq 1119} -ErrorAction SilentlyContinue) {
Write-Host "The Server Is Global Catalog" -ForegroundColor Green
break
} else {
Write-Warning "Wait IS GLOBAL CATALOG"
Start-Sleep 60
}
}
while ($true) {
if (Get-SmbShare -Name "SYSVOL" -ErrorAction SilentlyContinue) {
Write-Host "The Server share SYSVOL" -ForegroundColor Green
break
} else {
Write-Warning "Wait SYSVOL Share"
Start-Sleep 60
}
}
while ($true) {
if (Get-SmbShare -Name "NETLOGON" -ErrorAction SilentlyContinue) {
Write-Host "The Server share NETLOGON" -ForegroundColor Green
break
} else {
Write-Warning "Wait NETLOGON Share"
Start-Sleep 60
}
}
Clear
Write-Host "Add Tools DFS" -ForegroundColor Yellow
#Add-WindowsFeature -Name RSAT-DFS-Mgmt-Con
$DFSToolsInstall = [Bool](Get-WindowsFeature RSAT-DFS-Mgmt-Con).Available
if ($DFSToolsInstall -eq $false) {
$InstallTools = Add-WindowsFeature -Name RSAT-DFS-Mgmt-Con
}
if ($InstallTools.Success -eq $false) {
#Write-Host "non" -ForegroundColor Red
Write-Warning "Unable to install DFSR Tools installation package due of the following error:"
Write-Warning $InstallRole.ExitCode
return
}# Fin IF
Else {
Write-Host "Execute DFSRDIAG" -ForegroundColor Yellow
#Write-Host "yes" -ForegroundColor Green
$F = Get-WmiObject Win32_Computersystem
$fqdn = $F.Name+"."+$F.Domain
$setDFSR = dfsrdiag.exe staticRPC "/port:49155" "/member:$fqdn"
if ($setDFSR -Like "*ERROR*") {
Start-Sleep 5
Write-Warning "Unable to set value 49155 to DFSR RPC port"
#Write-Warning $setDFSR.ExitCode
}
Else {
Set-ItemProperty -Path $fullpathkey -Name Status -Value 5 -Type DWord -Force
Write-Warning "Components DFSR Tools is installed, Setting value RPC OK, Server Restart"
Start-Sleep 5
Restart-Computer -Force
}
}# Fin Else
} # Fin 4
}#Fin IF