下面的代码生成2个“相同”的Hashtables,但是在使用代码块分组的代码块中,我无法从密钥中获取项目。
$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
两个Hashtables有什么区别?
如何获取按代码块分组的第二个项目?
编辑:不仅仅是一种解决方法,我想知道是否可以通过表格查找检索我想要的项目,如果是,那该怎么办?
答案 0 :(得分:4)
两个Hashtable
之间的区别在于$HashTableWithBlock
将其密钥包含在PSObject
中。问题是PowerShell在将它传递给方法调用之前通常会解开PSObject
,所以即使你有正确的密钥,你仍然不能将它传递给索引器。要解决此问题,您可以创建帮助程序C#方法,该方法将使用正确的对象调用indexer。另一种方法是使用反射:
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)
答案 1 :(得分:0)
这是我发现的一种解决方法,实际上并不是很好:
$HashTableWithBlock =
Get-WmiObject Win32_Service | ForEach-Object -Process {
$_ | Add-Member -NotePropertyName _StateProp -NotePropertyValue $_.State -Force -Passthru
} |
Group-Object -Proerty _StateProp -AsHashTable
我的意思是,我猜你曾经做过ForEach-Object
,你几乎可以自己建立一个哈希表吗?
请注意,有趣的是,如果您在ScriptProperty上进行分组,这将不。我还没弄清楚原因。