KVM + Active Directory
Single-forest Windows Server 2022 domain controller in a libvirt VM — the foundation half of the two-VM Windows lab. Pair with the KVM + Exchange guide for mail.
Provision the VM
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/ad01.qcow2 80G && sudo chown root:qemu /var/lib/libvirt/images/ad01.qcow2 && sudo chmod 660 /var/lib/libvirt/images/ad01.qcow2Install Windows into the AD disk (with ISO)
sudo virt-install --name ad01 --memory 4096 --vcpus 2 --cpu host-passthrough --disk path=/var/lib/libvirt/images/ad01.qcow2,format=qcow2,bus=sata,cache=none --cdrom /var/lib/libvirt/images/SERVER_EVAL_x64FRE_en-us.iso --network network=default,model=e1000e --os-variant win2k22 --graphics spice1. Static IP + point DNS at self
AD requires a static IP; DNS must point at 127.0.0.1 so this DC resolves itself.
Get-NetAdapter # note the InterfaceAlias, usually "Ethernet"
New-NetIPAddress -InterfaceAlias "Ethernet" `
-IPAddress 192.168.122.10 -PrefixLength 24 -DefaultGateway 192.168.122.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 127.0.0.12. Install OpenSSH Server
# 1. Install the OpenSSH Server capability
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# 2. Start the service and set it to auto-start
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
# 3. Open the firewall (the installer usually creates this rule, but confirm)
if (-not (Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -DisplayName "OpenSSH Server (sshd)" `
-Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
}
# 4. Make PowerShell the default shell (so `ssh user@host` drops you into pwsh, not cmd)
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -ForceSame steps packaged as scripts/enable-ssh.ps1.
3. Rename the computer
Do this BEFORE promoting to DC — renaming a DC afterwards is painful.
Rename-Computer -NewName "DC01" -RestartVM reboots. Log back in.
4. Install the AD DS role
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools5. Promote to Domain Controller (creates a new forest)
DSRM password is for Directory Services Restore Mode recovery, not daily use.
$DSRMPassword = ConvertTo-SecureString "P@ssw0rd!LabOnly" -AsPlainText -Force
Install-ADDSForest `
-DomainName "lab.local" `
-DomainNetbiosName "LAB" `
-InstallDns:$true `
-SafeModeAdministratorPassword $DSRMPassword `
-Force:$trueVM reboots automatically. Login screen now shows LAB\Administrator.
6. Verify AD is healthy
Get-Service adws, kdc, netlogon, dns # all should be Running
Get-ADDomainController # should list DC01
Get-ADDomain # should show lab.local7. (Optional) Test OU + user
New-ADOrganizationalUnit -Name "LabUsers" -Path "DC=lab,DC=local"
New-ADUser -Name "Jane Doe" -SamAccountName "jane.doe" `
-UserPrincipalName "jane.doe@lab.local" `
-Path "OU=LabUsers,DC=lab,DC=local" `
-AccountPassword (ConvertTo-SecureString "TempP@ss123!" -AsPlainText -Force) `
-Enabled $true -ChangePasswordAtLogon $true