Automatic Virtual Machine Consolidation

Posted on 10/09/2013 · Posted in Development, VMware

I’ve worked on the previous script that allowed you to run trough which VMs require consolidation and approve them. As some backup systems leave VMs in the need on consolidation, there is no point to run that script manually yourself. Here is a script that automatically does the consolidation and send an e-Mail with the success/fail information in a HTML table. That way you can automate the process using task scheduler to ease your work.

The $style variable is empty in this example. You can use it to modify the table with to 100% for example, or add colors etc.

 

#############################################################
###
### Automatic Consolidations of VM HDD's
### Version 1.1b
### 29.8.2013
###
##############################################################
###
### CONFIGURATION
###
$login_user = ""
$login_pwd = ""
$login_host = "your vcs server"
##############################################################
### END
##############################################################
###Prepare variables
$consolidationlist = $result = @()
$consolidationcount = $consolidaitonfailcount = $consolidationsuccesscount = 0
$export_datef = get-date -format yyyy-MM-dd-H-mm
$export_path = "C:\ScriptData\ConsolidationStatistics"
$logs_path = "C:\ScriptData\ScriptLogs"
$style = Write your HTML style in here

###Check if we are connected to vCenter Server(s)
if($global:DefaultVIServers.Count -lt 1)
{
	echo "We need to connect first"
	#To connect using predefined username-password
	#Connect-VIServer $login_host -User $login_user -Password $login_pwd -AllLinked:$true

	#To connect using PowerCLI credential store
	Connect-VIServer $login_host -AllLinked:$true
}
else
{
	echo "Already connected"
}

function sendMail($message){

     Write-Host "Sending Email"

     #SMTP server name
     $smtpServer = "smtp.server.local"

     #Creating a Mail object
     $msg = new-object Net.Mail.MailMessage

     #Creating SMTP server object
     $smtp = new-object Net.Mail.SmtpClient($smtpServer)

     #Email structure 
     $msg.From = "something@yourcompany.com"
     $msg.ReplyTo = "something@yourcompany.com"
     $msg.To.Add("something@yourcompany.com")
     $msg.subject = "Yourcompany Consolidation Report"
     $msg.body = $message
	 $msg.IsBodyHTML = $true

     #Sending email 
     $smtp.Send($msg)
}

get-view -ViewType VirtualMachine -Property Name, "Runtime", "LayoutEx.File"  | %{
	$vmName = $_.name
	if($_.runtime.consolidationNeeded) {
		$consolidation = $_.runtime.consolidationNeeded
		$consolidationcount++
		$deltadisks = ($_.LayoutEx.File | where {$_.name -like "*-000*.vmdk"}).count
		$consolidationlist += "" | select-object  @{n="VmName";e={$vmName}},@{n="Consolidation";e={$consolidation}},@{n="Delta Disks";e={$deltadisks}}
	}
}
if($consolidationcount -gt 0)
{
	###Export the result to a CSV file
	$consolidationlist | export-csv -path "$export_path\VM-Consolidation-$export_datef.csv" -useculture
	write-host "VM's needing conslodation: $consolidationcount"
	#Print out our table
	$consolidationlist | format-table -autosize | out-default

	get-view -ViewType VirtualMachine -Property Name, "runtime" | where {$_.runtime.consolidationNeeded} | %{
		$vmName = $_.name
		if($_.runtime.consolidationNeeded) {
			write-host "$vmName consolidation started"
			try {
				$_.ConsolidateVMDisks()
			}
			catch [Exception] {
				$Exception = $_.Exception.Message
			}
			if(!$Exception) {
				write-host "Consolidation completed"
				$result += "" | select-object  @{N="Virtual Machine"; E={$vmName}},@{N="Status"; E={"Success"}}
				$consolidationsuccesscount++
			}
			else {
				Write-host "The following error was returned: $Exception"
				$consolidationfailure = 0
				$result += "" | select-object  @{N="Virtual Machine"; E={$vmName}},@{N="Status"; E={$Exception}}
				$consolidaitonfailcount++
				$Exception = $false
			}
		}
	}
	Write-Host "All Virtual Machines processsed"	
	Add-Content $logs_path\Automatic-ConsolidateAll.txt "`n $export_datef Script ran successfully and $consolidationcount VM's needing consolidation found. Success: $consolidationsuccesscount | Failed: $consolidaitonfailcount"
	$result = $result | ConvertTo-Html -head $style
	$message = "
	($consolidationsuccesscount of $consolidationcount) consolidated successfully
	($consolidaitonfailcount of $consolidationcount) failed consolidation

$result "; sendMail($message) 
}
else{ 
write-host "No virtual machines require consolidation" Add-Content $logs_path\Automatic-ConsolidateAll.txt "`n $export_datef No virtual machines require consolidation" 
}