I butchered a script which was originally created to clone VMs to a specific folder and datastore and remove a time stamp at the end of the VM name. I'm now trying to rework it so it recovers the clones back to a production datastore cluster rather than just a specific datastore. It does literally everything I need it to with one exception, I don't seem to be able to successfully tweak it to recover back to a datastore cluster as opposed to just a specific datastore. Everything I try results in dismal failure I wonder if someone can suggest a tweaked version for me so I can try and understand where I went wrong?
# ==============================================================================================
# NAME: RecoverVMs
#
# AUTHOR: Luke Glazebrook
# DATE : 09/10/2015
#
# COMMENT: Recovers cloned VMs and uses passed param to specify which cycle of VMs to restore,
# and removes the -$CYRPYYMMDD ammendment at the end of the VM name.
#
#
#
# * Software Dependencies: *
# - Microsoft PowerShell *
# - VMWare PowerCLI *
# ==============================================================================================
# Parameters
# ==============================================================================================
# The below parameter supplied by Control-M refers to cycle and recovery point prefix,
# the date can be added automatically however this functionality has been disabled.
# Date stamp supplied parameter e.g VM1-20151212
param ([string]$CYRPYYMMDD)
# ==============================================================================================
# Functions
# ==============================================================================================
#Function to allow you to check if a command is loaded
Function Check-Command($cmdname)
{
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}
# ==============================================================================================
# Varibles
# ==============================================================================================
# Add the vmware snapin for powershell
# Add-PSSnapin VMware.VimAutomation.Core
# Add the vmware snapin for powershell (stops you seeing the error messages)
if (Check-Command "Connect-VIServer")
{
Write-Host "Automation Tool already loaded"
}
else
{
#If not already loaded load the snapin
Write-Host "Loading Automation Tools"
Add-PSSnapin VMware.VimAutomation.Core
}
# backup = true appends date; false creates a clone with the same name.
$backup = "True"
# debug - true : will not clone vm; FALSE will clone the vm.
$debug = "FALSE"
# Target Datastore
$targetdatastore = "LS-H249-DS1-320GB"
#Refers to the percentage of free space for the DS space check
$freePerc = 5
# Target location - existing folder in vcenter structure, where the clones will be place
$targetlocation = "ProdFolder"
# Set date
$datestart = (get-date -uformat %Y%m%d)
# Name a logfile to capture results.
$logfile = $datestart + "_VMClones_bulk.txt"
#
write-output "New Log ($datestart) - ($logfile)" >> $logfile
# Gets the list of VMs from the file associated with this script
$VmFileList = Get-Content VmsToCloneList.list
#
$ds = Get-Datastore -Name $targetdatastore
#Email varibles
$From = "vCenter@lbase.homeip.net"
$To = "luke@lbase.homeip.net"
$Cc = "luke@lbase.homeip.net"
#$Attachment = "C:\temp\Some random file.txt"
$Subject = "!! TEST DMAT Report TEST !!"
$BodySuccess = "The DMAT VMs have been sucessfully recovered to the specified destination datastore and inventory organisational folder within vSphere"
$BodyFailure1 = "The combined provisioned VMDK usage of the VM's exceeds the capacity of the destination datastore, exiting with code 1"
$BodyFailure2 = "There is insufficient space on the target datastore, increase Space to continue, Exiting with code 2"
$BodyFailure3 = "A VM by the name specified cant be found perhaps it does not exists? Exiting with code 3"
$SMTPServer = "192.168.0.101"
$SMTPPort = "25"
# Establish Connection
Connect-VIServer -Server 127.0.0.1 -User administrator@lbase -Password omega1
# ==============================================================================================
# Deletes current working test VMs in preperation for the recovery of the backup clones
# ==============================================================================================
foreach($vm in $VmFileList){
$active = Get-VM $vm
if($active.PowerState -eq "PoweredOn"){
Stop-VM -VM $vm -Confirm:$false
Start-Sleep -Seconds 10
Remove-VM -VM $vm -DeleteFromDisk -Confirm:$false -RunAsync}
else
{Remove-VM -VM $vm -DeleteFromDisk -Confirm:$false -RunAsync}
}
# ==============================================================================================
# Gets the VM total ProvisionedSpaceGB for all VM's in the list.
# Additionally ensures whitespaces and hashes are ignored effectively
# creating a clean list which calculates/creates the varible required for validation check 1
# ==============================================================================================
$vmCleanedList = New-Object system.Collections.ArrayList
# Loop through our VM file List and clean is up, check for incorrectly specified VM's
ForEach ($vmname in $VmFileList)
{
if ([string]::IsNullOrWhiteSpace($vmname) -or $vmname.StartsWith("#"))
{
write-host("Invalid machine name - $vmname")
}
else
{
#Should trim vmname to ensure we have no spaces front or end
$vm = Get-VM $vmname
$vmCleanedList.Add($vmname)
$TotalRequiredGB += $vm.ProvisionedSpaceGB
}
Write-Host "Total Required = $TotalRequiredGB"
}
# ==============================================================================================
# Validation checks Prior to starting the clone script
# ==============================================================================================
# Validation check 1, Checks if the combined provisioned VMDK usage of the VM's exceeds the capacity of the destination datastore?
if(($ds.FreeSpaceGB -gt $TotalRequiredGB))
{
Write-Host "Continue with your script"
}
else
{
Write-Host "There is insufficient space on the target datastore. Please increase Space to continue"
Write-Output "There is insufficient space on the target datastore. Please increase Space to continue" >> $logfile
Write-Host "Exiting with code 1"
Write-Output "Exiting with code 1" >> $logfile
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $BodyFailure1 -SmtpServer $SMTPServer -port $SMTPPort
exit 1
}
$ds = Get-Datastore -Name $targetdatastore
# Validation check 2, do you have X % free datatstorespace?
if(($ds.FreeSpaceGB/$ds.CapacityGB*100) -ge $freePerc)
{
Write-Host "Continue with your script"
}
else
{
Write-Host "There is less than X% space free on the datastore. Please increase Space to continue"
Write-Output "There is less than X% space free on the datastore. Please increase Space to continue" >> $logfile
Write-Host "Exiting with code 2"
Write-Output "Exiting with code 2" >> $logfile
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $BodyFailure2 -SmtpServer $SMTPServer -port $SMTPPort
exit 2
}
#Hack + duplication of effort
#$VmListFile = Get-Content VmsToCloneList.list | Select-Object -Skip 3
ForEach ($vmname in $vmCleanedList)
{
# The VM Object
$RemoveCYRPYYMMDD = $vmname + "-" + $CYRPYYMMDD
$vm = Get-VM -Name $RemoveCYRPYYMMDD
# Target Host - use the same host as the current VM ( this is faster than cloning across hosts ).
$targethost = $vm.vmhost.name
# Target VM Name - name if BACKUP is FALSE
$vmtarget = $vmname
#
$datastore = get-datastore $targetdatastore -vmhost $targethost
# ==============================================================================================
# Begin the actual cloning script
# ==============================================================================================
if ($vm -ne $null)
{
Write-Host "A VM named $VM exists. Starting clone"
Write-output "A VM named $VM exists. Starting clone" >> $logfile
}
else
{
Write-Host "A VM by the name specified cant be found perhaps it does not exists?"
Write-Output "A VM by the name specified cant be found perhaps it does not exists?" >> $logfile
Write-Host "Exiting with code 3"
Write-Output "Exiting with code 3" >> $logfile
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $BodyFailure3 -SmtpServer $SMTPServer -port $SMTPPort
exit 3
}
if ($backup -eq "TRUE")
{
# Clone the VM to backup_vmname_todaysdate
$vmtarget #= $vmtarget + "-" + $CYRPYYMMDD #+ "-" + $datestart
}
# nice colors if you are watching the script run
write-host -foregroundcolor green "Cloning $vm to $vmtarget"
write-output -foregroundcolor green "Cloning $vm to $vmtarget" >> $logfile
new-vm -name $vmtarget -vm $vm -vmhost $targethost -datastore $datastore -Location $targetlocation -DiskStorageFormat thin
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $BodySuccess -SmtpServer $SMTPServer -port $SMTPPort
}
Write-Host "Complete"
Exit 0
# COMPLETED