Skip to main content

How to Save (Pause) a Hyper-V Virtual Machine in Batch Script

Saving a Hyper-V virtual machine captures its entire running state (memory contents, CPU registers, device states) to a file on disk and then powers off the VM. When the VM is started again, it resumes exactly where it left off, including all open applications, network connections, and in-progress operations. This is conceptually similar to hibernation on a physical machine.

In this guide, we will explore how to save and resume Hyper-V virtual machines from a Batch Script, including the differences between saving, pausing, and checkpointing.

Understanding Save vs. Pause vs. Checkpoint

These three operations are commonly confused because they all preserve VM state, but they work differently:

OperationPowerShellBehaviorVM State After
SaveSave-VMWrites memory to disk, powers off VM. Frees host RAM.Saved
PauseSuspend-VMFreezes the VM in place. Memory stays in host RAM.Paused
CheckpointCheckpoint-VMCreates a snapshot. VM keeps running.Running
  • Save: Best for temporarily freeing host resources. The VM stops consuming CPU and memory. Resume with Start-VM.
  • Pause: Best for brief freezes (seconds to minutes). Fast to resume since memory is already in RAM. Resume with Resume-VM.
  • Checkpoint: Best for creating restore points before risky changes. VM continues running uninterrupted.

Method 1: Saving a Virtual Machine

@echo off
setlocal

set "vm_name=DevEnvironment"

:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)

echo Saving VM "%vm_name%"...

powershell -NoProfile -Command "Save-VM -Name '%vm_name%'"

if %errorlevel% equ 0 (
echo [SUCCESS] VM "%vm_name%" has been saved.
echo The VM state is written to disk and host memory is freed.
echo Use "Start-VM" to resume where you left off.
) else (
echo [ERROR] Failed to save VM.
echo Ensure the VM is running and has enough disk space for the state file.
)

pause
endlocal

Disk Space Consideration

When a VM is saved, the state file is approximately equal to the VM's assigned memory. A VM with 8 GB of RAM will create an ~8 GB state file. Ensure the storage location (typically the VM's configuration directory) has sufficient free space.

Method 2: Pausing (Suspending) a Virtual Machine

@echo off
setlocal

set "vm_name=TestServer"

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

echo Pausing VM "%vm_name%"...

powershell -NoProfile -Command "Suspend-VM -Name '%vm_name%'"

if %errorlevel% equ 0 (
echo [SUCCESS] VM "%vm_name%" is paused.
echo Memory is preserved in host RAM. Use "Resume-VM" to continue.
) else (
echo [ERROR] Failed to pause VM. Ensure the VM is running.
)

pause
endlocal

Method 3: Resuming a Saved or Paused VM

Both saved and paused VMs are resumed differently:

@echo off
setlocal enabledelayedexpansion

set "vm_name=DevEnvironment"

net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

:: Check current state
set "state="
for /f "delims=" %%S in ('powershell -NoProfile -Command "(Get-VM -Name '%vm_name%' -ErrorAction SilentlyContinue).State"') do set "state=%%S"

if not defined state (
echo [ERROR] VM "%vm_name%" not found.
pause
exit /b 1
)

echo VM "%vm_name%" is currently: !state!

if /i "!state!" == "Saved" (
echo Resuming from saved state...
powershell -NoProfile -Command "Start-VM -Name '%vm_name%'"
echo [OK] VM is resuming.
) else if /i "!state!" == "Paused" (
echo Resuming from paused state...
powershell -NoProfile -Command "Resume-VM -Name '%vm_name%'"
echo [OK] VM is resuming.
) else if /i "!state!" == "Running" (
echo [INFO] VM is already running. Nothing to do.
) else if /i "!state!" == "Off" (
echo [INFO] VM is off. Use Start-VM for a fresh boot.
) else (
echo [WARNING] Unexpected state: !state!
)

pause
endlocal

Method 4: Save All Running VMs (Host Maintenance)

Before performing host maintenance (OS updates, hardware changes), save all running VMs to free resources and preserve their state.

@echo off
setlocal enabledelayedexpansion

net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

echo =============================================
echo SAVING ALL RUNNING VMs
echo =============================================
echo.

set "saved=0"
set "failed=0"

for /f "delims=" %%N in ('powershell -NoProfile -Command "Get-VM | Where-Object State -eq 'Running' | Select-Object -ExpandProperty Name"') do (
echo Saving %%N...
powershell -NoProfile -Command "Save-VM -Name '%%N'"

if !errorlevel! equ 0 (
echo [OK]
set /a "saved+=1"
) else (
echo [FAIL]
set /a "failed+=1"
)
)

echo.
if !saved! equ 0 if !failed! equ 0 (
echo [INFO] No running VMs found.
) else (
echo [DONE] Saved: !saved!, Failed: !failed!
)

echo Host resources are now free for maintenance.
pause
endlocal

Method 5: Interactive VM State Manager

A tool that lets administrators quickly save, pause, or resume any VM:

@echo off
title VM State Manager
setlocal enabledelayedexpansion

net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Run as Administrator.
pause
exit /b 1
)

:menu
cls
echo =============================================
echo VM STATE MANAGER
echo =============================================
echo.

powershell -NoProfile -Command ^
"Get-VM | Format-Table Name, State, @{Name='MemGB';Expression={[math]::Round($_.MemoryAssigned/1GB,1)}} -AutoSize"

echo.
echo Commands:
echo save [name] - Save VM state to disk
echo pause [name] - Pause VM (keep in RAM^)
echo resume [name] - Resume saved or paused VM
echo saveall - Save all running VMs
echo exit - Quit
echo.
set "cmd="
set /p "cmd=Enter command: "

if not defined cmd goto menu

for /f "tokens=1,*" %%A in ("!cmd!") do (
set "action=%%A"
set "target=%%B"
)

if /i "!action!" == "save" (
if not defined target (
echo [ERROR] Usage: save [VMName]
pause
goto menu
)
powershell -NoProfile -Command "Save-VM -Name '!target!'"
if !errorlevel! equ 0 (echo [OK] Saved.) else (echo [ERROR] Failed.)
pause
goto menu
)
if /i "!action!" == "pause" (
if not defined target (
echo [ERROR] Usage: pause [VMName]
pause
goto menu
)
powershell -NoProfile -Command "Suspend-VM -Name '!target!'"
if !errorlevel! equ 0 (echo [OK] Paused.) else (echo [ERROR] Failed.)
pause
goto menu
)
if /i "!action!" == "resume" (
if not defined target (
echo [ERROR] Usage: resume [VMName]
pause
goto menu
)
powershell -NoProfile -Command ^
"$v = Get-VM -Name '!target!' -ErrorAction SilentlyContinue;" ^
"if (-not $v) { Write-Host '[ERROR] VM not found' }" ^
"elseif ($v.State -eq 'Saved') { Start-VM -Name '!target!'; Write-Host '[OK] Resuming from saved state' }" ^
"elseif ($v.State -eq 'Paused') { Resume-VM -Name '!target!'; Write-Host '[OK] Resuming from paused state' }" ^
"else { Write-Host ('Cannot resume. Current state: ' + $v.State) }"
pause
goto menu
)
if /i "!action!" == "saveall" (
powershell -NoProfile -Command ^
"$running = Get-VM | Where-Object State -eq 'Running';" ^
"if ($running.Count -eq 0) { Write-Host 'No running VMs found.' }" ^
"else { $running | Save-VM -Passthru | Format-Table Name, State -AutoSize }"
pause
goto menu
)
if /i "!action!" == "exit" (
endlocal
exit /b 0
)

echo [ERROR] Unknown command: !action!
pause
goto menu

When to Use Save vs. Pause

ScenarioRecommended
Host reboot for OS updatesSave (frees RAM, survives reboot)
Quick config check (30 seconds)Pause (instant resume)
End of work day, resume tomorrowSave (frees host resources overnight)
Taking a backup snapshotCheckpoint (VM keeps running)
Host has limited RAM, need to run another VMSave (frees the memory)

Common Mistakes

The Wrong Way: Using Save-VM on an Off VM

:: WRONG - Cannot save a VM that is not running
powershell -Command "Save-VM -Name 'StoppedVM'"

Output Concern: Save-VM requires the VM to be in a Running state. Saving an already-off VM makes no sense because there is no state to capture. The command will throw an error.

The Wrong Way: Confusing Suspend-VM with Stop-VM

:: WRONG - This shuts down the VM, not pauses it
powershell -Command "Stop-VM -Name 'MyVM'"
:: Expected: VM frozen in place | Actual: VM shut down

Stop-VM performs a graceful shutdown (guest OS powers off). Suspend-VM freezes the VM in place without shutting down. They are fundamentally different operations.

Best Practices

  1. Use Save-VM for long pauses: Save frees host memory and the VM state survives host reboots.
  2. Use Suspend-VM for brief freezes: Pausing is nearly instant to resume since memory stays in RAM.
  3. Verify disk space before saving: The state file equals the VM's memory size. Running out of disk during a save can corrupt the VM state.
  4. Resume saved VMs with Start-VM: Although it is the same command as a cold boot, Hyper-V detects the saved state and resumes instead of booting fresh.
  5. Resume paused VMs with Resume-VM: Do not use Start-VM on paused VMs; it will fail.

Conclusion

Saving and pausing Hyper-V virtual machines from a Batch Script is accomplished through PowerShell's Save-VM and Suspend-VM cmdlets. Saving writes the VM's complete state to disk and frees host resources, making it ideal for maintenance windows and overnight shutdowns. Pausing freezes the VM in RAM for instant resumption during brief administrative tasks. Understanding which operation to use in each scenario ensures efficient resource management and seamless VM lifecycle control.