Skip to main content

Windows Server 2022 VM

Windows Server 2022 VM creation on a Linux host using KVM

This process gives us a fairly minimal Windows Server 2022 VM running under KVM. This process has only been tested on Fedora Linux.

Define the VM name and location

# Define the new VM name:
export VMNAME="win2022-01"
mkdir -p ~/VMs/"${VMNAME}"
cd ~/VMs/"${VMNAME}"

# Set a custom folder icon with GNOME:
gio set -t string ${HOME}/VMs/${VMNAME} metadata::custom-icon file://${HOME}/Pictures/icons/folder-windows-server-2025.png

Creating the VM

# Copy the base image to the VM specific directory:
rsync --progress ~/VMs/base_images/win-serv-2022-c-base.qcow2 ~/VMs/${VMNAME}/${VMNAME}-c.qcow2

# Create the VM:
virt-install \
--connect qemu:///session \
--hvm \
--name "${VMNAME}" \
--memory "8192" \
--vcpus "2" \
--disk path="${HOME}/VMs/${VMNAME}/${VMNAME}-c.qcow2",bus=sata \
--cdrom "${HOME}/VMs/ISOs/Windows/VirtIO-Win/latest/virtio-win-0.1.285.iso" \
--os-variant "win2k22" \
--graphics spice \
--network=bridge:virbr0 \
--boot hd \
--noautoconsole \
--import

Installing VirtIO drivers

After the OS has been initialized the system will automatically shut down. Start the system back up, set the default Administrator password (See Password Manager) and login. Run the following application from the DVD and accept all the defaults:

virtio-win-guest-tools

Eject the ISO from the VM when the install has completed. Do not reboot yet! Set the desktop resolution to: 2560 x 1600 at 150% scale. Run the PowerShell script at: Set background colors for Windows desktops to set the intended desktop color.

Set the hostname

Set the hostname via an administrative level PowerShell instance:

Rename-Computer -NewName "win2022-01"

A system restart will be required for this to take effect, but do not reboot yet!

Set the time zone

Run the tzutil CLI utility in an administrative level PowerShell instance:

tzutil /s "UTC"

Ensure the system clock matches wall time after setting this.

Windows Update

Run the sconfig CLI utility in an administrative level PowerShell instance:

sconfig
# Option 5 - Enable Automatic updates
# Option 6 - Install updates
# Choose 1 to search for All updates
# then A again to install All updates
# Restart when requested

Install all available updates and reboot. This step may have to be run 3 times to get all of the updates installed. Continue until no more updates are available.

Install WinGet

WinGet is not included on Windows Server 2022 but can be installed. This script works but MUST be run under PowerShell v5, it will NOT install the .appx files under PowerShell 7.

# PowerShell v5 REQUIRED!!!
cd ~\Downloads
Start-BitsTransfer -Source "https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Destination "~\Downloads\WinGet.msixbundle"
Start-BitsTransfer -Source "https://github.com/microsoft/winget-cli/releases/latest/download/DesktopAppInstaller_Dependencies.zip" -Destination "~\Downloads\DesktopAppInstaller_Dependencies.zip"
Start-BitsTransfer -Source "https://github.com/microsoft/winget-cli/releases/latest/download/e53e159d00e04f729cc2180cffd1c02e_License1.xml" -Destination "~\Downloads\license.xml"
Expand-Archive -Path "~\Downloads\DesktopAppInstaller_Dependencies.zip"
Add-AppxPackage "~\Downloads\DesktopAppInstaller_Dependencies\x64\Microsoft.UI.Xaml*x64.appx"
Add-AppxPackage "~\Downloads\DesktopAppInstaller_Dependencies\x64\Microsoft.VCLibs*x64.appx"
Add-AppxPackage "~\Downloads\DesktopAppInstaller_Dependencies\x64\Microsoft.WindowsAppRuntime*x64.appx"
Add-AppxProvisionedPackage -Online -PackagePath .\WinGet.msixbundle -LicensePath .\license.xml
Get-AppPackage *Microsoft.DesktopAppInstaller*|select Name,PackageFullName
winget --info
Remove-Item -Path "~\Downloads\WinGet.msixbundle", "~\Downloads\DesktopAppInstaller_Dependencies.zip", "~\Downloads\DesktopAppInstaller_Dependencies", "~\Downloads\license.xml" -Recurse -Force

Installing PowerShell 7

Install the latest available version of PowerShell on Windows Server 2022, this installs to: C:\Program Files\PowerShell\7

Invoke-Expression "& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -useMSI -Quiet -EnablePSRemoting"

There will be a new PowerShell 7 (x64) item on the Start Menu. In the Windows Terminal app, open SettingsStartupDefault ProfilePowerShellSaveClose to set PowerShell 7 as the default terminal.

info

Do NOT install PowerShell from the Windows Store as if you do the install will end up in the users %LOCALAPPDATA%\Microsoft\WindowsApps\ folder and is only usable by the user that installed it.

Install POSH

See: Installing OhMyPosh / Powerline on your local Windows 11 system

Install Git etc.

Here we’ll install a few basic utilities to make our life easier:

# Install Git
winget install -e --source winget --id Microsoft.Git

# Install Notepad++
winget install -e --source winget --id Notepad++.Notepad++

# Install Zed (Advanced text editor) (Optional - can be slow on older systems)
# winget install -e --source winget --id ZedIndustries.Zed

# Install Nano for Windows (CLI text editor)
winget install -e --source winget --id okibcn.nano

# Install 7-Zip
winget install -e --source winget --id 7zip.7zip

# Install the Sysinternals Suite
winget install -e --source winget --id Microsoft.Sysinternals.Suite

Install marcosnils/bin for managing random binaries

bin is a lightweight, cross-platform binary manager that simplifies downloading, installing, and managing binaries without requiring root privileges. See the doc at: bin - Effortless binary manager

Uninstall PowerShell ISE

This tool does not support PowerShell 7 therefore it should be removed from the system and its usage discouraged.

DISM /Online /Remove-Capability /CapabilityName:Microsoft.Windows.PowerShell.ISE~~~~0.0.1.0

Expected response:

Deployment Image Servicing and Management tool
Version: 10.0.20348.2849

Image Version: 10.0.20348.5139

[==========================100.0%==========================]
The operation completed successfully.

Optional Installs

Installing IIS

Install-WindowsFeature -name Web-Server -IncludeManagementTools

Expected response:

Success Restart Needed Exit Code      Feature Result
------- -------------- --------- --------------
True No Success {Common HTTP Features, Default Document, Dir…

Verify what features are installed:

Get-WindowsFeature | Where-Object {$_.Installed -eq $true} | Format-Table Name, InstallState

Expected result:

Name                      InstallState
---- ------------
FileAndStorage-Services Installed
Storage-Services Installed
Web-Server Installed
Web-WebServer Installed
Web-Common-Http Installed
Web-Default-Doc Installed
Web-Dir-Browsing Installed
Web-Http-Errors Installed
Web-Static-Content Installed
Web-Health Installed
Web-Http-Logging Installed
Web-Performance Installed
Web-Stat-Compression Installed
Web-Security Installed
Web-Filtering Installed
Web-Mgmt-Tools Installed
Web-Mgmt-Console Installed
NET-Framework-45-Features Installed
NET-Framework-45-Core Installed
NET-WCF-Services45 Installed
NET-WCF-TCP-PortSharing45 Installed
Windows-Defender Installed
System-DataArchiver Installed
WindowsAdminCenterSetup Installed
PowerShellRoot Installed
PowerShell Installed
Wireless-Networking Installed
WoW64-Support Installed
XPS-Viewer Installed