Category Archives: powercli

Copy vSwitch portgroups to a new host

Based on: PowerCLI: Easy vSwitch & PortGroup Setup | Virtu-Al.Net.

Here’s a great one-liner to copy all the portgroups from one host’s vswitch to a new host’s vswitch (example below copies oldhost’s portgroups on vSwitch1 to newhost’s portgroups on vSwitch2, keeping VLAN IDs intact):


$oldhost = get-vmhost -name oldhost.local.dom
$newhost = get-vmhost -name newhost.local.dom

$oldhost | get-virtualswitch -name vSwitch1 | get-virtualportgroup | foreach { $newportgroup = $newhost | get-virtualswitch -name vSwitch2 | new-virtualportgroup -name $_.Name -VLanID $_.VLanID }

Reporting on vCenter alarm emails

The PowerCLI applet Get-VIEvent can be used to report on any events that occur in vCenter, for any object.

To use it to see which alarms have generated email alerts for all VMs in the cluster, the following one-liner gets the job done:


Get-Cluster ClusterName | Get-VM | Get-VIevent -Start ([DateTime]"2012-07-10 00:00") -Finish ([DateTime]"2012-07-11 23:59") | Where { $_.GetType().Name -eq "AlarmEmailCompletedEvent"} | Select @{N="Name"; E={$_.Vm.Name}}, CreatedTime, Key, FullFormattedMessage | ft -autosize

Simply put, for all VMs in cluster “ClusterName”, get their events from 7/10/2012 to 7/11/2012 that have an event type of AlarmEmailCompletedEvent, and output the VM’s name, the date/time of the entry, the event key number for future reference, and the text of the message. Output it as a formatted table, autosized to accommodate the long strings of the message.

This can take awhile to run, especially if there are a large number of VMs in the cluster and they have a large number of events to sift through. By including start/finish times, the script will return faster as there’s a shorter window to sift through for AlarmEmailCompletedEvent entries.

Some notes:

  • Dynamic time-frame: the -Start and -Finish parameters can be dynamic, so that, for example, the time-frame to search begins 12 hours ago and ends 1 hour ago: -Start ((Get-Date).AddHours(-12)) -Finish ((Get-Date).Addhours(-1)) (Thanks LucD)
  • Type: this can be determined by piping the output of Get-VIevent to Get-Member. Above the list of methods and properties will be a TypeName which can be used with the Gettype().Name property (do not include the “VMware.Vim” portion of the TypeName).
  • Instead of piping to ‘ft’ (Format-Table), the output could be piped to Export-CSV (be sure to use the -notype parameter).
  • As always, bits and pieces were assembled from LucD’s great work.

Determining linked-clone space usage

I wanted to understand how VMware View linked-clone virtual machines consume space. Thankfully, Andre Leibovici has a great article “How to read Linked Clone Storage Provisioning metrics in vCenter“, describing these three storage metrics that are visible from a VM’s Summary tab in vSphere. (Need a review of how linked-clones work? Check out Andre’s “VMware View 4.5 Linked Cloning explained“)

These three storage metrics for every VM are described as follows:

  • Provisioned Storage: amount of total storage provisioned to a VM, since thin-provisioning is in use. This only includes files in the VM directory and is the sum of the “Provisioned size” column in the VM’s folder on the datastore. These files include the main VM disk which actually points to the replica, and then also the snapshot/delta disk. So easily, a linked clone has a provisioned size that is double that of the master VM (and therefore the replica). But it’s slightly misleading because the replica will not grow, only the VM’s snapshot/delta file will grow as the VM is used, until the next recompose.
  • Not-shared Storage: the total storage actually in use by the linked-clone, which only includes files in the VM directory. This would be the sum of the “Size” column in the VM’s folder on the datastore, and is data that the linked-clone has written after recompose or refresh: changes recorded in the delta (snapshot) disk.
  • Used Storage: the sum of storage used to support the existence of the virtual machine – includes the replica disk as well as changes that the VM has written since recompose or refresh.

With these key pieces of information, we can see that the most important metric is “Not-shared Storage”. However, “Used Storage” is useful to compare space savings. If the linked-clone VM was a full-blown normal VM, it would consume the amount indicated in “Used Storage”. But since it is using linked-clone technology, it only actually uses the amount indicated in “Not-shared Storage”, because the main bulk of the VM’s data (operating system, applications baked in to the image) is actually stored in the replica disk which is also used by all the other linked-clones.

If you want to compare across the entire environment and generate a space savings calculation, a bit of powershell can accomplish this:

Function GetUsage {
	Param($datastore)
	$VMs = get-datastore $datastore | get-vm | get-view
	$VMs | foreach-object {
		$VMName = $_ | select -expandproperty name
		$VMUnshared = $_ | select -expandproperty storage | select -expandproperty perdatastoreusage | select -expandproperty Unshared
		$VMUnsharedMB = [math]::round($VMUnshared/1MB,2)
		$VMUsed = $_ | select -expandproperty storage | select -expandproperty perdatastoreusage | select -expandproperty Committed
		$VMUsedMB = [math]::round($VMUsed/1MB,2)
		$UsageObj = New-Object System.Object
		$UsageObj | add-member -type noteproperty -name Name -value $VMName
		$UsageObj | add-member -type noteproperty -name UsageMB -value $VMUnsharedMB
		$UsageObj | add-member -type noteproperty -name FullUsageMB -value $VMUsedMB
		$UsageObj
	} | sort -property Name | export-csv c:\temp\usage-$datastore.csv -notype
}

GetUsage "Linked_Clones_01"
GetUsage "Linked_Clones_02"

To run, save it to a file and change the datastores on the “GetUsage” lines (add or remove datastores as needed) and change the CSV path as necessary (default: c:\temp). Connect to a vCenter server (connect-viserver) and run the script. The resulting CSV file will have three columns: Name of the VM, UsageMB (“Not-shared storage”) and FullUsageMB (“Used Storage”).

By adding up the UsageMB column and comparing it to the sum of the FullUsageMB column, one can easily see the difference in space usage by using linked-clone technology versus full-blown virtual machines. To calculate the space savings percentage, use the formula (1-(Usage/Full)).

A customer with over 3,000 linked-clone desktops (using a master VM image of 30GB) is only using 6.55 TB on disk. If these were full-blown virtual machines, the customer would consume over 91TB. By using linked-clones, the customer is realizing a space savings of 93%. Pretty cool stuff.

Datastore usage via powershell

In the vSphere Client, Datastore inventory view (Ctrl+Shift+D), VMware kindly gives us datastore Capacity and Free space values, but there is no column for Provisioned.

If you open a datastore, the Provisioned amount is displayed:

In my (humble) opinion, besides knowing how much Free space is left on the volume, Provisioned is important too so you know just how far in the hole you’re digging yourself by over-provisioning datastores, and it would be nice to see this in the list view of all Datastores as a way of comparison.

Since we don’t have that column available to us (VMware, pretty please?), a bit of Powershell can give us what we need.

connect-viserver your_vcenter_server
$datastores = get-datastore | where-object {$_.name -match "Servers"} | get-view
$datastores | select -expandproperty summary | select name, @{N="Capacity (GB)"; E={[math]::round($_.Capacity/1GB,2)}}, @{N="FreeSpace (GB)"; E={[math]::round($_.FreeSpace/1GB,2)}}, @{N="Provisioned (GB)"; E={[math]::round(($_.Capacity - $_.FreeSpace + $_.Uncommitted)/1GB,2) }}| sort -Property Name

In my example above, I am using where-object to filter only for datastores that have “Servers” in the name. Remove it or customize it as needed. The snippet above produces the following output:

.. you could even append “Export-CSV c:\path\to\output.csv -NoTypeInformation” to the end to write it to a CSV file, useful for Excel or other things.

Based on the following pages:

Expanding a VM’s hard drive using Powershell

Recently we needed to expand our Virtual Desktop VMs from 10GB C: drives to 15GB to accommodate some updates for one of our primary applications. The VMs are chronically low on free space so the decision was made to expand the drive.

The first step was to grow each VM’s VMDK from 10GB to 15GB. This was easily accomplished with Powershell:

Get-Folder Desktops | Get-VM | Get-HardDisk | Where {$_.CapacityKB -eq 10485760} | Set-HardDisk -CapacityKB 15728640 -Confirm:$false

Simply put, this one-liner acts against all VMs in the “Desktops” folder, and if it currently has a 10GB drive (10,485,760 KB), it uses the Set-HardDisk command to expand it to 15GB (15,728,640 KB). This worked incredibly well. I did run in to one or two VMs that had trouble expanding because they could not be “stunned” while currently in the process of VMotioning to another host. They weren’t actually migrating, so I quickly powercycled them and ran the one-liner again, with success.

The VMDKs are thin-provisioned so no additional space was consumed on the datastores, but now the disks can grow beyond 10GB, up to 15GB.

The next step which fortunately is “not my problem” is to expand the C: partition from 10GB to 15GB. I advised our desktop manager to try Dell’s “extpart” utility which can expand the C: partition while the VM is booted. I have used it successfully with Windows Server 2003, but not tried it with XP. I believe it will work though. Our desktop manager will probably make use of Altiris and some batch scripts to run extpart on all the desktops.