You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:20:26