有或没有代码块的组对象差异

Group-Object diffencies with or without code block

下面的代码生成 2 "identical" 哈希 table,但是在使用代码块分组的代码上我无法从键中获取项目。

$HashTableWithoutBlock = 
    Get-WmiObject Win32_Service | Group-Object State -AsHashTable
$HashTableWithBlock = 
    Get-WmiObject Win32_Service | Group-Object {$_.State} -AsHashTable

Write-Host "Search result for HashTable without using code block : " -NoNewline
if($HashTableWithoutBlock["Stopped"] -eq $null)
{
    Write-Host "Failed"
}
else
{
    Write-Host "Success"
}

Write-Host "Search result for HashTable with code block : " -NoNewline
if($HashTableWithBlock["Stopped"] -eq $null)
{
    Write-Host "Failed"
}
else
{
    Write-Host "Success"
} 

输出:

Search result for HashTable without using code block : Success
Search result for HashTable with code block : Failed

两个Hashtable有什么区别?

如何获取按代码块分组的第二个项目?

编辑:不仅仅是解决方法,我想知道是否可以使用 table lookup 检索我想要的项目,如果可以, 怎么样?

两个 Hashtable 的区别在于 $HashTableWithBlock 的密钥包含在 PSObject 中。问题是 PowerShell 在将 PSObject 传递给方法调用之前通常会对其进行解包,因此即使您拥有正确的密钥,您仍然不能将其传递给索引器。要解决此问题,您可以创建辅助 C# 方法,该方法将使用正确的对象调用索引器。另一种方法是使用反射:

Add-Type -TypeDefinition @'
    public static class Helper {
        public static object IndexHashtableByPSObject(System.Collections.IDictionary table,object[] key) {
            return table[key[0]];
        }
    }
'@
$HashTableWithBlock = Get-WmiObject Win32_Service | Group-Object {$_.State} -AsHashTable
$Key=$HashTableWithBlock.Keys-eq'Stopped'
#Helper method
[Helper]::IndexHashtableByPSObject($HashTableWithBlock,$Key)
#Reflection
[Collections.IDictionary].InvokeMember('','GetProperty',$null,$HashTableWithBlock,$Key)

这是我找到的一个解决方法,它真的不是很好:

$HashTableWithBlock = 
    Get-WmiObject Win32_Service | ForEach-Object -Process {
        $_ | Add-Member -NotePropertyName _StateProp -NotePropertyValue $_.State -Force -Passthru
    } |
    Group-Object -Proerty _StateProp -AsHashTable

我的意思是,我想一旦你做了 ForEach-Object 你几乎还不如自己构建一个哈希表?

请注意,有趣的是,如果您改为在 ScriptProperty 上分组,这将 不会 起作用。我还没弄明白为什么。

其他张贴者是正确的,问题是密钥存储为 PSObject 但有一个内置的解决方案:使用 -AsString 开关和 -AsHashTable.这将强制将密钥存储为字符串。你可以看看代码here

我已经在 GitHub 上为这个错误打开了一个 issue