cloning VDI - specify specific host

by Symbiot at 2012-09-28 03:36:20


I’ve created a script to clone a vdi template machine…
it checks the hosts available and selects the best one each time I run the script.
however… before I had 3 servers serving as hosts… now I have only one…
but the script cannot accept less than 2 hosts… because it uses an array to check…
but I must admit I just use powershell… I don’t really understand it that good… so I’m actually a bit stumped as to why I can’t get it to work…

but perhaps you can skim through the code, and offer a solution…

## Importer vmm cmdlets
add-pssnapin microsoft.systemcenter.virtualmachinemanager

## henter vmm serveren, og bruger denne som default igennem scriptet. Den printer også info på skærmen.
get-vmmserver -computerName “”

$VMHostGroup = Get-VMHostgroup -Name “vdi”
$HWProfile = Get-HardwareProfile | Where {$.Name -eq “Windows 7 Default”}
$vmNicArray = @()
$VM = Get-VM | where {$
.Name -eq “”}

#$BestHost = Get-VMHostRating -VMHostgroup $VMHostGroup -HardwareProfile $HWProfile -DiskSpaceGB 25 -VMName New | where {$.rating -gt 0} | sort-object -property rating -descending
#$currentHost = get-vmhost | where {$
.name -eq $BestHost[0].name}
#$currentHost = get-vmhost | where {$.name -eq $}

#hack to use only hv15
$currentHost = get-vmhost | where {$
.name -eq “”}

#new-vm -Name “$[PcName]” -vm $vm -VMHost $currentHost -path $currentHost.vmpaths[0] -OperatingSystem “Windows 7” -Owner “hostname_NT\admin” -RunAsSystem -StartAction NeverAutoTurnOnVM -UseHardwareAssistedVirtualization $true -StopAction SaveVM
new-vm -Name “$[PcName]” -vm $vm -VMHost $currentHost -path $currentHost.vmpaths -OperatingSystem “Windows 7” -Owner “hostname_NT\admin” -RunAsSystem -StartAction NeverAutoTurnOnVM -UseHardwareAssistedVirtualization $true -StopAction SaveVM

$currentVm = get-vm | where {$.name -eq “$[PcName]”}
$Adapter = Get-VirtualNetworkAdapter -VM $currentVM

Set-VirtualNetworkAdapter -VirtualNetworkAdapter $Adapter -PhysicalAddressType Dynamic -VirtualNetwork “VM-LAN” -VLanEnabled $true -VLanID 4026 -VMNetworkOptimizationEnabled $false -MACAddressesSpoofingEnabled $false

set-VM -vm $currentVm -BootOrder “PxeBoot”,“CD”,“IdeHardDrive”,“Floppy” -MemoryMB 1024

start-vm -vm $currentVm
by poshoholic at 2012-09-28 06:53:53
Hello and welcome to! I should be able to help you out, but I’d like a little more information about the specific issue you are having with your script. Sharing your script is a great first step, but I also need to see any errors that it returns because those will highlight where I should start looking at your script. Also, when you talk about using 3 servers in an array and now only using 1, are you referring to the line in your script that is marked with “#hack”?

While I’m waiting for the additional details, I’ll quickly point out one thing. In PowerShell 2, if you are retrieving something from a command or a pipeline and you want to make sure that you always have an array in the end, even if you only retrieve one item, you can simply wrap it in array enclosures. For example, let’s say I’m retrieving services and my script uses an array of services, like this:
$services = Get-Service
# Do something with $services as a collection here

If later on that changes, so that I’m only retrieving one service, my script may break if it was expecting an array. To avoid that risk, when I expect to get an array, I force it, like this:
$services = @(Get-Service wuauserv)
# Now services is still a collection, like I expect in my script, even when I only get one item back.

This is only an issue in PowerShell 1 and 2. In PowerShell 3, they made PowerShell smart enough to allow you to work with a single item as a collection so you don’t need to do the wrapping. I think it’s still a good practice to wrap a collection with array enclosures though because that identifies the expectation.

Also, I have a blog post about this that might help. Here’s the link:
by Symbiot at 2012-09-28 07:09:29

I’ll quickly post the error, then try to answer your other questions… :slight_smile:

New-VM : Cannot convert ‘System.Object[]’ to the type ‘Microsoft.SystemCenter.V
irtualMachineManager.Host’ required by parameter ‘VMHost’. Specified method is
not supported.
At line:23 char:59
+ new-vm -Name “” -vm $vm -VMHost <<<< $currentHost
-path $currentHost.vmpaths -OperatingSystem “Windows 7” -Owner “hostname_NT\admin” -R
unAsSystem -StartAction NeverAutoTurnOnVM -UseHardwareAssistedVirtualization $t
rue -StopAction SaveVM
+ CategoryInfo : InvalidArgument: (:slight_smile: [New-VM], ParameterBindingE
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.SystemCenter.Vir
by poshoholic at 2012-09-28 07:29:08
That error message is telling you that your $currentHost variable is an array of objects, and the -VMHost parameter is expecting a single Microsoft.SystemCenter.VirtualMachineManager.Host object. This means you need to verify that $currentHost contains what you expect it to contain. If you run your script up to and including line 19, where you assign a value to $currentHost, you should then be able to check to see what $currentHost contains as well as what type of object $currentHost is. For example, you want to run the following commands once $currentHost is assigned a value:
$currentHost.GetType().FullName # If this does not return Microsoft.SystemCenter.VirtualMachineManager.Host, that’s problem #1
$currentHost # This will show what $currentHost contains
$currentHost.Count # Since PowerShell is telling you that $currentHost is an array, this will tell you how many items you have in your array
$currentHost[0].GetType().FullName # This will tell you the type of object you have in your array

These commands should help you see what is happening so that you can identify what needs to change in your script to make this work. If you don’t know what to do with the results of those commands, share them here and I can help.
by Symbiot at 2012-10-01 04:53:06
hi poshoholic…

I’ve run the commands you suggested…
#1 - PS C:\windows> $currenthost.gettype().fullname

#2 - runturns all info on the 1 host it contains (lotsa info that’s pointless to post here…)

#3 - returns nothing… nothing happens
PS C:\windows> $currenthost.count

#4 - gives an error…
PS C:\windows> $currenthost[0].gettype().fullname
Unable to index into an object of type Microsoft.SystemCenter.VirtualMachineManage
At line:1 char:14
+ $currenthost[ <<<< 0].gettype().fullname
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : CannotIndex

so it’s an array with only 1 “entry”… how can I just use a single host variable?
by poshoholic at 2012-10-01 05:26:34
Based on that output, your $currentHost variable looks just fine.

Next question: why do you pass in the Paths array instead of just the first item like you were doing in your commented-out line of script?
#new-vm -Name “$[PcName]” -vm $vm -VMHost $currentHost -path $currentHost.vmpaths[0] -OperatingSystem “Windows 7” -Owner “hostname_NT\admin” -RunAsSystem -StartAction NeverAutoTurnOnVM -UseHardwareAssistedVirtualization $true -StopAction SaveVM
new-vm -Name “$[PcName]” -vm $vm -VMHost $currentHost -path $currentHost.vmpaths -OperatingSystem “Windows 7” -Owner “hostname_NT\admin” -RunAsSystem -StartAction NeverAutoTurnOnVM -UseHardwareAssistedVirtualization $true -StopAction SaveVM

If you uncomment the first line (and fix the VM name) and run that one instead, do you still get the issue?

Note: I don’t have an SCVMM 2008 environment handy to test this out, so I need to rely on the answers I get from these questions that I would ask myself if troubleshooting it locally.