Skip to main content

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

StateMeaning
RunningVM is powered on and active
OffVM is completely shut down
SavedVM state has been saved to disk (suspended)
PausedVM is temporarily paused
StartingVM is in the process of booting
StoppingVM 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
info

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

  1. Use Get-VM via PowerShell: It is the official, fully-supported cmdlet for Hyper-V management.
  2. Run as Administrator: Hyper-V operations require elevated privileges.
  3. Filter by state for targeted actions: Use Where-Object to isolate running, stopped, or saved VMs.
  4. Export regularly: CSV exports provide audit trails and capacity planning data.
  5. Use -ComputerName for 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.