将对象数组转换为哈希表时出错

Error converting object array to hashtable

快速概述:脚本有两个功能,一个获取两个角色列表并将它们放入散列 table,然后 returns 散列 table。 Process-Roles 然后接受一个散列 table,并对其进行一些比较。

$RoleTable 应该是一个散列 table,但我认为在我的 Get-Roles 函数之后,Powershell 使 $RoleTable 成为一个对象数组。然后我得到一个转换错误:

Cannot convert the "System.Object[]" value of type "System.Object[]" to type 
"System.Collections.Hashtable".

这是我的脚本"main"

$creds = Get-Credential
$MasterServer = Read-Host "`n Master Server"
$SlaveServer  = Read-Host "`n Slave Server"

$RoleTable = Get-Roles -MasterServer $MasterServer -SlaveServer $SlaveServer -Credential $creds

Process-Roles -RoleTable $RoleTable

这是我在其中创建散列table 并将其传递给 $RoleTable

的函数
function Get-Roles {
    Param(
        [Parameter(Mandatory=$True,Position=0)]
        [string]$MasterServer,

        [Parameter(Mandatory=$True,Position=1)]
        [string]$SlaveServer,

        [Parameter(Mandatory=$True,Position=2)]
        [pscredential]$Credential
    )

    $DiscoveredRoles = @{}

    # Get Master Roles
    Connect-VIServer $MasterServer -Credential $Credential | out-null
    $DiscoveredRoles["MasterRoles"] = Get-VIRole
    Disconnect-VIServer $MasterServer -Confirm:$false

    #Get Slave Roles
    Connect-VIServer $SlaveServer -Credential $Credential | out-null
    $DiscoveredRoles["SlaveRoles"] = Get-VIrole
    Disconnect-VIServer $SlaveServer -Confirm:$false

    Write-Verbose "`n + Retrieved Roles Successfully"

    return $DiscoveredRoles

}    

这里是错误发生的地方。 Process-Roles 需要哈希table,但我相信 powershell 将 $RoleTable 转换为数组? (至少我的 google-fu 是这么告诉我的)

function Process-Roles { 
    param(
        [Parameter(Mandatory=$true)]
        [ValidateScript({ $_.ContainsKey("MasterRoles") -and $_.ContainsKey("SlaveRoles") })]
        [hashtable]$RoleTable
    )

    $MasterRoleNames = $RoleTable["MasterRoles"] |Select-Object -ExpandProperty Name

    $SlaveRoleNames = $RoleTable["SlaveRoles"] |Select-Object -ExpandProperty Name

    $MasterRoleNames |Where-Object { $SlaveRoleNames -notcontains $_ } |ForEach-Object {
        Write-Verbose "$_ doesn't exist on slave"    
    }

    $SlaveRoleNames |Where-Object { $MasterRoleNames -notcontains $_ } |ForEach-Object {
        Write-Verbose "$_ doesn't exist on Master"    
    }

    Write-Verbose "`n + Processed Roles Successfully"
}

当有多个值时,PowerShell 函数 return 是一个数组 returned。 return 未被忽略且未分配给变量的值的函数中的每个语句都对 return 值有贡献。

我看到了 Connect-VIServer return 的东西。因此 Get-Roles 将 return 多个值:包括对 Connect-VIServer.

的两次调用中的两个

如果您不想要这些其他语句中的值,则需要明确删除它们。例如。通过管道进入 out-null.

例如。 (感谢 @MathiasRJessen):

Connect-VIServer $SlaveServer -Credential $Credential | Out-Null

正如@Richard 指出的那样,如果您不想看到它被写入管道,则需要抑制 cmdlet 的输出。

除了通过管道传输到 Out-Null 之外,还有其他方法可以抑制输出:

显式转换为 void:

[void](Connect-VIServer $SlaveServer -Credential $Credential)

未经检查转换为 void

(Connect-VIServer $SlaveServer -Credential $Credential) -as [void]

分配给$null

$null = Connect-VIServer $SlaveServer -Credential $Credential

重定向到 $null:

Connect-VIServer $SlaveServer -Credential $Credential > $null