Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

InfoWorld: Automate Live VM Export

Posted on March 13, 2014

infoworldThis is kinda cool, but I got published in InfoWorld, in a roundabout manner. J. Peter Bruzzese writes a column for InfoWorld on enterprise Windows. His latest column is about exporting Hyper-V virtual machines using PowerShell. In Windows Server 2012 R2 (and Windows 8.1) you can export a virtual machine even while it is running. Peter wanted to demonstrate with a weekly and monthly scenario using PowerShell to export virtual machines to a new folder and also delete older versions. The end result would be a set of 4 weekly folders and 2 monthly folders. But he needed help with some of the PowerShell so I pulled together a script which is linked in the InfoWorld article.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The script I wrote is a bit more complicated than what Peter originally envisioned. Now, I doubt his goal could be accomplished with a one-liner. So since I needed to write a script, I took the time to make it robust with items such as error handling and parameter validation. I only wanted to develop the script once so why not be thorough?

As I as finishing up the script to Peter's requirements, I realized this could also be tackled using a PowerShell workflow. One of the limitations in the original script is that it needs to run on the Hyper-V server. I didn't include any provision for connecting to a remote server. I also recognized that exporting multiple virtual machines could be done in parallel. Although my original script allows the use of background jobs which is sort of like running in parallel. But I thought a workflow version might at least be educational. Here is the Export-MyVM workflow.

#requires -version 3.0
#requires -module Hyper-V

Workflow Export-MyVM {

Param(
[Parameter(Position=0,Mandatory=$True,
HelpMessage="Enter the virtual machine name or names")]
[ValidateNotNullorEmpty()]
[Alias("name")]
[string[]]$VM,
[Parameter(Position=0,Mandatory=$True,
HelpMessage="Enter the root backup path")]
[ValidateNotNullorEmpty()]
[string]$Path,
[switch]$Monthly
)

Write-Verbose -Message "Starting $workflowcommandname"
#define some variables if we are doing weekly or monthly backups
if ($monthly) {
  $type = "Monthly"
  $retain = 2
}
else {
   $type = "Weekly"
   $retain = 4
}

Write-Verbose -message "Processing $type backups. Retaining last $retain."

#manage folders

#get backup directory list
Try {
 Write-Verbose -Message "Checking $path for subfolders"

 #get only directories under the path that start with Weekly or Monthly
 $subFolders =  Get-ChildItem -Path $path\$type* -Directory -ErrorAction Stop
}
Catch {
    Write-Warning "Failed to enumerate folders from $path. $($_.Exception.Message)"
    #bail out of the script
    return
}

#check if any backup folders
if ($subFolders) {
    #if found, get count
    Write-Verbose -message "Found $($subfolders.count) folder(s)"

    #if more than the value of $retain, delete oldest one
    if ($subFolders.count -ge $retain ) {
       #get oldest folder based on its CreationTime property
       $oldest = $subFolders | Sort-Object -property CreationTime | Select-Object -first 1 
       Write-Verbose -message "Deleting oldest folder $($oldest.fullname)"
       #delete it
       $oldest | Remove-Item -Recurse -Force 
    }

 } #if $subfolders
else {
    #if none found, create first one
    Write-Verbose -Message "No matching folders found. Creating the first folder"    
}

#create the folder
#get the current date
$now = Get-Date

#name format is Type_Year_Month_Day_HourMinute
$childPath = "{0}_{1}_{2:D2}_{3:D2}_{4:D2}{5:D2}" -f $type,$now.year,$now.month,$now.day,$now.hour,$now.minute

#create a variable that represents the new folder path
$newpath = Join-Path -Path $path -ChildPath $childPath

Try {
    Write-Verbose -message "Creating $newpath"
    #Create the new backup folder
    $BackupFolder = New-Item -Path $newpath -ItemType directory -ErrorAction Stop 
}
Catch {
  Write-Warning -message "Failed to create folder $newpath."
  throw $_
  #failed to create folder so bail out of the script
  Return
}

#export VMs
if ($BackupFolder) {

#export each machine in parallel
foreach -parallel ($item in $VM) {
    Write-Verbose -Message "Exporting $item"

    #define a hashtable of parameters to splat to Export-VM
    $exportParam = @{
     Path = $newPath
     Name=$item
     ErrorAction="Stop"
    }
    Try {
          Export-VM @exportParam
    }
    Catch {
           Write-Warning "Failed to export virtual machine(s)."
           Throw $_
     }

    } #foreach parallel
} #if backup folder exists 

Write-Verbose -Message "Ending $workflowcommandname"

} #close workflow

Most of the code is the same as the original script, although I removed the WhatIf parameter. You can't use SupportsShouldProcess in a workflow and I didn't have the time to fully write my own. The only code that is really workflow specific is this:

#export each machine in parallel
foreach -parallel ($item in $VM) {
    Write-Verbose -Message "Exporting $item"

    #define a hashtable of parameters to splat to Export-VM
    $exportParam = @{
     Path = $newPath
     Name=$item
     ErrorAction="Stop"
    }
    Try {
          Export-VM @exportParam
    }
    Catch {
           Write-Warning "Failed to export virtual machine(s)."
           Throw $_
     }

    } #foreach parallel

Perhaps the biggest advantage is that with a workflow I get automatic support for background jobs and remoting. Now I can execute the workflow against the Hyper-V server.

PS C:\> export-myvm -name 'chi-client02','chi-dctest' -path d:\backup -Verbose -AsJob -PSComputerName chi-hvr2.globomantics.local

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
100    Job100          PSWorkflowJob   Running       True            chi-hvr2.globoman... export-myvm              

PS C:\> get-job 100 -IncludeChildJob

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
100    Job100          PSWorkflowJob   Running       True            chi-hvr2.globoman... export-myvm              
101    Job101          PSWorkflowJob   Running       True            chi-hvr2.globoman... Export-MyVM

And I could still create a PowerShell scheduled job on my computer to run this workflow.

By the way, I'm sure you are aware that there are plenty of Hyper-V backup products from companies like Altaro, Veeam and Unitrends (all of whom help support my blog). Some of them even have free versions of their products. So while you can use PowerShell to export VMs that doesn't mean you should. Although I can see value for a quick and dirty backup. Ultimately, I suppose it is a good thing to have options.

Enjoy.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

5 thoughts on “InfoWorld: Automate Live VM Export”

  1. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #72 - Windows Management - TechCenter - Dell Community
  2. Sergio says:
    June 30, 2014 at 8:47 am

    Dear Jeffery,
    You did an amazing job in giving a direction in solving every administrator’s headache – automate a backup process. I have just one question. I can’t realize how to make it work in network environment. I get this 0*80070005 access denied error when trying to export VM to shared folder. I understand that this happens because I didn’t point the credetials to accsess shared folder. How can I specify credentials to access to my shared folder for “-path” parameter? Couple hours of googling brought nothing. Thanks in advance!
    Sergio

    1. Jeffery Hicks says:
      June 30, 2014 at 9:04 am

      If you are running this from a client pointed to a Hyper-V box and trying to backup to a network share that would account for the access denied. This is the 2nd hop issue with PowerShell remoting. By default you can’t remote to one machine and then hop from there to another remote machine. For security reasons that is not allowed. Unless you enable CredSSP which is the official solution.

      1. Sergio says:
        July 1, 2014 at 4:46 am

        Thank you so much for your advice. I’ll try to dig something in this direction. Maybe I’ll also try to automate moving files to network folder via script . But anyway your script is brilliant and advices very helpful. Thanks!

      2. Jeffery Hicks says:
        July 1, 2014 at 8:05 am

        Or run the script ON the server as a PowerShell scheduled job. Thanks for reading.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d