Feb 8th, 2015
under
Programming
PowerShell
The following powershell script creates snapshots or exports of VMs on the local, and performs retention/cleanup as well. Be forewarned. There are known bugs with the current hyper-v snapshot integration and *nix systems.
<#
.SYNOPSIS
vmbackup - Creates snapshots or exports of VMs on this server
.DESCRIPTION
vmbackup - Creates snapshots or exports of VMs on this server
.PARAMETER mode
[Required] Snapshot mode or export/backup mode
.PARAMETER snap_days_retention
[Optional] Number of days to retain snapshots (defaults 3)
.PARAMETER num_exports_retention
[Optional] Number of exports to retain (defaults 2)
.PARAMETER export_path
[Optional] Path to export to
.PARAMETER debug
[Optional] Outputs debug level details
.NOTES
#>
Param (
[ Parameter ( Mandatory = $true )]
[ ValidateSet ( 'snapshot' , 'export' )]
[ string ] $mode ,
[ int ] $num_exports_retention = 2 ,
[ int ] $snap_days_retention = 1 ,
[ string ] $export_path = 'F:\ExportedVMs' ,
[ string ] $Logfile = 'C:\Scripts\Log\vmbackup.log'
)
$Error ActionPreference = "Stop"
<#
Formated output
#>
function Write-Output ( $message , $iserror = $false )
{
$message = ( "{0} {1}" -f ( Get-Date -Format s ), $message );
if ( $iserror -eq $true )
{
$Host . UI . WriteErrorLine ( $message );
}
else
{
Write-Host $message ;
}
}
<#
Snapshot all running VMs, and delete snapshots older than given days
#>
function snapshotAllRunningVMs ( $snap_days_retention )
{
# Get list of VMs (that are running)
Get-VM | Where { $_ . State -eq 'Running' } | ForEach-Object {
# Create a snapshot
Checkpoint-VM -VM $_ ;
# Delete snapshots older than $snap_days_retention days
Get-VMSnapshot -VM $_ | Where { $_ . CreationTime -lt ( Get-Date ) . AddDays ( - $snap_days_retention )} | Remove-VMSnapshot ;
}
}
<#
Returns true if given string is a parseable date
#>
function isDate ([ string ] $date )
{
$result = 0
if ( ! ([ DateTime ]:: TryParse ( $date , [ ref ] $result )))
{
return $false ;
}
return $true ;
}
<#
Performs a export backup of config and data togiven path for all vms
with a subdirectory dated
#>
function exportALLVMs ( $exports_retention , $export_path )
{
# Create our backup folder
$bk_folder = ( Join-Path $export_path $ ( get-date -f yyyy-MM-dd ));
New-Item -ItemType Directory -Force -Path $bk_folder | Out-Null ;
Write-Output ( "Exporting VMs to {0}" -f $bk_folder );
try
{
# Get list of all VMs
Get-VM | ForEach-Object {
Write-Output ( "Exporting {0}..." -f $_ . Name );
$_ | Export-VM -Path $bk_folder ;
}
}
catch [ Exception ]
{
echo $_ . Exception | format-list -force
exit -1 ;
}
try
{
# Delete directories over the number retention
Get-ChildItem -Path $export_path -Directory | Where { isDate $_ . Name -eq $true } |
Where { ([ DateTime ] $_ . Name ) -lt ( Get-Date ) . AddDays ( - $exports_retention )} |
ForEach-Object {
Write-Output ( "Remove exports for {0}" -f $_ . Name );
# Remove folder recursivly
Remove-Item -Recurse -Force $_ . FullName ;
}
}
catch [ Exception ]
{
echo $_ . Exception | format-list -force
exit -2 ;
}
}
if ( $mode -eq 'snapshot' )
{
snapshotAllRunningVMs $snap_days_retention ;
}
if ( $mode -eq 'export' )
{
exportAllVMs $num_exports_retention $export_path ;
}