GaneshShastri
Enthusiast
Enthusiast

Powershell Script to take VM Snapshot on scheduled time

Hi Team,

I need PS script to take snapshot about 42 VMs with memory. 25vms are located in one VC, and others are located in different VCs with respect to data center location.

While executing below PS i am getting error. Can anybody please help me on this.

$vc = Read-Host "vCenter Server Name"

$crediantial = Get-Credential

Connect-VIServer $vc -Credential $crediantial

$vmlist = Get-Content <VM Path>

    foreach ($vm in $vmlist)

{

New-Snapshot -VM $vm -Name <Snapshot name> -Description '<Descri+'%%date'>' -Quiesce -Memory

}

Disconnect-VIServer -Server $vc

Regards

Ganesh Shastri.

0 Kudos
1 Reply
Gidrakos
Hot Shot
Hot Shot

Hey Ganesh,

Use Get-VM instead of Get-Content since, by default, Get-VM will return all VMs in the inventory. You can also pass it names or wildcards to get specific VMs. I've also run into some small snags with running Connect-VIServer without error-checking, so you may want to throw something like this in:

## Disconnect all viServer instances so we don't get duplicate results.

Write-Host "Checking for unclosed vCenter Connections..." -noNewLine

try{

     # We don't want a previous connection because it will cause duplicate entries later on.

     Disconnect-VIServer * -confirm:$false

     # Run it again just in case it missed one or there were already multiple connections.

     Disconnect-VIServer * -confirm:$false

}

catch{

     # Nothing to do here since there were no servers to disconnect from.

     Write-Host -foregroundColor Green "[Done]"

}

## Attempt to connect to the vCenter Server

Write-Host -foreGroundColor Cyan "`nInitializing Services:"

try{

     Write-Host "Connecting to vCenter $vcAddress..." -noNewLine

     $vcConnection = Connect-ViServer vmware

     Write-Host -foreGroundColor Green "[Done]"

}

catch{

     Write-Host -foregroundColor Red -backgroundColor Black "`nCould not authenticate to vCenter"

     exit

}

That's something I like to add at the beginning of all my PowerCLI scripts just to make sure I've got a single, clean, connection to vCenter.

Beyond that, you'll want to use Get-VM instead of Get-Content since it's much easier and you can specify VM names including wildcards. Here's a small example of setting up and deleting a  snapshot for a VM:

function createSnapshot($vm){

     try{

          Write-Host "Creating new snapshot for $vm"

          Get-VM $vm | New-Snapshot -name "$vm Daily Snap" -description "Created with Snapshot Manager.ps1" -memory:$false -quiesce:$false -confirm:$false

          Write-Host -foregroundcolor "Green" "`nDone."

     }

     catch{

          Write-Host -foregroundcolor RED -backgroundcolor BLACK "Error creating new snapshot. See VCenter log for details."

     }

}

function removeSnapshot($vm){

     try{

          Write-Host "Previous snapshot detected, removing first..."

          Get-VM $vm | Get-Snapshot -name $snapshot | Remove-Snapshot -confirm:$false

          Write-Host -foregroundcolor "Green" "`nDone."

     }

     catch {

          Write-Host -foregroundcolor RED -backgroundcolor BLACK "Error deleting old snapshot. See VCenter log for details."

     break

     }

}

In combination with those above functions, you can run a for-loop for each VM. Here's a quick example that will grab all my VM's who's names begin with "vm-", deletes any current snapshots and creates a new one:

$vmList = Get-VM "vm-*"

forEach ($vm in $vmList) {

     $snapshot = Get-VM $vm | Get-Snapshot | Select-Object -expandProperty name

     if ($snapshot -eq "" -or $snapshot -eq $null){

          #No snapshots, create one at top level.

          createSnapshot($vm)

     }

     else {

          #Snapshot Exists, remove before continuing.

          removeSnapshot($vm)

          createSnapshot($vm)

     }

}

Hope this helps! Smiley Happy

0 Kudos