How to Use PowerShell to Manage Hyper-V VMs on Windows Server 2025

Windows Server 2025 ships with a mature and comprehensive Hyper-V PowerShell module that gives administrators granular, scriptable control over every aspect of virtual machine lifecycle management. Whether you’re spinning up hundreds of VMs from a template, adjusting compute resources on the fly, or orchestrating bulk operations across an entire fleet of virtualisation hosts, PowerShell is the most efficient path available. This tutorial walks through the essential cmdlets and patterns you need to confidently manage Hyper-V infrastructure using PowerShell on Windows Server 2025, from basic VM state control through to advanced networking, memory, and processor configuration.

Prerequisites

  • Windows Server 2025 with the Hyper-V role installed (Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart)
  • PowerShell 5.1 or PowerShell 7.4+ running as Administrator
  • The Hyper-V PowerShell module (automatically available after role install; verify with Get-Module -ListAvailable Hyper-V)
  • At least one existing VM to practice against, or sufficient disk space to create test VMs
  • Network connectivity to any remote Hyper-V hosts you plan to manage

Step 1: Import the Module and Enumerate VMs

The Hyper-V module loads automatically on systems with the role installed, but it is good practice to confirm the module is available and pull a baseline inventory before making changes. Get-VM is your starting point for almost every Hyper-V PowerShell session.

# Confirm module is loaded
Import-Module Hyper-V

# List all VMs on the local host
Get-VM

# List VMs in a specific state
Get-VM | Where-Object { $_.State -eq 'Running' }
Get-VM | Where-Object { $_.State -eq 'Off' }

# Get a specific VM by name
Get-VM -Name 'WebServer01'

# View detailed configuration of a single VM
Get-VM -Name 'WebServer01' | Select-Object *

# Query a remote Hyper-V host
Get-VM -ComputerName 'HVHOST02'

# Enumerate all VMs across multiple hosts
$hosts = 'HVHOST01', 'HVHOST02', 'HVHOST03'
Get-VM -ComputerName $hosts | Sort-Object ComputerName, Name

Step 2: Controlling VM Power State

Managing VM power state is one of the most frequent Hyper-V tasks. PowerShell provides dedicated cmdlets for each state transition, including graceful shutdown (which requires Integration Services) versus forced power-off.

# Start a stopped VM
Start-VM -Name 'WebServer01'

# Graceful shutdown (requires Hyper-V Integration Services in the guest)
Stop-VM -Name 'WebServer01'

# Force power off (equivalent to pulling the plug — use with caution)
Stop-VM -Name 'WebServer01' -Force

# Restart a running VM (graceful)
Restart-VM -Name 'WebServer01' -Force   # -Force bypasses the confirmation prompt

# Suspend (pause) a VM — freezes CPU execution while keeping RAM allocated
Suspend-VM -Name 'WebServer01'

# Resume a suspended VM
Resume-VM -Name 'WebServer01'

# Save VM state (hibernates to disk, frees RAM)
Save-VM -Name 'WebServer01'

# Bulk operation: start all VMs that are currently off
Get-VM | Where-Object { $_.State -eq 'Off' } | Start-VM

# Graceful shutdown of all running VMs (for maintenance window)
Get-VM | Where-Object { $_.State -eq 'Running' } | Stop-VM

Step 3: Configuring Dynamic Memory with Set-VMMemory

Dynamic Memory allows Hyper-V to adjust the RAM allocated to a VM between a configured minimum and maximum based on demand, improving host consolidation ratios. Use Set-VMMemory to configure all dynamic memory parameters.

# Enable dynamic memory with 2 GB startup, 1 GB minimum, 8 GB maximum
Set-VMMemory -VMName 'WebServer01' `
    -DynamicMemoryEnabled $true `
    -StartupBytes 2GB `
    -MinimumBytes 1GB `
    -MaximumBytes 8GB `
    -Buffer 20          # Reserve 20% above current demand as a buffer

# Disable dynamic memory (set a fixed allocation of 4 GB)
Set-VMMemory -VMName 'WebServer01' `
    -DynamicMemoryEnabled $false `
    -StartupBytes 4GB

# Review current memory settings
Get-VMMemory -VMName 'WebServer01'

# Apply consistent memory policy across multiple VMs
$vms = 'WebServer01', 'WebServer02', 'AppServer01'
foreach ($vm in $vms) {
    Set-VMMemory -VMName $vm `
        -DynamicMemoryEnabled $true `
        -StartupBytes 2GB `
        -MinimumBytes 512MB `
        -MaximumBytes 16GB
}

Step 4: Adjusting vCPU Count with Set-VMProcessor

Virtual processor configuration affects both VM performance and host resource planning. Set-VMProcessor lets you adjust the vCPU count, NUMA topology, and processor compatibility settings. Note that most vCPU changes require the VM to be in a stopped state.

# Assign 4 virtual processors to a stopped VM
Set-VMProcessor -VMName 'WebServer01' -Count 4

# Enable processor compatibility mode (allows live migration to hosts with different CPU features)
Set-VMProcessor -VMName 'WebServer01' -CompatibilityForMigrationEnabled $true

# Enable nested virtualisation (required for running Hyper-V or Docker inside a VM)
Set-VMProcessor -VMName 'WebServer01' -ExposeVirtualizationExtensions $true

# Set NUMA topology: 2 NUMA nodes, each with 2 vCPUs and 4 GB RAM
Set-VMProcessor -VMName 'WebServer01' -Count 4 -MaximumCountPerNumaNode 2
Set-VMMemory -VMName 'WebServer01' -MaximumAmountPerNumaNodeBytes 4GB

# Check current processor configuration
Get-VMProcessor -VMName 'WebServer01'

Step 5: Managing Virtual Hard Disks

You can create new virtual hard disks and attach them to running VMs without downtime. New-VHD creates the disk file and Add-VMHardDiskDrive connects it to the VM’s virtual storage controller.

# Create a new 100 GB dynamic VHDX
New-VHD -Path 'D:VHDsWebServer01_Data.vhdx' `
        -SizeBytes 100GB `
        -Dynamic

# Attach the new disk to a VM on SCSI controller 0, location 1
Add-VMHardDiskDrive -VMName 'WebServer01' `
    -ControllerType SCSI `
    -ControllerNumber 0 `
    -ControllerLocation 1 `
    -Path 'D:VHDsWebServer01_Data.vhdx'

# List all hard drives attached to a VM
Get-VMHardDiskDrive -VMName 'WebServer01'

# Create a fixed-size VHD for predictable performance
New-VHD -Path 'D:VHDsSQL01_Data.vhdx' `
        -SizeBytes 500GB `
        -Fixed

# Remove an attached disk (detach only — does not delete the file)
Remove-VMHardDiskDrive -VMName 'WebServer01' `
    -ControllerType SCSI `
    -ControllerNumber 0 `
    -ControllerLocation 1

Step 6: Configuring Network Adapters and VLANs

Network adapter management in Hyper-V covers adding synthetic adapters, connecting them to virtual switches, and configuring VLAN tagging — all controllable via PowerShell without touching the VM.

# Add a new synthetic network adapter to a VM
Add-VMNetworkAdapter -VMName 'WebServer01' -Name 'ProductionNIC' -SwitchName 'External-vSwitch'

# List all network adapters on a VM
Get-VMNetworkAdapter -VMName 'WebServer01'

# Connect an existing adapter to a different virtual switch
Connect-VMNetworkAdapter -VMName 'WebServer01' -Name 'ProductionNIC' -SwitchName 'Isolated-vSwitch'

# Configure access-mode VLAN tagging (assigns VLAN 100 to all traffic from this adapter)
Set-VMNetworkAdapterVlan -VMName 'WebServer01' `
    -VMNetworkAdapterName 'ProductionNIC' `
    -Access `
    -VlanId 100

# Configure trunk mode (for VMs running their own 802.1Q stack)
Set-VMNetworkAdapterVlan -VMName 'WebServer01' `
    -VMNetworkAdapterName 'ProductionNIC' `
    -Trunk `
    -AllowedVlanIdList '100-200' `
    -NativeVlanId 1

# Enable bandwidth management on an adapter (limit to 1 Gbps)
Set-VMNetworkAdapter -VMName 'WebServer01' `
    -Name 'ProductionNIC' `
    -MaximumBandwidth 1000000000

# Get MAC addresses for all adapters (useful for DHCP reservations)
Get-VMNetworkAdapter -VMName 'WebServer01' | Select-Object Name, MacAddress, SwitchName

Step 7: Querying and Configuring the Hyper-V Host

Get-VMHost exposes host-level configuration including default storage paths, live migration settings, and the number of concurrent migrations allowed. These settings affect every VM on the host.

# View all host-level settings
Get-VMHost

# Set default paths for new VMs and VHDs
Set-VMHost -VirtualMachinePath 'D:VMs' -VirtualHardDiskPath 'D:VHDs'

# Enable and configure live migration
Set-VMHost -VirtualMachineMigrationEnabled $true `
           -MaximumVirtualMachineMigrations 4 `
           -MaximumStorageMigrations 4

# Use Kerberos for live migration authentication
Set-VMHost -VirtualMachineMigrationAuthenticationType Kerberos

# Check resource metering (per-VM CPU/RAM/network/disk usage)
Enable-VMResourceMetering -VMName 'WebServer01'
Measure-VM -VMName 'WebServer01'

# Query host-level statistics across all nodes
$hosts = 'HVHOST01', 'HVHOST02'
Get-VMHost -ComputerName $hosts | Select-Object Name, LogicalProcessorCount, MemoryCapacity, VirtualMachineMigrationEnabled

Step 8: Building Bulk Operations with Pipelines

PowerShell pipelines let you apply changes to many VMs at once without writing explicit loops. This is especially valuable during maintenance windows or when rolling out a configuration standard across a large estate.

# Snapshot all running VMs with a timestamped checkpoint name
$timestamp = Get-Date -Format 'yyyy-MM-dd_HH-mm'
Get-VM | Where-Object { $_.State -eq 'Running' } |
    ForEach-Object { Checkpoint-VM -VM $_ -SnapshotName "Pre-Patch_$timestamp" }

# Report on VMs with fewer than 2 vCPUs
Get-VM | ForEach-Object {
    $proc = Get-VMProcessor -VMName $_.Name
    [PSCustomObject]@{
        VMName = $_.Name
        State  = $_.State
        vCPUs  = $proc.Count
    }
} | Where-Object { $_.vCPUs -lt 2 }

# Upgrade VM configuration version on all off VMs (WS2025 format)
Get-VM | Where-Object { $_.State -eq 'Off' } |
    ForEach-Object { Update-VMVersion -VMName $_.Name -Force }

# Export inventory of all VMs to CSV
Get-VM -ComputerName (Get-VMHost).Name |
    Select-Object ComputerName, Name, State, MemoryAssigned, ProcessorCount |
    Export-Csv -Path 'C:ReportsHyperV_Inventory.csv' -NoTypeInformation

Conclusion

PowerShell is the backbone of scalable Hyper-V management on Windows Server 2025. The cmdlets covered in this tutorial — from Get-VM and basic power state transitions through to dynamic memory tuning, vCPU assignment, disk attachment, VLAN configuration, and host-level settings — give you everything needed to manage a virtualisation infrastructure entirely from the command line or automated scripts. Combining these cmdlets with PowerShell pipelines, -ComputerName remoting, and scheduled jobs turns repetitive tasks into reliable, auditable automation. As a next step, explore pairing these techniques with Desired State Configuration (DSC) or PowerShell workflows to enforce VM configuration standards continuously across your environment.