VMware Cloud Community
GuruAnt
Contributor
Contributor
Jump to solution

New-VM - Not accepting a variable as input

Hi, I'm hoping someone will be able to help me.

I'm looking to create a script that deploys machines from an existing template to the datastore with the most space, and the server with the least guests.

So far, I've got the following

Set-Variable -Name strTemplate -Value template_name
Set-Variable -Name strName -Value new_machine_name
Set-Variable -Name strCustomization -Value customisation_name
Connect-VIserver my_vi_server
$biggestdatastore = (get-Datastore -Name VOL* | Sort-Object -Property FreeSpaceMB -Descending)
$strBesthost = (get-vmhost | select name, @{ name="NVMs";
expression = {($_ | get-vm | measure-object).count}} | sort -property NVMs)
Get-Template $strTemplate | New-VM -name $strTemplate$increment -VMHost $strBesthost[0] -OSCustomizationSpec $strCustomization -Datastore $biggestdatastore[0]

When I run this, I get the following error

New-VM : Cannot bind parameter 'VMHost'. Cannot convert "" to "VMware.VimAutomation.Types.VMHost".
At E:\Scripting\Powershell\deployMachines.ps1:15 char:72
+ Get-Template $strTemplate | New-VM -name $strTemplate$increment -VMHost <<<<
$strBesthost[0] -OSCustomizationSpec $strCustomization -Datastore $biggestdatastore[0]

When I replace the $strBesthost[0] variable with a server name, it seems to work fine, so the $biggestdatastore[0] variable seems to work, it's just the $strBesthost[0] that's causing problems.

Dot-sourcing the script, seems to result in the correct object being assigned, with $strBesthost[0] displaying the following:

Name NVMs
-


-


+ my_esx_host.fqdn.com+ 3

Im a newbie to PowerShell scripting, so any fixes, or alternatives would be appreciated!

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
hugopeeters
Hot Shot
Hot Shot
Jump to solution

You should be able to get the correct VMHost in a single step. Let me try it off the top of my head (not near any powershell VI toolkit right now):

If MYCLUSTER is the cluster you want to look in, use:

$cluster = Get-Cluster MYCLUSTER

$objBestHost = (Get-VMHost -Location $cluster | Add-Member -MemberType ScriptProperty -Name NumVMs -Value {(Get-VM -VMHost $_ | Measure-Object).Count} -Passthru | Sort NumVMs)[0]

{noformat]{code}

Edit: Not descending, best host has least vms

View solution in original post

0 Kudos
4 Replies
hugopeeters
Hot Shot
Hot Shot
Jump to solution

The object type of $strBestHost is wrong. This is caused by Select, as it creates a new object and copies the properties you specify. Dot-source it and do $strBestHost.GetType() to confirm.

DO:

$objBestHost = Get-VMHost -Name $strBestHost[0].Name

Then use $objBestHost for the New-VM

Hugo

GuruAnt
Contributor
Contributor
Jump to solution

Edit: Never mind - The host with the least guests was part of the Lab Manager cluster, and gave the same error message when specified explicitly as it did when using the variable. Now to try and find a way of only selecting non-lab manager hosts!

I now get the following:

New-VM : 21/11/2008 13:39:30 New-VM BA55273F-BDA9-46EA-A877-DAE9AE5C0656
The operation for the entity vm-2859 failed with the following message: "A specified parameter was not correct. host"
At E:\Scripting\Powershell\deployMachines.ps1:31 char:37
+ Get-Template $strTemplate | New-VM <<<< -name $strTemplate$increment -VMHost $objBestHost -OSCustomizationSpec $strCustomization -Datastore $biggestdatastore[0]

I've also tried running it in the Dot-Namepsace, and $strBestHost.GetType() Reports the following:

IsPublic: True
IsSerial: True
Name: Object[]
BaseType: System.Array

$objBestHost produces

Name: servername.fqdn.com
State: Connected
Id: HostSys...

And $objBestHost.GetType() displays:

IsPublic: True
IsSerial: False
Name: VMHostImpl
BaseType: VMware.VimAutomat...

Hope this helps.

0 Kudos
hugopeeters
Hot Shot
Hot Shot
Jump to solution

You should be able to get the correct VMHost in a single step. Let me try it off the top of my head (not near any powershell VI toolkit right now):

If MYCLUSTER is the cluster you want to look in, use:

$cluster = Get-Cluster MYCLUSTER

$objBestHost = (Get-VMHost -Location $cluster | Add-Member -MemberType ScriptProperty -Name NumVMs -Value {(Get-VM -VMHost $_ | Measure-Object).Count} -Passthru | Sort NumVMs)[0]

{noformat]{code}

Edit: Not descending, best host has least vms

0 Kudos
GuruAnt
Contributor
Contributor
Jump to solution

When I try that, I get the following:

 Get-VMHost : Cannot bind parameter 'Location'. Cannot conv" to type "VMware.VimAutomation.Types.VIContainer". Error: "Invalid cast from 'System.String' to VMware.VimAutomation.Types.VIContainer'."


At line:1 char:37


+ $objBestHost = (Get-VMHost -Location  <<<< ++my_cluste | Add-Member -MemberType ScriptProperty -Name NumVMs -Value {(Get-VM -VMHost $_ | Measure-Object).Count} -Passthru | Sort NumVMs)[0]

As it's going into a script, I'm not too worried about it being a one-liner though. The multi-line from above works fine.

I've now got Ed Wilson's book, so I'm going through that trying to learn the basics. I'll give you credit for an answer on your second post though, as when you answered it the first time I only gave you a "helpful" as I had another problem!

0 Kudos