首页 > 解决方案 > Powershell 计算的分栏符表

问题描述

我有一个简单的 Powershell 脚本来从一组服务器收集磁盘信息:

$servers="ALPHA", "BRAVO", "CHARLIE", "DELTA", "ECHO", "FOXTROT", "GOLF", "HOTEL"

ForEach ($s in $servers)
{ 
 get-wmiobject win32_logicaldisk -ComputerName $s -Filter "Drivetype=3"| select @{n='Server '; e={$s}}, 
                                                                                DeviceID,
                                                                                @{n="Size [GB]";e={[math]::truncate($_.size / 1GB)}},  
                                                                                @{n="Free [GB]";e={[math]::truncate($_.freespace / 1GB)}}  
}

这会产生所需的输出:

Server       DeviceID Size [GB] Free [GB]
-------      -------- --------- ---------
ALPHA        C:             299       161
ALPHA        E:             499       201
BRAVO        C:             476       148
CHARLIE      C:             233        46
DELTA        C:             475        94
ECHO         C:             464       256
ECHO         S:             465       222
FOXTROT      C:             476       224
GOLF         C:             475       100
HOTEL        C:             476        50

我想在输出表中添加一个计算列,显示每个磁盘的空闲百分比,所以我添加, @{n="Free [%]";e={($_.freespace / $_.Size).ToString("P0")}}到我的选择列表中,因此生成的脚本是:

ForEach ($s in $servers)
{ 
        get-wmiobject win32_logicaldisk -ComputerName $s -Filter "Drivetype=3"| select @{n='Server '; e={$s}}, 
                                                                                       DeviceID,
                                                                                       @{n="Size [GB]";e={[math]::truncate($_.size / 1GB)}},  
                                                                                       @{n="Free [GB]";e={[math]::truncate($_.freespace / 1GB)}} , 
                                                                                       @{n="Free [%]";e={($_.freespace / $_.Size).ToString("P0")}} 
}

令我惊讶的是,它不只是在前一个输出表中添加一列,而是产生输出:

Server    : ALPHA
DeviceID  : C:
Size [GB] : 299
Free [GB] : 161
Free [%]  : 54%

Server    : ALPHA
DeviceID  : E:
Size [GB] : 499
Free [GB] : 198
Free [%]  : 40%

Server    : BRAVO
DeviceID  : C:
Size [GB] : 476
Free [GB] : 142
Free [%]  : 30%

Server    : CHARLIE
DeviceID  : C:
Size [GB] : 233
Free [GB] : 44
Free [%]  : 19%

Server    : DELTA
DeviceID  : C:
Size [GB] : 475
Free [GB] : 88
Free [%]  : 19%

Server    : ECHO
DeviceID  : C:
Size [GB] : 464
Free [GB] : 256
Free [%]  : 55%

Server    : ECHO
DeviceID  : S:
Size [GB] : 465
Free [GB] : 222
Free [%]  : 48%

Server    : FOXTROT
DeviceID  : C:
Size [GB] : 476
Free [GB] : 224
Free [%]  : 47%

Server    : GOLF
DeviceID  : C:
Size [GB] : 475
Free [GB] : 100
Free [%]  : 21%

Server    : HOTEL
DeviceID  : C:
Size [GB] : 476
Free [GB] : 46
Free [%]  : 10%

其中“二维表”格式完全丢失,以牺牲简洁的可读性为代价。

添加| Format-Table只会导致输出为:

Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
ALPHA        C:             299       161 54%     
ALPHA        E:             499       192 39%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
BRAVO        C:             476       137 29%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
CHARLIE      C:             233        45 19%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
DELTA        C:             475        78 16%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
ECHO         C:             464       256 55%     
ECHO         S:             465       222 48%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
FOXTROT      C:             476       224 47%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
GOLF         C:             475       100 21%     



Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
HOTEL        C:             476        42 9% 

而期望的输出是:

Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
ALPHA        C:             299       161 54%     
ALPHA        E:             499       192 39%     
BRAVO        C:             476       137 29%     
CHARLIE      C:             233        45 19%
DELTA        C:             475        78 16%
ECHO         C:             464       256 55%     
ECHO         S:             465       222 48%
FOXTROT      C:             476       224 47%
GOLF         C:             475       100 21%
HOTEL        C:             476        42 9% 

或者,甚至更好:

Server       DeviceID Size [GB] Free [GB] Free [%]
------------ -------- --------- --------- --------
ALPHA        C:             299       161 54%     
ALPHA        E:             499       192 39% 
------------ -------- --------- --------- --------
BRAVO        C:             476       137 29%
------------ -------- --------- --------- --------
CHARLIE      C:             233        45 19%
------------ -------- --------- --------- --------
DELTA        C:             475        78 16%
------------ -------- --------- --------- --------
ECHO         C:             464       256 55%     
ECHO         S:             465       222 48%
------------ -------- --------- --------- --------
FOXTROT      C:             476       224 47%
------------ -------- --------- --------- --------
GOLF         C:             475       100 21% 
------------ -------- --------- --------- --------
HOTEL        C:             476        42 9% 

我怎样才能获得这两种最后的输出格式之一?

标签: powershellselectformat

解决方案


此行为是由于 powershell 如何处理同一对象的多次写入(此处解释:https ://github.com/PowerShell/PowerShell/issues/2228 )。

我可以建议一个小的改变来解决这个问题:

$output = @()
ForEach ($s in $servers)
{ 
        $output += get-wmiobject win32_logicaldisk -ComputerName $s -Filter "Drivetype=3"| Select-Object  @{n='Server '; e={$s}}, 
                         DeviceID,
                         @{n="Size [GB]";e={[math]::truncate($_.size / 1GB)}},  
                         @{n="Free [GB]";e={[math]::truncate($_.freespace / 1GB)}} , 
                         @{n="Free [%]";e={($_.freespace / $_.Size).ToString("P0")}} 
}

$output | ft 

输出: 结果图像


推荐阅读