#Requires -RunAsAdministrator <# .SYNOPSIS MABDC Domain Join Script .DESCRIPTION Joins a Windows 11 Pro/Enterprise PC to the MABDC domain, installs Chocolatey, adds the MABDC package feed, and triggers auto-provisioning of all base packages. .NOTES Run as Administrator on a fresh Windows 11 Pro/Enterprise PC. Requires internet access to dc1.mabdc.org and repo.mabdc.com. #> param( [Parameter(Mandatory=$true)] [string]$Department, [Parameter(Mandatory=$false)] [string]$PCName, [Parameter(Mandatory=$false)] [string]$AdminUser = "Administrator", [Parameter(Mandatory=$false)] [string]$DomainName = "mabdc.org" ) $ErrorActionPreference = 'Stop' $LogFile = "C:\MABDC\Logs\domain-join.log" function Write-Log { param([string]$Message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $entry = "[$timestamp] $Message" Write-Host $entry -ForegroundColor Green Add-Content -Path $LogFile -Value $entry -ErrorAction SilentlyContinue } # Pre-flight checks Write-Log "=== MABDC Domain Join Script v1.0 ===" Write-Log "Starting pre-flight checks..." # Check Windows edition $edition = (Get-WindowsEdition -Online).Edition if ($edition -match "Home|Core") { Write-Host "ERROR: Windows 11 Home cannot join a domain. You need Pro or Enterprise." -ForegroundColor Red exit 1 } Write-Log "Windows Edition: $edition ✓" # Check if already domain-joined $currentDomain = (Get-WmiObject Win32_ComputerSystem).Domain if ($currentDomain -eq $DomainName) { Write-Log "PC is already joined to $DomainName. Skipping domain join." } else { Write-Log "Current domain: $currentDomain (will join $DomainName)" } # Create MABDC directories $dirs = @("C:\MABDC", "C:\MABDC\Config", "C:\MABDC\Logs", "C:\MABDC\Wallpapers", "C:\MABDC\Scripts", "C:\MABDC\Certs") foreach ($dir in $dirs) { if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null Write-Log "Created $dir" } } # Set PC name if provided if ($PCName) { $currentName = $env:COMPUTERNAME if ($currentName -ne $PCName) { Rename-Computer -NewName $PCName -Force Write-Log "PC renamed to $PCName (reboot required)" } } # Configure DNS to point to AD server Write-Log "Configuring DNS..." $adapters = Get-NetAdapter | Where-Object Status -EQ 'Up' foreach ($adapter in $adapters) { Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ServerAddresses ("159.195.41.59", "45.90.28.0") Write-Log "DNS set on adapter: $($adapter.Name)" } # Test AD connectivity Write-Log "Testing connection to AD server..." $adTest = Test-NetConnection -ComputerName "dc1.mabdc.org" -Port 389 -WarningAction SilentlyContinue if ($adTest.TcpTestSucceeded) { Write-Log "AD server reachable on LDAP (389) ✓" } else { Write-Log "WARNING: Cannot reach AD server on port 389. Trying port 636 (LDAPS)..." $adTest2 = Test-NetConnection -ComputerName "dc1.mabdc.org" -Port 636 -WarningAction SilentlyContinue if ($adTest2.TcpTestSucceeded) { Write-Log "AD server reachable on LDAPS (636) ✓" } else { Write-Host "ERROR: Cannot reach AD server. Check network/firewall." -ForegroundColor Red exit 1 } } # Join domain (if not already joined) if ($currentDomain -ne $DomainName) { Write-Log "Joining domain $DomainName..." $cred = Get-Credential -Message "Enter domain admin credentials for $DomainName" $ouPath = "OU=$Department,DC=mabdc,DC=org" try { Add-Computer -DomainName $DomainName -OUPath $ouPath -Credential $cred -Force Write-Log "Successfully joined $DomainName in OU=$Department ✓" } catch { Write-Log "Trying without OU specification..." Add-Computer -DomainName $DomainName -Credential $cred -Force Write-Log "Successfully joined $DomainName (default OU) ✓" } } # Install Chocolatey Write-Log "Installing Chocolatey package manager..." if (!(Get-Command choco -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy Bypass -Scope Process -Force [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) Write-Log "Chocolatey installed ✓" } else { Write-Log "Chocolatey already installed ✓" } # Refresh PATH $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") # Add MABDC Chocolatey source Write-Log "Adding MABDC package repository..." choco source add --name=mabdc --source="https://repo.mabdc.com/api/packages/mabdc/nuget/v2" --priority=1 -y Write-Log "MABDC repo added ✓" # Install base packages Write-Log "Installing base packages (this may take several minutes)..." $basePackages = @( "mabdc-base-config", "mabdc-debloat", "mabdc-nextdns-config", "mabdc-wallpaper", "mabdc-chrome-enterprise", "mabdc-rustdesk" ) foreach ($pkg in $basePackages) { Write-Log "Installing $pkg..." choco install $pkg --source=mabdc -y --no-progress 2>&1 | Out-Null if ($LASTEXITCODE -eq 0) { Write-Log "$pkg installed ✓" } else { Write-Log "WARNING: $pkg may have had issues (exit code: $LASTEXITCODE)" } } # Install department-specific packages Write-Log "Installing department packages for: $Department" $deptPackage = "dept-$($Department.ToLower())" choco install $deptPackage --source=mabdc -y --no-progress 2>&1 | Out-Null # Set up auto-update scheduled task Write-Log "Setting up automatic package updates..." $action = New-ScheduledTaskAction -Execute "choco" -Argument "upgrade all -y --source=mabdc --no-progress" $trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM" $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd Register-ScheduledTask -TaskName "MABDC-AutoUpdate" -Action $action -Trigger $trigger -Settings $settings -User "SYSTEM" -RunLevel Highest -Force | Out-Null Write-Log "Auto-update scheduled for 2:00 AM daily ✓" # Save join metadata $metadata = @{ pcName = $env:COMPUTERNAME department = $Department joinedAt = (Get-Date -Format "yyyy-MM-dd HH:mm:ss") joinedBy = $env:USERNAME windowsEdition = $edition windowsVersion = [System.Environment]::OSVersion.Version.ToString() domainName = $DomainName packagesInstalled = $basePackages } | ConvertTo-Json -Depth 3 Set-Content -Path "C:\MABDC\Config\join-metadata.json" -Value $metadata -Force Write-Log "" Write-Log "=========================================" Write-Log " MABDC Domain Join Complete! 🎉" Write-Log " Domain: $DomainName" Write-Log " Department: $Department" Write-Log " PC Name: $env:COMPUTERNAME" Write-Log "=========================================" Write-Log "" Write-Log "A restart is required to complete the domain join." $restart = Read-Host "Restart now? (Y/N)" if ($restart -eq 'Y' -or $restart -eq 'y') { Restart-Computer -Force }