Problem with hashtable in function

Hi all!

I’m struggling to figure what am I doing wrong on this one…

I’m fairly new to Powershell scripting and I’m creating a function to get me the virtual machine current host. So far, so good, but…! I’m creating a new object (pretty simple one), but my ComputerName value is returning inside {}. Look at the code:

function Get-VMHostname{
[CmdletBinding()]
Param
(
# Computer names to query
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true, 
Position=0)]
[String[]]$ComputerName="Aries",

[System.Management.Automation.PSCredential]
$Credential 
)

Process{
if($Credential){
$VMhostname=Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock {(get-item "HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters").GetValue("HostName")}
$Prop=@{
'ComputerName'=$ComputerName;
'VMHostname'=$VMhostname
}
$Obj=New-Object -TypeName PSObject -Property $Prop 
Write-Output $Obj}

The output:

PS C:\Windows\system32> Get-VMHostname -ComputerName orion -Credential $cred

ComputerName VMHostname 
------------ ---------- 
{orion} Malin.microservicebnu.local

Can anyone help me?

Thanks in advance! (any tip/critic on general with this function is very welcome)

You allow for the $ComputerName in your param block to be an array of strings [String]. So your variable $ComputerName will likely be an array. Therefor the output will be an array as well. So you should change the variable type in your param block to a single string [String].

If you want to support multiple computers, you need to add a for loop to your code to loop through each of the computers:

function Get-VMHostname{
    [CmdletBinding()]
    param (
        [Parameter(
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true, 
            Position=0
        )]
        [String[]]$ComputerName="Aries",
        [System.Management.Automation.PSCredential]
        $Credential 
    )
    begin {}
    process{
        foreach ($computer in $ComputerName) {
            if($Credential){
                $VMhostname=Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock {(get-item "HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters").GetValue("HostName")}
                $Prop=@{
                    'ComputerName'=$Computer;
                    'VMHostname'=$VMhostname
                }
            
                $Obj = New-Object -TypeName PSObject -Property $Prop 

            }
        }
    }
    end{}
}

If you are using VMWare, the PowerCLI has cmdlet for this. Get-VMHost -VM <VMName> will return the host details for that VM. This cmdlet supports array of VMs, so a oneliner would be enough.

Thanks Olaf, i’ve got the problem now.

And yes Rob, the intention is to support multiple computers, I’ve tested your sugestion and it work like a charm. Much appreciated! :slight_smile:

 

Thanks for the information kvprasoon.

But no, it’s an Hyper-V enviroment.

Get-VM(Hyper-V module) output has a ComputerName property. You can try that as well.

Get-VM -Name $ComputerName | Select-Object ComputerName