Question:
I have a Powershell script which gets a list of Remote Desktop user sessions and puts them into a hash by SessionID.
1 2 3 4 5 6 7 |
# 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
1 2 3 4 5 6 7 8 9 10 11 |
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.
Answer:
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]
.
1 2 3 |
$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….
1 2 |
$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 2 3 4 5 6 7 8 |
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 2 3 4 5 6 7 8 |
1..10 | %{$test.add("$_",$_%2)} $test.containskey(6) False $test.containskey("6") True |