Powershell 哈希 containskey 错误地返回 false

bpe*_*kes 5 powershell hash

我有一个 Powershell 脚本,它获取远程桌面用户会话列表,并通过 SessionID 将它们放入散列中。

# Create a hashtable which contains all of the remote desktop sessions by SessionId
$userSessionBySessionID = @{}
ForEach($userSession in Get-RDUserSession -CollectionName $collectionName)
{
    $userSessionBySessionID.Add($userSession.SessionId, $userSession)
}
Run Code Online (Sandbox Code Playgroud)

然后我可以在 PowerShell ISE 中转储 $userSessionByID

Name                           Value                                                                                                                                                                                                          
----                           -----                                                                                                                                                                                                          
9                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
8                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
7                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
6                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
5                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
4                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
2                              Microsoft.RemoteDesktopServices.Management.RDUserSession                                                                                                                                                       
1                              Microsoft.RemoteDesktopServices.Management.RDUserSession       
Run Code Online (Sandbox Code Playgroud)

令人沮丧的部分是 $userSessionBySessionID.ContainsKey(4) 返回 false。我在这里缺少什么?我也试过 $userSessionBySessionID.ContainsKey("4") ,但也返回 false。

Mat*_*att 3

我认为问题可能在于$userSession.SessionId.GetType()返回[UInt32]

在测试中这正是你的问题。考虑以下测试,我使用创建哈希表[UInt32]

$test = @{}
1..10 | %{$test.add($_ -as [uint32],$_%2)}
Run Code Online (Sandbox Code Playgroud)

$test.containskey(6)如您所见,运行返回 false。我也遇到同样的问题$test.containskey("6")。然而这返回 true......

$test.containskey(6 -as [uint32])
Run Code Online (Sandbox Code Playgroud)

注意:您不需要-as在此处使用运算符,因为您只需执行简单的转换即可[uint32]6,但是如果您使用包含整数的变量-as会很有帮助。

密钥本身可以靠近任何对象,并且containskey()在所有情况下都会返回正确的结果。您的哈希表没有整数6 的键。此外,[uint32]无法转换为整数 6 [int],因为它具有更高的上限,因此无法进行强制转换。这就是为什么 PowerShell 或底层 .Net 不会进行“自动”转换的原因。实际上,我认为这种情况不会发生。

要点是确保您具有类型意识。

与上面的示例相同,只是这次我们使用整数。

1..10 | %{$test.add($_,$_%2)}

$test.containskey(6)
True

$test.containskey("6")
False
Run Code Online (Sandbox Code Playgroud)

当我用字符串创建键时,我可以逆转结果。

1..10 | %{$test.add("$_",$_%2)}

$test.containskey(6)
False

$test.containskey("6")
True
Run Code Online (Sandbox Code Playgroud)