How to List All Hyper-V Virtual Machines in Batch Script
Hyper-V is Microsoft's hypervisor technology built into Windows Server and Windows 10/11 Pro and Enterprise editions. Listing all virtual machines (VMs) on a Hyper-V host is a routine task for administrators managing virtualized infrastructure. Whether you are checking which VMs are running, generating inventory reports, or building automation scripts that operate on specific VMs, programmatic enumeration is essential.
In this guide, we will explore how to list all Hyper-V virtual machines from a Batch Script using PowerShell integration, since Batch alone has no native Hyper-V management commands.
Why PowerShell Integration?
Hyper-V management in Windows is handled exclusively through PowerShell cmdlets (Get-VM, Start-VM, Stop-VM, etc.) and the Hyper-V Manager GUI. There are no native cmd.exe commands for Hyper-V operations. Batch scripts access Hyper-V by embedding PowerShell commands using the powershell -command or powershell -noprofile -command syntax.
Method 1: Basic VM Listing
The simplest approach lists all VMs with their name and state.
@echo off
setlocal
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
echo =============================================
echo HYPER-V VIRTUAL MACHINES
echo =============================================
echo.
powershell -noprofile -command "Get-VM | Format-Table Name, State, CPUUsage, MemoryAssigned, Uptime -AutoSize"
if %errorlevel% neq 0 (
echo.
echo [ERROR] Failed to query Hyper-V.
echo Ensure Hyper-V is installed and the Hyper-V PowerShell module is available.
)
pause
Sample Output
Name State CPUUsage MemoryAssigned Uptime
---- ----- -------- -------------- ------
WebServer-01 Running 2 4294967296 3.05:22:10
DatabaseVM Running 12 8589934592 3.05:22:05
TestEnv-Dev Off 0 0 00:00:00
BackupProxy Saved 0 2147483648 00:00:00
VM States
| State | Meaning |
|---|---|
Running | VM is powered on and active |
Off | VM is completely shut down |
Saved | VM state has been saved to disk (suspended) |
Paused | VM is temporarily paused |
Starting | VM is in the process of booting |
Stopping | VM is shutting down |
Method 2: Listing Only VM Names
For scripts that need a clean list of names to iterate over:
@echo off
setlocal enabledelayedexpansion
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
echo Hyper-V Virtual Machine Names:
echo ==============================
echo.
set "count=0"
for /f "delims=" %%N in ('powershell -noprofile -command "Get-VM | Select-Object -ExpandProperty Name"') do (
set /a count+=1
echo !count!. %%N
)
echo.
echo Total: !count! VMs
pause
Method 3: Filtering by State
List only running VMs, only stopped VMs, or any specific state:
@echo off
setlocal
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
echo Currently RUNNING Virtual Machines:
echo ====================================
echo.
powershell -noprofile -command "Get-VM | Where-Object { $_.State -eq 'Running' } | Format-Table Name, CPUUsage, MemoryAssigned, Uptime -AutoSize"
echo.
echo Currently OFF Virtual Machines:
echo ================================
echo.
powershell -noprofile -command "Get-VM | Where-Object { $_.State -eq 'Off' } | Format-Table Name -AutoSize"
pause
Method 4: Detailed VM Inventory Report
For comprehensive infrastructure documentation:
@echo off
setlocal
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
echo Generating detailed VM inventory...
echo.
powershell -noprofile -command ^
"Get-VM | ForEach-Object {" ^
" Write-Host ('=== ' + $_.Name + ' ===');" ^
" Write-Host (' State: ' + $_.State);" ^
" Write-Host (' Generation: ' + $_.Generation);" ^
" Write-Host (' CPUs: ' + $_.ProcessorCount);" ^
" Write-Host (' Memory: ' + [math]::Round($_.MemoryAssigned / 1GB, 2) + ' GB');" ^
" Write-Host (' Uptime: ' + $_.Uptime);" ^
" $_.NetworkAdapters | ForEach-Object {" ^
" Write-Host (' NIC: ' + $_.SwitchName + ' (' + ($_.IPAddresses -join ', ') + ')')" ^
" };" ^
" $_.HardDrives | ForEach-Object {" ^
" Write-Host (' VHD: ' + $_.Path)" ^
" };" ^
" Write-Host ''" ^
"}"
pause
Method 5: CSV Export for Inventory Management
@echo off
setlocal
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
set "output=%~dp0hyperv_inventory_%COMPUTERNAME%.csv"
echo Exporting Hyper-V VM inventory to CSV...
powershell -noprofile -command ^
"Get-VM | Select-Object Name, State, Generation, ProcessorCount," ^
"@{Name='MemoryGB';Expression={[math]::Round($_.MemoryAssigned/1GB,2)}}," ^
"@{Name='Uptime';Expression={$_.Uptime.ToString()}}," ^
"@{Name='VHDPaths';Expression={($_.HardDrives.Path) -join '; '}}" ^
"| Export-Csv -Path '%output%' -NoTypeInformation"
if %errorlevel% equ 0 (
echo [SUCCESS] Exported to: %output%
echo.
type "%output%"
) else (
echo [ERROR] Export failed.
)
echo.
pause
Method 6: Status Dashboard
A refreshing dashboard that shows live VM status:
@echo off
setlocal
title Hyper-V Status Monitor
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
:loop
cls
echo =============================================
echo HYPER-V STATUS MONITOR
echo %date% %time:~0,8%
echo =============================================
echo.
powershell -noprofile -command ^
"$vms = Get-VM;" ^
"$running = @($vms | Where-Object State -eq 'Running').Count;" ^
"$off = @($vms | Where-Object State -eq 'Off').Count;" ^
"$other = $vms.Count - $running - $off;" ^
"$vms | Sort-Object State, Name | ForEach-Object {" ^
" $icon = '[ ]'; if ($_.State -eq 'Running') { $icon = '[*]' };" ^
" Write-Host ('{0} {1,-25} {2,-10} CPU:{3}%% Mem:{4}GB' -f $icon, $_.Name, $_.State, $_.CPUUsage, [math]::Round($_.MemoryAssigned/1GB,1))" ^
"};" ^
"Write-Host '';" ^
"Write-Host ('Running: {0} Off: {1} Other: {2} Total: {3}' -f $running, $off, $other, $vms.Count)"
echo.
echo Press any key to refresh...
pause >nul
goto loop
Querying Remote Hyper-V Hosts
To list VMs on a remote server:
@echo off
setlocal
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
set "remote_host=HyperV-Server01"
echo Querying VMs on %remote_host%...
echo.
powershell -noprofile -command "Get-VM -ComputerName '%remote_host%' | Format-Table Name, State, CPUUsage -AutoSize"
pause
Remote Hyper-V management requires the Hyper-V PowerShell module installed locally and WinRM configured on the remote host. The executing user must have Hyper-V administrator permissions on the remote server.
Common Mistakes
The Wrong Way: Using WMIC for Hyper-V
:: WRONG - WMIC does not have direct Hyper-V VM enumeration
wmic /namespace:\\root\virtualization\v2 path Msvm_ComputerSystem get ElementName
Output Concern:
While the WMI namespace root\virtualization\v2 exists and can technically query Hyper-V objects, the output is raw and difficult to parse. The Get-VM PowerShell cmdlet is the supported, documented, and far more user-friendly interface.
The Wrong Way: Not Running as Administrator
:: WRONG - Get-VM requires elevation
powershell -command "Get-VM"
Without administrator privileges, Get-VM may return an empty result or throw an access denied error. Always verify admin rights before querying Hyper-V.
Best Practices
- Use
Get-VMvia PowerShell: It is the official, fully-supported cmdlet for Hyper-V management. - Run as Administrator: Hyper-V operations require elevated privileges.
- Filter by state for targeted actions: Use
Where-Objectto isolate running, stopped, or saved VMs. - Export regularly: CSV exports provide audit trails and capacity planning data.
- Use
-ComputerNamefor remote hosts: Manage your entire Hyper-V cluster from a single management machine.
Conclusion
Listing all Hyper-V virtual machines from a Batch Script requires embedding PowerShell's Get-VM cmdlet, which provides comprehensive VM information including name, state, CPU usage, memory allocation, and storage paths. By formatting the output as tables, filtered lists, CSV exports, or live dashboards, administrators can build powerful monitoring and inventory tools that serve both day-to-day operations and long-term capacity planning. The key is remembering that all Hyper-V management flows through PowerShell, with Batch serving as the scripting wrapper.