Den*_*nis 4 powershell hashtable pscustomobject
PowerShell 中的某些哈希表(例如使用 导入的Import-PowerShellDataFile哈希表)如果改为 PSCustomObject,则导航起来会容易得多。
@{
AllNodes = @(
@{
NodeName = 'SRV1'
Role = 'Application'
RunCentralAdmin = $true
},
@{
NodeName = 'SRV2'
Role = 'DistributedCache'
RunCentralAdmin = $true
},
@{
NodeName = 'SRV3'
Role = 'WebFrontEnd'
PSDscAllowDomainUser = $true
PSDscAllowPlainTextPassword = $true
CertificateFolder = '\\mediasrv\Media'
},
@{
NodeName = 'SRV4'
Role = 'Search'
},
@{
NodeName = '*'
DatabaseServer = 'sql1'
FarmConfigDatabaseName = '__FarmConfig'
FarmContentDatabaseName = '__FarmContent'
CentralAdministrationPort = 1234
RunCentralAdmin = $false
}
);
NonNodeData = @{
Comment = 'No comment'
}
}
Run Code Online (Sandbox Code Playgroud)
导入后它将成为哈希表的哈希表
$psdnode = Import-PowerShellDataFile .\nodefile.psd1
$psdnode
Name Value
---- -----
AllNodes {System.Collections.Hashtable, System.Collect...
NonNodeData {Comment}
$psdnode.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
Run Code Online (Sandbox Code Playgroud)
当按属性名称导航时,数据结构会很奇怪。
mkl*_*nt0 12
现有答案中有很好的信息,但考虑到您问题的通用标题,让我尝试系统概述:
您不需要将哈希表转换为[pscustomobject]实例,以便使用点表示法深入了解其条目(属性),如评论中所讨论的以及iRon 的答案中所演示的。
一个简单的例子:
@{ top = @{ nested = 'foo' } }.top.nested # -> 'foo'
Run Code Online (Sandbox Code Playgroud)
请参阅此答案以获取更多信息。
事实上,在可能的情况下,使用哈希表比使用 s更可取[pscustomobject],因为:
[pscustomobject](使用更少的内存)笔记:
上面的内容不仅适用于类型[hashtable],更普遍地适用于实现[System.Collections.IDictionary]接口或其通用对应物的类型实例,System.Collections.Generic.IDictionary[TKey, TValue]]特别是包括有序哈希表(它们是类型的实例,PowerShell允许您使用语法糖System.Collections.Specialized.OrderedDictionary构造它)。 [ordered] @{ ... }
除非另有说明,下一节中的哈希表指的是所有此类类型。
如果您确实需要将 a 转换[hasthable]为 a[pscustomobject]:
虽然许多标准 cmdlet 接受[hasthable]s与s互换[pscustomobjects],但有些 cmdlet不接受 s ,特别是ConvertTo-Csvand (有关更改这一点的功能请求,Export-Csv请参阅GitHub 问题 #10999 );在这种情况下,[pscustomobject]必须转换为。
警告:Hastables 可以有任何类型的键,而转换[pscustomobject]总是需要使用字符串“keys”,即属性名称。因此,并非所有哈希表都可以忠实地或有意义地转换为[pscustomobject]s。
将非嵌套哈希表转换为[pscustomobject]:
PowerShell 为[pscustomobject]文字提供的语法糖(例如[pscustomobject] @{ foo = 'bar'; baz = 42 })也可以通过预先存在的哈希来工作;例如:
$hash = @{ foo = 'bar'; baz = 42 }
$custObj = [pscustomobject] $hash # Simply cast to [pscustomobject]
Run Code Online (Sandbox Code Playgroud)
将嵌套哈希表(即对象图)转换为[pscustomobject]图:
您自己的答案中显示了一种简单但有限且可能昂贵的解决方案:使用 将哈希表转换为 JSON ConvertTo-Json,然后使用 将生成的 JSON 重新转换为[pscustomobject]图表ConvertFrom-Json。
Import-PowerShellDataFile,但给定的哈希表可能包含在 JSON 中没有有意义表示的类型实例。您可以使用自定义转换函数ConvertFrom-HashTable来克服此限制(源代码如下);例如(用 检查结果Format-Custom -InputObject $custObj):
$hash = @{ foo = 'bar'; baz = @{ quux = 42 } } # nested hashtable
$custObj = $hash | ConvertFrom-HashTable # convert to [pscustomobject] graph
Run Code Online (Sandbox Code Playgroud)
ConvertFrom-HashTable源代码:
注意:尽管有这个名称,该函数通常支持作为输入实现的类型实例IDictionary。
function ConvertFrom-HashTable {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[System.Collections.IDictionary] $HashTable
)
process {
$oht = [ordered] @{} # Aux. ordered hashtable for collecting property values.
foreach ($entry in $HashTable.GetEnumerator()) {
if ($entry.Value -is [System.Collections.IDictionary]) { # Nested dictionary? Recurse.
$oht[[object] $entry.Key] = ConvertFrom-HashTable -HashTable $entry.Value # NOTE: Casting to [object] prevents problems with *numeric* hashtable keys.
} else { # Copy value as-is.
$oht[[object] $entry.Key] = $entry.Value
}
}
[pscustomobject] $oht # Convert to [pscustomobject] and output.
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7811 次 |
| 最近记录: |