How to Use PowerShell to Manage Hyper-V VMs on Windows Server 2022
PowerShell is the primary management interface for Hyper-V on Windows Server 2022. While Hyper-V Manager provides a GUI, PowerShell gives you automation, bulk operations, remote management, and capabilities that simply do not exist in the GUI. This guide covers the full Hyper-V PowerShell module and practical techniques for managing virtual machines efficiently in production environments.
Exploring the Hyper-V PowerShell Module
Before managing VMs, it helps to understand what commands are available. The Hyper-V module ships with Windows Server 2022 when the Hyper-V role is installed. List all available commands with:
Get-Command -Module Hyper-V
This returns over 200 cmdlets covering everything from VM creation to replication. To see commands grouped by noun, which reveals related functionality:
Get-Command -Module Hyper-V | Group-Object -Property Noun | Sort-Object Count -Descending
To import the module explicitly (it auto-loads on Server 2022 but useful in scripts):
Import-Module Hyper-V
Check the module version installed on your host:
Get-Module -Name Hyper-V -ListAvailable | Select-Object Name, Version, ModuleBase
Listing and Querying Virtual Machines
The Get-VM cmdlet is your starting point for any VM management task. By default it returns all VMs on the local host:
Get-VM
Filter by state to find only running VMs:
Get-VM | Where-Object { $_.State -eq 'Running' }
Get a specific VM by name:
Get-VM -Name "WebServer01"
View detailed properties of a VM including CPU, memory, and uptime:
Get-VM -Name "WebServer01" | Select-Object *
Get CPU usage statistics for all running VMs:
Get-VM | Where-Object { $_.State -eq 'Running' } | Select-Object Name, CPUUsage, MemoryAssigned, Uptime
Managing VM State: Start, Stop, Suspend, and Save
Controlling VM power state is straightforward with dedicated cmdlets. Start a VM:
Start-VM -Name "WebServer01"
Stop a VM gracefully (sends shutdown signal to the guest OS via Integration Services):
Stop-VM -Name "WebServer01"
Force a hard power off (equivalent to pulling the power cord — use only when the guest is unresponsive):
Stop-VM -Name "WebServer01" -Force -TurnOff
Suspend a VM (pauses execution, keeps state in memory):
Suspend-VM -Name "WebServer01"
Resume a suspended VM:
Resume-VM -Name "WebServer01"
Save a VM (hibernate-like state — writes memory to disk and stops):
Save-VM -Name "WebServer01"
Restart a VM gracefully:
Restart-VM -Name "WebServer01" -Force
Creating New Virtual Machines
Create a new Generation 2 VM with a specific amount of startup memory and connected to a virtual switch:
New-VM -Name "AppServer02" `
-Generation 2 `
-MemoryStartupBytes 4GB `
-SwitchName "External Switch" `
-NewVHDPath "D:VMsAppServer02AppServer02.vhdx" `
-NewVHDSizeBytes 80GB `
-Path "D:VMsAppServer02"
After creating the VM, attach an ISO for installation:
Add-VMDvdDrive -VMName "AppServer02" -Path "E:ISOsWS2022.iso"
Set the boot order so the VM boots from DVD first:
$dvd = Get-VMDvdDrive -VMName "AppServer02"
Set-VMFirmware -VMName "AppServer02" -FirstBootDevice $dvd
Configuring VM Settings with Set-VM
The Set-VM cmdlet modifies core VM properties. Rename a VM:
Set-VM -Name "AppServer02" -NewName "WebFrontend01"
Set a VM notes description:
Set-VM -Name "WebFrontend01" -Notes "Production web frontend - deployed 2026-05-17"
Enable automatic start on host boot with a 30-second delay:
Set-VM -Name "WebFrontend01" -AutomaticStartAction Start -AutomaticStartDelay 30
Configure what happens when the Hyper-V host shuts down:
Set-VM -Name "WebFrontend01" -AutomaticStopAction ShutDown
Valid values for AutomaticStopAction are TurnOff, Save, and ShutDown. For production VMs, ShutDown is the safest option as it sends a proper shutdown signal.
Configuring Virtual Processors
Adjust the number of virtual processors assigned to a VM (VM must be off or this can be done on WS2022 hot-add enabled VMs):
Set-VMProcessor -VMName "WebFrontend01" -Count 4
Configure NUMA topology for a VM that needs predictable memory access patterns:
Set-VMProcessor -VMName "WebFrontend01" -Count 8 -MaximumCountPerNumaNode 4 -MaximumCountPerNumaSocket 8
Limit CPU usage to prevent a noisy neighbor from consuming all host CPU resources:
Set-VMProcessor -VMName "WebFrontend01" -Maximum 50 -Reserve 10 -RelativeWeight 100
The -Maximum parameter caps CPU usage at a percentage of total host CPU capacity. -Reserve guarantees a minimum percentage. -RelativeWeight (1-10000) determines priority when CPU is contended.
Enable hardware performance counters pass-through (useful for profiling workloads in VMs):
Set-VMProcessor -VMName "WebFrontend01" -HwThreadCountPerCore 2
Managing VM Memory and Dynamic Memory
Set static memory for a VM:
Set-VMMemory -VMName "WebFrontend01" -StartupBytes 8GB
Enable Dynamic Memory, which allows Hyper-V to adjust the amount of RAM allocated to a VM based on demand:
Set-VMMemory -VMName "WebFrontend01" `
-DynamicMemoryEnabled $true `
-MinimumBytes 2GB `
-StartupBytes 4GB `
-MaximumBytes 16GB `
-Buffer 20 `
-Priority 80
The -Buffer parameter (percentage, 5-2000) tells Hyper-V how much extra memory to try to keep available above what the VM is currently using. The -Priority (1-100) controls how aggressively memory is allocated to this VM compared to others when the host is under memory pressure.
Check current memory status of all VMs:
Get-VMMemory -VMName * | Select-Object VMName, DynamicMemoryEnabled, Minimum, Startup, Maximum, Buffer, Priority
Network Adapter Management
List network adapters for a VM:
Get-VMNetworkAdapter -VMName "WebFrontend01"
Add a new network adapter and connect it to a virtual switch:
Add-VMNetworkAdapter -VMName "WebFrontend01" -SwitchName "Internal Switch" -Name "Management"
Connect an existing disconnected adapter to a switch:
Connect-VMNetworkAdapter -VMName "WebFrontend01" -Name "Management" -SwitchName "Internal Switch"
Configure a VLAN ID on a VM’s network adapter:
Set-VMNetworkAdapterVlan -VMName "WebFrontend01" -VMNetworkAdapterName "Management" -Access -VlanId 100
Enable bandwidth management to limit network throughput:
Set-VMNetworkAdapter -VMName "WebFrontend01" -Name "Management" `
-MaximumBandwidth 1000000000 `
-MinimumBandwidthWeight 10
The bandwidth values are in bits per second. 1000000000 = 1 Gbps. Remove a network adapter:
Remove-VMNetworkAdapter -VMName "WebFrontend01" -Name "Management"
Disk Operations: New-VHD, Resize-VHD, and Mount-VHD
Create a new dynamically expanding VHDX disk:
New-VHD -Path "D:VMsWebFrontend01DataDisk.vhdx" -SizeBytes 200GB -Dynamic
Create a fixed-size VHDX for predictable I/O performance:
New-VHD -Path "D:VMsWebFrontend01DataDisk-Fixed.vhdx" -SizeBytes 200GB -Fixed
Attach a VHDX to a running VM (SCSI controller required, not IDE):
Add-VMHardDiskDrive -VMName "WebFrontend01" -Path "D:VMsWebFrontend01DataDisk.vhdx" -ControllerType SCSI
Resize an existing VHDX online (VM can be running for expand operations):
Resize-VHD -Path "D:VMsWebFrontend01DataDisk.vhdx" -SizeBytes 500GB
After resizing at the Hyper-V level, you still need to extend the partition inside the VM using Resize-Partition or Disk Management. Mount a VHDX on the host for direct file access (useful for recovery):
Mount-VHD -Path "D:VMsWebFrontend01DataDisk.vhdx" -ReadOnly
Dismount when done:
Dismount-VHD -Path "D:VMsWebFrontend01DataDisk.vhdx"
Convert a VHD to VHDX format (VM must be off):
Convert-VHD -Path "D:VMsOldVMOldDisk.vhd" -DestinationPath "D:VMsOldVMOldDisk.vhdx" -VHDType Dynamic
Checkpoints (Snapshots)
Create a checkpoint before making risky changes:
Checkpoint-VM -Name "WebFrontend01" -SnapshotName "Before-IIS-Upgrade-2026-05-17"
List all checkpoints for a VM:
Get-VMCheckpoint -VMName "WebFrontend01"
Restore to a specific checkpoint:
Restore-VMCheckpoint -Name "Before-IIS-Upgrade-2026-05-17" -VMName "WebFrontend01" -Confirm:$false
Remove a checkpoint (frees disk space by merging the differencing disk):
Remove-VMCheckpoint -VMName "WebFrontend01" -Name "Before-IIS-Upgrade-2026-05-17"
Configure checkpoint type — Production checkpoints use VSS inside the guest for application-consistent state:
Set-VM -Name "WebFrontend01" -CheckpointType Production
Exporting and Importing Virtual Machines
Export a VM (creates a complete portable copy including all disks and configuration):
Export-VM -Name "WebFrontend01" -Path "E:Exports"
This creates a folder structure at E:ExportsWebFrontend01 containing the VM configuration and disk files. Import a previously exported VM:
Import-VM -Path "E:ExportsWebFrontend01Virtual Machines{GUID}.vmcx" -Copy -GenerateNewId
Bulk VM Operations with the Pipeline
PowerShell pipelines make bulk operations simple. Start all VMs that are currently saved:
Get-VM | Where-Object { $_.State -eq 'Saved' } | Start-VM
Shut down all running VMs except domain controllers:
Get-VM | Where-Object { $_.State -eq 'Running' -and $_.Name -notlike "DC*" } | Stop-VM
Create checkpoints on all running VMs before a host maintenance window:
Get-VM | Where-Object { $_.State -eq 'Running' } | ForEach-Object {
Checkpoint-VM -Name $_.Name -SnapshotName "Pre-Maintenance-$(Get-Date -Format 'yyyy-MM-dd')"
Write-Host "Checkpoint created for $($_.Name)"
}
Report memory usage for all VMs in a formatted table:
Get-VM | Select-Object Name, State,
@{N='MemoryGB'; E={[math]::Round($_.MemoryAssigned/1GB, 2)}},
@{N='MemoryDemandGB'; E={[math]::Round($_.MemoryDemand/1GB, 2)}},
CPUUsage, Uptime | Format-Table -AutoSize
Hyper-V PowerShell Remoting
Manage Hyper-V on remote hosts by specifying the -ComputerName parameter. This works with most Hyper-V cmdlets and requires WinRM connectivity to the remote host:
Get-VM -ComputerName "HV-HOST-02"
Start a VM on a remote host:
Start-VM -Name "DBServer01" -ComputerName "HV-HOST-02"
Query all VMs across multiple Hyper-V hosts at once:
$hvHosts = @("HV-HOST-01", "HV-HOST-02", "HV-HOST-03")
Get-VM -ComputerName $hvHosts | Select-Object ComputerName, Name, State, MemoryAssigned | Format-Table -AutoSize
Use an Enter-PSSession or Invoke-Command for operations that don’t support -ComputerName:
Invoke-Command -ComputerName "HV-HOST-02" -ScriptBlock {
Import-Module Hyper-V
Get-VMNetworkAdapter -VMName "DBServer01"
}
To manage Hyper-V on Server Core or Nano Server hosts remotely from your workstation, ensure the Hyper-V PowerShell tools are installed locally:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell
Live Migration with PowerShell
Move a running VM to another host (requires shared storage or storage migration):
Move-VM -Name "WebFrontend01" -DestinationHost "HV-HOST-02"
Storage live migration — move VM storage to a different path while the VM is running:
Move-VMStorage -VMName "WebFrontend01" -DestinationStoragePath "E:VMsWebFrontend01"
Move both the VM and its storage simultaneously:
Move-VM -Name "WebFrontend01" -DestinationHost "HV-HOST-02" `
-IncludeStorage -DestinationStoragePath "D:VMsWebFrontend01"
PowerShell provides the depth of control needed for serious Hyper-V management. Combining these cmdlets with scheduled tasks, monitoring scripts, and CI/CD pipelines gives you a fully automated virtualization platform built on Windows Server 2022.