# ===================================================================================== # Windows 11 client side: DNS -> optional CA trust -> domain join -> verification. # Run in an elevated PowerShell on the Windows 11 machine. # # .\win11-join.ps1 -DnsServer 192.168.5.12 -Domain ad.example.com -CaCert C:\ca.crt # .\win11-join.ps1 -VerifyOnly # ===================================================================================== #Requires -RunAsAdministrator param( [string]$DnsServer = "192.168.5.12", [string]$Domain = "ad.example.com", [string]$DcHost = "dc1.ad.example.com", [string]$OUPath = "", # e.g. "OU=Wks,DC=ad,DC=example,DC=com" [string]$CaCert = "", # ca.crt path - local, or straight off the DC: # \\premier.local\NETLOGON\ad-root-ca.crt [switch]$VerifyOnly, [switch]$NoRestart ) $ErrorActionPreference = 'Stop' function Step($m) { Write-Host "`n==> $m" -ForegroundColor Cyan } function Warn($m) { Write-Host " ! $m" -ForegroundColor Yellow } if ($VerifyOnly) { Step "Secure channel" Test-ComputerSecureChannel -Verbose Step "DC discovery for $Domain" & nltest /dsgetdc:$Domain Step "Group policy" & gpupdate /force & gpresult /r Step "Kerberos tickets (look for cifs/$DcHost and HTTP/$DcHost)" & klist Step "Last 15 logon / netlogon errors" Get-WinEvent -FilterHashtable @{ LogName = 'System'; Level = 1,2,3; StartTime = (Get-Date).AddHours(-4) } ` -MaxEvents 15 -ErrorAction SilentlyContinue | Format-Table TimeCreated, ProviderName, Id, @{n='Msg';e={$_.Message.Substring(0, [Math]::Min(120, $_.Message.Length))}} -AutoSize return } Step "Point DNS at the domain controller ($DnsServer)" $adapters = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Sort-Object LinkSpeed -Descending $adapter = $adapters[0] Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ServerAddresses ($DnsServer, '8.8.8.8') Write-Host " adapter: $($adapter.Name) -> $($DnsServer), 8.8.8.8" ipconfig /flushdns | Out-Null Step "SRV bootstrap records" try { Resolve-DnsName -Name "_ldap._tcp.dc._msdcs.$Domain" -Type SRV -ErrorAction Stop | Select-Object Name, Strings | Format-Table -AutoSize } catch { Warn "no SRV answer for _ldap._tcp.dc._msdcs.$Domain - DNS is not pointing at the DC yet" throw } Step "Connectivity matrix" foreach ($p in 53, 88, 389, 445, 636, 3268) { $r = Test-NetConnection -ComputerName $DcHost -Port $p -WarningAction SilentlyContinue Write-Host (" {0,-5} {1}" -f $p, $(if ($r.TcpTestSucceeded) { 'open' } else { 'CLOSED' })) } if ($CaCert -and (Test-Path $CaCert)) { Step "Importing LDAPS root CA into the machine trust store" Import-Certificate -FilePath $CaCert -CertStoreLocation 'Cert:\LocalMachine\Root' | Out-Null Write-Host " imported $CaCert" } else { Warn "no -CaCert supplied: LDAPS will present an untrusted certificate" } Step "Joining $Domain as $(hostname)" $cred = Get-Credential -Message "Domain join credentials (use ${Domain.ToUpper()}\administrator)" $joinArgs = @{ DomainName = $Domain; Credential = $cred } if ($OUPath) { $joinArgs['OUPath'] = $OUPath } if ($NoRestart) { $joinArgs['NoRestart'] = $true } Add-Computer @joinArgs Write-Host "" Write-Host "Joined. Reboot now (or run: Restart-Computer -Force) and log in with a domain account." -ForegroundColor Green Write-Host "Then re-run this script with -VerifyOnly to confirm secure channel + GPO." -ForegroundColor Green