Estet
Estet

Reputation: 146

Powershell doesn't return key value in hashtable

PS C:\Users\kris> $hashx=@{}
PS C:\Users\kris> $(Get-CimInstance Win32_Process | Select-Object ProcessId, Name) | ForEach-Object { $hashx[$_.ProcessId]=$_.Name }
PS C:\Users\kris> $hashx
    
    Name                           Value
    ----                           -----
    1292                           svchost.exe
    6032                           StartMenuExperienceHost.exe
    428                            smss.exe
    4736                           powershell.exe
    2580                           svchost.exe
    5628                           explorer.exe
    5164                           taskhostw.exe
PS C:\Users\kris> $hashx['5164']
PS C:\Users\kris> $hashx.5164
PS C:\Users\kris> $hashx."5164"
PS C:\Users\kris> $hashx.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

Can anyone explain me what i do wrong? i'm beginner in powershell, and i don't understand why it returns null value by key?

Upvotes: 1

Views: 917

Answers (1)

AdminOfThings
AdminOfThings

Reputation: 25001

Get-CimInstance Win32_Process returns ProcessId property as type System.UInt32. You will need to cast your key retrieval values to that type or convert the ProcessId values to System.Int32. The reason is by default the shell interprets unquoted or uncast whole numbers as System.Int32 provided the number is less than or equal to [int32]::maxvalue or System.Int64 otherwise.

In your case, you can simply use the syntax below if you don't mind working with Uint32:

$hashx[[uint32]5164]

Personally, I would convert the ProcessId value to System.Int32 (using accelerator [int]) when adding it to the hash table:

Get-CimInstance Win32_Process |
    Select-Object ProcessId, Name | ForEach-Object {
        $hashx[[int]$_.ProcessId] = $_.Name 
    }

# Now the keys can be accessed using Int32 numbers
$hashx[5164]

As an aside, you can discover property types yourself with the Get-Member command:

Get-CimInstance win32_Process | 
    Select -First 1 -Property ProcessId | Get-Member


   TypeName: Selected.Microsoft.Management.Infrastructure.CimInstance

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
ProcessId   NoteProperty uint32 ProcessId=0

Notice the definition of ProcessId shows type uint32.

Upvotes: 5

Related Questions