Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell hash containskey returns false incorrectly

I have a Powershell script which gets a list of Remote Desktop user sessions and puts them into a hash by 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)
}

I then can then dump the $userSessionByID in the PowerShell ISE

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       

The frustrating part is that $userSessionBySessionID.ContainsKey(4) returns false. What am I missing here? I've tried $userSessionBySessionID.ContainsKey("4") as well, but that also returns false.

like image 357
bpeikes Avatar asked Oct 18 '22 11:10

bpeikes


1 Answers

I think the issue may be that $userSession.SessionId.GetType() returns [UInt32]

In testing that is your issue exactly. Consider the following test where I create a hashtable using [UInt32].

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

Running $test.containskey(6) returns false as you have seen. I also get the same issue with $test.containskey("6"). However this returns true....

$test.containskey(6 -as [uint32])

Note: You don't need to use the -as operator here as you can just do a simple cast with [uint32]6 however if you are using variables that contain integers -as would be helpful.

The key itself can be near any object and containskey() is returning the correct result in all cases. Your hashtable does not have a key with the integer 6. Furthermore, [uint32] cannot be converted to [int] since it has a higher upper bound so a cast would not be possible. This would be a reason why PowerShell or the underlying .Net would not be doing an "automatic" cast. In practice I don't think this ever happens in this scenario.

Point is be sure you are type aware.

Same example as above except this time we are using integers.

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

$test.containskey(6)
True

$test.containskey("6")
False

I can reverse the findings when I create the keys with strings.

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

$test.containskey(6)
False

$test.containskey("6")
True
like image 158
Matt Avatar answered Oct 21 '22 03:10

Matt