Таблица расчётов столбцов в Powershell - PullRequest
1 голос
/ 24 февраля 2020

У меня есть простой скрипт 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% 

Как Могу ли я получить один из этих двух последних форматов вывода?

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

, который, к моему удивлению, не просто добавляет столбец к предыдущей выходной таблице

Поскольку дополнительное вычисляемое свойство делает ваши выходные объекты более чем 4 свойствами , PowerShell автоматически переключается с табличного (подразумевается Format-Table на список (подразумевается Format-List) отображения (это поведение по умолчанию для объектов, которые не имеют предопределенный формат данных связан с ними). ​​

Добавление | Format-Table просто приводит к выводу:

Причина кратная отображаются заголовки: вы вызываете Format-Table для каждого вызова устаревшего командлета [1] get-wmiobject вместо применения single Format-Table вызов комбинированного выхода l oop.

Самое простое решение - использовать командлет ForEach-Object в конвейер вместо foreach l oop оператор :

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

Обратите внимание на использование of automati c variable $_ для обозначения входного объекта под рукой.

Если вы хотите использовать foreach l oop, оберните его в & { ... } | Format-Table


[1] Обратите внимание, что командлеты CIM (например, Get-CimInstance) заменили командлеты WMI (например, Get-WmiObject) в PowerShell v3 (выпущен в сентябре 2012 г.). Поэтому следует избегать командлетов WMI, не в последнюю очередь потому, что PowerShell Core , где все будущие усилия будут go, даже не будет их больше. Для получения дополнительной информации см. этот ответ .

1 голос
/ 24 февраля 2020

Это происходит из-за того, что 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 

вывод: result image

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...