Automating VM deployment with conditions

I hope someone can help me automate our VM deployments.  I have most of the script done but I need help with a few things.

Here's what I'm trying to automate:

  • Prestage VMs in a specific folder for users to take at will. 

The exiting process:

  • Check folder and confirm there are at least 3 VMs available.  If not, manually deploy the VM from template.
  • Enter the VM name based on the next available number sequence (userx122, userx123, userx124, etc),
  • Choose the customization specification
  • Select the datastore with the most free space. 
    • Conditions = Datastore name must start with USER and it must have more than 100GB of free space.
  • Press finish.

I need help with:

  • Syntax to determine the new VM name
  • Syntax to select the datastore based on the conditions.

Any help would be greatly appreciated!

0 Kudos
5 Replies

Could you post what you have already?

0 Kudos

Hello, bolsen-

To get the two items you mentioned, how about:

## Syntax to determine the new VM name
# get the number portion of the currently highest numbered userx* VM
$intCurrentHighestNum = Get-VM userx* | Select name | %{if ($_ -match "\d+") {[int]$Matches[0]}} | Sort-Object -Descending | Select -First 1
## make a string to use for the next sequential VM name
$strNextVMName = "userx$($intCurrentHighestNum + 1)"

## Syntax to select the datastore whose name starts with USER, has the most free space, and has at least 100GB free
   will be the given datastore object if one that meets all of the criteria exists, else it will be $null
$dstDatastoreToUse = Get-Datastore -Name user* | Sort FreeSpaceMB -Descending | Select -First 1 | ?{$_.FreeSpaceMB -gt 100*1kb}

Let us know how that does.

0 Kudos

Thanks for the help.  I've almost got it working but I could use help with two other things:

1. Is it possible to dynamically select the -vmhost value based on certain requirements?  For example, I have two clusters and I want to select a host within the cluster with most free CPU resources and free disk space.

2. Stupid question but how to I power on the machine after it's been deployed.  There must be a way to take the results of the new-vm command, specifically the name value, and apply that to a "get-vm | somethingsomething | start-vm"

0 Kudos

1) Try something like this

$esx = Get-Cluster MyCluster | Get-VMHost | Sort-Object -Property CpuUsageMhz | Select -First 1

It will provide you with the host that uses the least CPU resources in the cluster

Similarly for the datastore you can do

$ds = Get-Cluster MyCluster | Get-VMHost | Select -First 1 | Get-Datastore | where {$_.Extensiondata.Summary.MultipleHostAccess -and $_.Type -eq "VMFS"} | Sort-Object FreeSpaceMB -Descending | select -First 1

2) You can capture the output from the New-VM cmdlet and use that object in the Start-VM cmdlet

New-VM .... | Start-VM -Confirm:$false


$vm = New-VM ....

Start-VM -VM $vm -Confirm:$false

Blog:  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos

Thanks to everyone for their help, here's the script I have so far:

EDIT: Removed script because it had some typos in it.  I'll re-upload it after I add some of the features below.

Next I plan to make the following enhancements (help is always needed Smiley Wink)

  • Insert another condition to only deploy a machine if there are less than 3 VMs in the _UnderConstruction folder.
  • Add error reporting and email notifications.
    • If no datastores have free space, send an email saying the deployment can't finish because no space exists.
  • Insert a condition to check the VM name.
    • If the number within the VM name is more than 25 "Counts" higher than the second highest number, then send an email alert and exit script.
      • On occasion we deploy test VMs with a very high number - the script sees this and selects the next highest number (which we don't want because it will mess up the "production" numbering scheme.

0 Kudos