I am writing a script to administer Hyper-VMs using the PowerShell Management Library for Hyper-V. Since we are using several Hyper-V Hosts and our VMs can change their host for performance reasons or other reasons I need a script that finds out which Host a VM runs on for the following functions.
This was my try at accomplishing this:
function IdentifyHost
{
param
(
[parameter(Position=0, Mandatory = $true)]
[ValidateNotNullOrEmpty()]
$VM
)
[Array]$hosts=Get-VMHost
if ($hosts.count -eq 0)
{
Write-Warning "No valid hosts found."
}
for ([int]$i=0; $i -lt $hosts.count; $i++ )
{
try
{
$out = Get-VM -Name $VM -Server $hosts[$i] -ErrorAction Stop
}
catch [UnauthorizedAccessException]
{
Write-Warning "Access to $hosts[$i] denied."
}
if ($VM -is [String])
{
if ($out.VMElementName -eq $VM )
{
return $out.__SERVER
}
}
elseif ($VM.ElementName -ne $null)
{
if ($out.VMElementName -eq $VM.VMElementName)
{
return $out.__SERVER
}
}
}
Write-Warning "No Host found for $VM"
}
Get-VMHost returns an array of all available Hyper-V hosts in the local area network. My problem is that my function always returns the first element of the $hosts array whenever there is an UnauthorizedAccessException for the first element.
The plan is as following: If the VM exists on the Host he will return a WMI Object representing that VM whose VMElementName property is equal to the VMs name given as parameter. If the VM is given a WMI Object representing a VM the VMElementName properties of the two objects are equal. If the VM does not exist on the Host he returns nothing. If there's an access issue it should be catched.
But somehow it doesn't work out.
My question is this: What am I doing wrong in the code? And how can I fix it?
EDIT: The output of the function is the access problem warning for the first element of the $hosts array and then the first element of $hosts itself.
EDIT2: I fixed this myself by changing the return from the fragile $hosts[$i] to $out.__Server