2
0
Files
PowershellScripts/Active Directory/Setup-ADForest.ps1
2024-07-05 17:04:06 +02:00

214 lines
9.3 KiB
PowerShell

<#
.SYNOPSIS
This PowerShell script configures a Windows server as a domain controller.
.DESCRIPTION
The script performs the following tasks:
1. Checks for pending system reboots and creates a log directory if it doesn't exist.
2. Validates the server's hostname and allows the user to edit it if necessary.
3. Configures a static IP address if not already set.
4. Installs required roles, including AD-Domain-Services, DNS, RSAT-AD-Tools, and gpmc.
5. Configures Active Directory Domain Services (ADDS) Forest, including creating a DNS delegation, setting up the database, and configuring the domain mode and forest mode.
.PARAMETER None
.EXAMPLE
Run this script in PowerShell to configure a Windows server as a domain controller.
.NOTES
This script requires administrative privileges to run.
Author: D.de Kooker - info@dcomputers.nl
Version: 1.0
DISCLAIMER: Use scripts at your own risk, if there is anything I can help you with I will try but I do not take responsibility for the way that anyone else uses my scripts.
Sharing is caring. Share your knowledge with the world so that everybody can learn from it.
.LINK
The latest version can Always be found on my GIT page on the link below:
https://git.dcomputers.nl/Dcomputers/PowershellScripts
#>
#region Global script settings and variables
$Version = "v1.0"
$logfilelocation = "$($MyInvocation.MyCommand.Path | Split-Path -Parent)\Logs"
$logfilename = "$(Get-Date -Format yyyyMMddHHmmss)-ADDS_Installation.log"
$summaryfilename = "$(Get-Date -Format yyyyMMddHHmmss)-ADDS_Installation_Summary.txt"
#endregion
#region functions
function Initiate-Log {
# Get current user and session information
$username = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$computerName = $env:COMPUTERNAME
$sessionID = $pid
$date = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Write log header
$logHeader = "[$date] Log initiated by $username on $computerName (Session ID: $sessionID)"
Add-Content -Path $logfilelocation\$logfilename -Value "**********************"
Add-Content -Path $logfilelocation\$logfilename -Value "LogFile initiation"
Add-Content -Path $logfilelocation\$logfilename -Value "Start time: $date"
Add-Content -Path $logfilelocation\$logfilename -Value "Username: $username"
Add-Content -Path $logfilelocation\$logfilename -Value "Machine: $computerName"
Add-Content -Path $logfilelocation\$logfilename -Value "Process ID: $sessionID"
Add-Content -Path $logfilelocation\$logfilename -Value "Script Version: $Version"
Add-Content -Path $logfilelocation\$logfilename -Value "Script Source: https://git.dcomputers.nl/Dcomputers/PowershellScripts"
Add-Content -Path $logfilelocation\$logfilename -Value "**********************"
}
function Approve-Reboot {
Write-Host "The computer needs to be restarted in order to apply the changes"
Write-Host "Please confirm that you have read this message and are ready to reboot"
$confirmReboot = Read-Host "Type 'yes' to confirm"
if ($confirmReboot -eq "yes") {
Restart-Computer -Force
} else {
Write-Host "Reboot cancelled. Please restart the server manually to apply the changes"
exit 1
}
}
function Write-Log {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Message,
[Parameter(Mandatory=$false)]
[ValidateSet("INFO", "WARNING", "ERROR")]
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logmessage = "[$timestamp] [$Level] $Message"
Add-Content -Path $logfilelocation\$logfilename -Value $logmessage
}
function Write-Summary {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Message
)
Add-Content -Path $logfilelocation\$summaryfilename -Value $Message
}
#endregion
#region prerequisites check
#Create log directory if not present
if (!(test-path $logfilelocation)) {mkdir $logfilelocation}
Initiate-Log
#Check pending system reboot
if (Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Session Manager" -Name "PendingFileRenameOperations" -ErrorAction Ignore) {
Approve-Reboot
}
#Server hostname validation
$hostname = [System.Net.Dns]::GetHostName()
Write-Host "Current hostname is: $hostname"
Write-Log -Message "Current hostname is: $hostname" -Level "INFO"
$editHostname = Read-Host "Do you want to edit the hostname? (y/n)"
if ($editHostname -eq "y") {
$newHostname = Read-Host "Enter new hostname"
Rename-Computer -NewName $newHostname -Force
Write-Host "Hostname changed to: $newHostname"
Write-Log -Message "Hostname changed to: $newHostname" -Level "INFO"
Write-Log -Message "Computer restart required after hostname change" -Level "WARNING"
[bool]$rebootneeded = $true
}
#Static IP configuration
$staticIP = Get-NetIPAddress -AddressFamily IPv4 -PrefixOrigin Manual -ErrorAction SilentlyContinue
if ($staticIP) {
Write-Host "Static IP address is configured: $($staticIP.IPAddress)"
Write-Log -Message "Static IP address is configured: $($staticIP.IPAddress)" -Level "INFO"
} else {
Write-Host "No static IP address is configured, let's configure it"
Write-Log -Message "No static IP address is configured, let's configure it" -Level "INFO"
$ipAddress = Read-Host "Enter IP address"
$subnetMask = Read-Host "Enter subnet mask eg. 24"
$gateway = Read-Host "Enter gateway"
$dns = Read-Host "Enter DNS server address"
New-NetIPAddress -IPAddress $ipAddress -PrefixLength $subnetMask -InterfaceIndex $((Get-NetAdapter).ifIndex) -DefaultGateway $gateway
Set-DnsClientServerAddress -InterfaceIndex $((Get-NetAdapter).ifIndex)
Write-Host "Static IP address configured: $ipAddress"
Write-Log -Message "Static IP address configured: $ipAddress" -Level "INFO"
}
#Reboot server if needed
if ($rebootneeded) {
Approve-Reboot
}
#endregion
#region install required roles and features
#Check the required roles
$requiredRoles = @("AD-Domain-Services", "DNS", "RSAT-AD-Tools", "gpmc")
$progress = 0
Write-Progress -Activity "Installing required roles" -Status "Starting installation" -PercentComplete $progress
foreach ($role in $requiredRoles) {
if (!(Get-WindowsFeature -Name $role).Installed) {
Write-Host "Installing required role: $role"
Write-Log -Message "Installing required role: $role" -Level "INFO"
Write-Progress -Activity "Installing required roles" -Status "Installing $role" -PercentComplete $progress
Add-WindowsFeature -Name $role -IncludeAllSubFeature -IncludeManagementTools
$progress += (100 / $requiredRoles.Count)
[bool]$rebootneeded = $true
}
}
Write-Progress -Activity "Installing required roles" -Status "Completed" -PercentComplete 100
#Reboot server if needed
if ($rebootneeded) {
Approve-Reboot
}
#All role requirements are met
Write-Host "All role requirements are met continuing Forest configuration"
Write-Log -Message "All role requirements are met continuing Forest configuration" -Level "INFO"
#endregion
#region configure ADDS
#Gather the required information
$domainName = Read-Host "Enter the domain name"
$domainNetBiosName = ($domainName.Split(".")[0] | ForEach-Object { $_.ToUpper() })
#Confirm domain name and netbios name
Write-Host "Domain name: $domainName"
Write-Log -Message "Domain name: $domainName" -Level "INFO"
Write-Host "NetBIOS name: $domainNetBiosName"
Write-Log -Message "NetBIOS name: $domainNetBiosName" -Level "INFO"
$confirmDomainInfo = Read-Host "Is this information correct? (y/n)"
if ($confirmDomainInfo -eq "y") {
#Perform the installation
Import-Module ADDSDeployment
Install-ADDSForest `
-CreateDnsDelegation:$false `
-DatabasePath "C:\Windows\NTDS" `
-DomainMode "WinThreshold" `
-DomainName $domainName `
-DomainNetbiosName $domainNetBiosName `
-ForestMode "WinThreshold" `
-InstallDns:$true `
-LogPath "C:\Windows\NTDS" `
-NoRebootOnCompletion:$true `
-SysvolPath "C:\Windows\SYSVOL" `
-Force:$true
} else {
Write-Host "Domain configuration cancelled. Please restart the script to continue."
Write-Log -Message "Domain configuration cancelled. Please restart the script to continue." -Level "WARNING"
exit 1
}
Write-Host "ADDS Forest configuration completed successfully"
Write-Log -Message "ADDS Forest configuration completed successfully" -Level "INFO"
#endregion
#region summary
Write-Summary "ADDS Forest configuration Summary:"
Write-Summary "---------------------------"
Write-Summary "Configuration date: $(Get-Date -Format "dd-MM-yyy HH:mm:ss")"
Write-Summary "Domain name: $domainName"
Write-Summary "NetBIOS name: $domainNetBiosName"
Write-Summary "---------------------------"
Approve-Reboot
#endregion