如何将PowerShell哈希表中的数组数据转换为结构化表格展示
问题:将Invoke-Command返回的数组型哈希表转换为结构化表格
我通过Invoke-Command而非ForEach获取了两台服务器的目录大小等数据,结果存储在每个元素均为数组的哈希表中:
PS> $table Name Value ---- ----- Size {2.72 GB, 5.18 GB} Computer {Server01, Server02} Count {363,765, 446,832}
我希望将结果展示为每行对应一台服务器的结构化表格:
Computer Count Size -------- ----- ---- Server01 363,765 2.72 GB Server02 446,832 4.18 GB
尝试执行$badmailtable | foreach {[PSCustomObject]$_}后仍未达到预期:
$badmailtable | foreach {[PSCustomObject]$_} Size Computer Count ---- -------- ----- {2.72 GB, 5.18 GB} {Server01, Server02} {363,765, 446,832}
我怀疑需要通过某种ForEach循环来生成目标表格,但不清楚该循环的对象是什么,特此求助。原始脚本如下:
$BadMailPath="D:\InetPub\mailroot\badmail" $QueuePath="D:\InetPub\mailroot\queue" $BadMailTable=@() $QueueTable=@() $Computers=@( [PSCustomObject]@{Server="Server01";Alias="SV01.anydomain.com"} [PSCustomObject]@{Server="Server02";Alias="SV02.anydomain.com"} ) Foreach ($Svr in $Computers) {Write-Color "Retrieving ",$Svr.Server," contents ",$Svr.Alias White,Yellow,White,Green} $ScriptBlock = {param ($ParamPath) Get-ChildItem -path $ParamPath -recurse -force -erroraction silentlycontinue | Measure-Object -property Length -sum | Select-Object Sum,Count} $Params = @{ 'Computer'=$Computers.Server 'ScriptBlock'=$ScriptBlock 'Credential'=$ADCred 'ArgumentList'=$BadMailPath } $BadMailFolderSize = Invoke-Command @Params $Params = @{ 'Computer'=$Computers.Server 'ScriptBlock'=$ScriptBlock 'Credential'=$ADCred 'ArgumentList'=$QueuePath } $QueueFolderSize = Invoke-Command @Params
解决方案
方法1:直接利用Invoke-Command返回结果的内置属性
Invoke-Command返回的对象自带PSComputerName属性,无需额外构建哈希表,直接处理返回结果即可:
# 处理BadMail目录数据 $BadMailFolderSize | ForEach-Object { [PSCustomObject]@{ Computer = $_.PSComputerName Count = $_.Count Size = [math]::Round($_.Sum / 1GB, 2) | ForEach-Object { "$_ GB" } } } | Format-Table -AutoSize # 处理Queue目录数据同理 $QueueFolderSize | ForEach-Object { [PSCustomObject]@{ Computer = $_.PSComputerName Count = $_.Count Size = [math]::Round($_.Sum / 1GB, 2) | ForEach-Object { "$_ GB" } } } | Format-Table -AutoSize
方法2:针对已存在的数组型哈希表做索引匹配
如果已经有了$table这类哈希表,通过数组索引循环,将对应位置的元素组合为自定义对象:
for ($i = 0; $i -lt $table.Computer.Count; $i++) { [PSCustomObject]@{ Computer = $table.Computer[$i] Count = $table.Count[$i] Size = $table.Size[$i] } } | Format-Table -AutoSize
优化原始脚本(推荐)
直接在Invoke-Command的脚本块中生成结构化对象,避免后续转换麻烦:
$BadMailPath="D:\InetPub\mailroot\badmail" $QueuePath="D:\InetPub\mailroot\queue" $Computers=@( [PSCustomObject]@{Server="Server01";Alias="SV01.anydomain.com"} [PSCustomObject]@{Server="Server02";Alias="SV02.anydomain.com"} ) Foreach ($Svr in $Computers) {Write-Color "Retrieving ",$Svr.Server," contents ",$Svr.Alias White,Yellow,White,Green} $ScriptBlock = { param ($ParamPath) $measure = Get-ChildItem -path $ParamPath -recurse -force -ErrorAction SilentlyContinue | Measure-Object -property Length -sum [PSCustomObject]@{ Computer = $env:COMPUTERNAME Count = $measure.Count SizeGB = [math]::Round($measure.Sum / 1GB, 2) } } # 获取BadMail目录数据并直接格式化输出 $Params = @{ Computer = $Computers.Server ScriptBlock = $ScriptBlock Credential = $ADCred ArgumentList = $BadMailPath } Invoke-Command @Params | Select-Object Computer, Count, @{Name='Size'; Expression={"$($_.SizeGB) GB"}} | Format-Table -AutoSize # 获取Queue目录数据同理 $Params.ArgumentList = $QueuePath Invoke-Command @Params | Select-Object Computer, Count, @{Name='Size'; Expression={"$($_.SizeGB) GB"}} | Format-Table -AutoSize
内容的提问来源于stack exchange,提问作者Zeff Wheelock
相关产品推荐
相关产品推荐

