Exporting your Nutanix Hyper-V machines with Powershell

img_nutanix-v5

Hi Guys,

In this short blog post you will find a powershell script I created to quickly export my hyper-v virtual machines running on Nutanix. As you may or may not know, we can do this LIVE. Yes that’s right, there is no longer need to shut down your virtual machine before you can export it. This makes testing any changes on a production machine pretty easy. There is even a possiblity to export a snapshot of your virtual machine live. Anyway all of that are built in features of Hyper-V ofcourse.

First of all I’m guessing you know what Nutanix is and what it can deliver to you and your company so I’m jumping right in the setup I created. The main idea here was to have a script that I could execute on demand or via a scheduled task. Since I have multiple Nutanix nodes in my cluster I would need to call upon this script for every node. So in general this means I have created two scripts:

  • One to execute the actions to export the running virtual machines to another nutanix container and copy it over to a NAS
  • One that calls the above script once for every node and sends me a nice e-mail afterwards

I’m no powershell guru but this is something that you can easily use – maybe adapt it – in your own environment.

$date = Get-Date -format yyyy-MM-dd
$backupDir = “\\nutanix\CTR1\BACKUP\$date”
$Logfile = “$backupdir\log.log”

#Function to append data to the log file
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}

import-module hyper-v
$vms = get-vm

foreach ($vm in $vms)
{
Try{
$vmname = $vm.name
$VMState = $vm.State
If ($vm.name -like “NTNX*”)
{
write-host “This is a controller vm, do not export”

}elseif($vmstate -eq “running”){
$timestamp = get-date
logwrite($timestamp)
logwrite($vmname, $vmstate,”Exporting the virtual machine “”$VMname””… “)
Write-Host “Exporting the virtual machine “”$vm””… ” -NoNewline
Export-VM -vm $vm -Path $backupdir
Write-Host “Successfully exported $vmname” -ForegroundColor Green
logwrite(“Succesfully exported $vmname”)
$timestamp = get-date
logwrite($timestamp)
logwrite(“”)
}
}
Catch
{
Write-Host “Failed” -ForegroundColor Red
logwrite(“Failed to export””$vmname”” to “”$backupdir”)
logwrite(“”)

}

}

 

If you were to run this interactively, you can verify this export progress easily. Note that this will only export the running virtual machines but excluding the nutanix controller vm’s:

screen25

Ofcourse the goal would be to have this script run at a certain time and this for every  node in your cluster. So far I have only adapted the scripts to call upon for every node. You could adapt this to first enumerate all nodes in the cluster and work with a for each loop. Try it out! 🙂

The log file looks something like this:

screen26

This brings us to the next script, running it for every node and then reporting afterwards.

#clean up nutanix container  from yesterday’s backup
$limit = (Get-Date).AddDays(-1)
$path = “\\nutanix\CTR1\BACKUP”
# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

#start export
invoke-command -ComputerName NTNX-XYLOS-1 ‘C:\scripts\export-vm.ps1’
invoke-command -ComputerName NTNX-XYLOS-2 ‘C:\scripts\export-vm.ps1’
invoke-command -ComputerName NTNX-XYLOS-3 ‘C:\scripts\export-vm.ps1’

#START WITH REPORT

$Logfile= “$backupdir\$date\log.log”
$smtpServer = “xxxx”
$date = Get-Date -format yyyy-MM-dd
$attlog = new-object Net.Mail.Attachment($Logfile)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = “xxxxxxxxxxx”
$msg.To.Add(“xxxxxxxxxxx”)
$msg.To.Add(“yyyyyyyyyyy”)
$msg.Subject = “Nutanix backup script – $date”
$msg.Body = “Attached is the Nutanix export log for $date”
$msg.Attachments.Add($attlog)
$smtp.Send($msg)
$att.Dispose()

And there you go!

2 comments

    1. Hi John,

      Do be aware that this script was initially inteded to export all running VM’s except for Nutanix controller VM’s, this line of code should be removed in every non-nutanix environment:
      If (($vmname -notlike “NTNX*”) -and ($vmstate -eq “running”))

Leave a comment