Управление шириной столбцов с помощью Format-Table

Я пытаюсь получить последнее время перезагрузки некоторых ПК из списка. Когда я использую

foreach ($pc in $pclist) {
  Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pc |
    select csname, lastbootuptime 
}

Выход поступает следующим образом.

csname       lastbootuptime
------       --------------
CONFA7-L1-1A 7/15/2016 9:55:16 AM
CONFA7-L1-1F 5/31/2016 8:51:46 AM
CONFA7-L1-1G 6/18/2016 11:09:15 AM
CONFA7-L1... 6/26/2016 5:31:31 PM
CONFA7-L3... 7/24/2016 3:48:43 PM

Что является опрятным, но если имя ПК длинное, я не могу увидеть полное имя. Поэтому я конвейерный Format-Table:

Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pc |
  select csname, lastbootuptime |
  Format-Table  -HideTableHeaders 

И это то, что я получаю:

CONFA7-L1-1A 7/15/2016 9:55:16 AM



CONFA7-L1-1E 7/21/2016 12:58:16 PM



CONFA7-L1-1F 5/31/2016 8:51:46 AM

Здесь есть две проблемы.

  1. Нет заголовка. Если я удалю -HideTableHeaders будет заголовок для каждого выхода, который не требуется.

  2. Между ними много белых промежутков.

В принципе, мне просто нужно получить результат, похожий на первый, но без обрезания полных имен. Как я могу это исправить?

Ответ 1

Подводя итог и дополняя полезные комментарии, сделанные PetSerAl и Ansgar Wiechers:

ТЛ; др

Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pclist |
  Sort-Object CSName |
    Format-Table CSName, LastBootUpTime -AutoSize

-AutoSize гарантирует, что CSName (имя компьютера) будет настолько широким, насколько это необходимо для отображения всех значений в полном объеме.

Get-CimInstance принимает массив имен компьютеров, поэтому цикл не нужен; однако, поскольку целевые компьютеры запрашиваются параллельно, порядок возвращаемых объектов обычно не будет соответствовать порядку ввода имен компьютеров - это исправляется с Sort-Object CSName вызова Sort-Object CSName.

Читайте дальше, чтобы узнать больше о форматировании таблицы.


По сути, ваш вопрос заключается в том, как управлять шириной выходного столбца табличного вывода, которая применяется к любому выводу командлета.

Используйте командлет Format-Table (напрямую) для табличного вывода, а не Select-Object: целью Select-Object является создание пользовательских объектов, а не форматирование вывода; если такие объекты (как правило, экземпляры любого типа без предопределенных представлений форматирования) имеют 4 или менее свойств, они по умолчанию отформатированы с помощью Format-Table за кулисами (но вы не можете применять параметры); в противном случае это неявно используемый Format-List. Спасибо, PetSerAl.

  • Format-Table неизменно ограничивает выходные строки доступной шириной экрана, что означает:

    • Столбцы могут вообще не печататься.
    • В последнем столбце, который печатается, его значение может быть усечено, а отсутствующая часть обозначена ... (хотя обратите внимание, что все напечатанные столбцы могут иметь усеченные значения).
  • Если вы хотите создать более длинные строки, Format-Table вывод Format-Table в | Out-File -Width <int> | Out-File -Width <int> или | Out-String -Stream -Width <int> | Out-String -Stream -Width <int>; обратите внимание, что если вы напечатаете последний на экране, строки будут перенесены (но дополнительные разрывы строк не будут частью данных).

    • Предупреждение: в Windows PowerShell НЕ используйте -Width ([int]::MaxValue), поскольку данные в формате таблицы для типов с данными форматирования безоговорочно дополняются пробелами до полной ширины, что может занимать чрезмерное количество памяти/пробел в выходном файле, и вы можете даже не хватает памяти. В PowerShell Core это было исправлено, по крайней мере, начиная с версии 6.1.

    • Альтернатива в Windows (не работает в PowerShell Core на Unix-подобных платформах) - использовать [console]::BufferWidth = <column-count> чтобы расширить экранный буфер, чтобы разрешить более длинные строки, которые не переносятся, но требуют горизонтального переноса прокрутки.
      Кроме того, на Windows это работает только в обычной консоли, а не в ISE.

  • Для управления шириной столбцов, которая косвенно определяет, сколько столбцов поместится, используйте следующие параметры:

    • -AutoSize... указывает Format-Table сделать столбцы настолько широкими, насколько это необходимо, чтобы соответствовать всем значениям данных, но учтите, что это может привести к тому, что будет отображаться меньше (реже: больше) столбцов.

    • -Wrap... заставляет значения последнего напечатанного столбца занимать несколько строк, если необходимо, чтобы избежать усечения.

    • Чтобы указать настраиваемую ширину столбца, передайте хеш Format-Table со свойством Width в качестве элемента параметру Format-Table -Property; например, следующий пример ограничивает первый выходной столбец 5 символами:
      [pscustomobject] @{ prop1='1234567890'; prop2='other' } | Format-Table -Property @{ e='prop1'; width = 5 }, prop2
      Если происходит усечение, индикатор усечения ... неизменно принимает последние 3 символа усеченного значения; в приведенном выше prop1 значение prop1 отображается как 12... для 5 символов.
      Кроме того, указание хотя бы одной настраиваемой ширины означает, что вы должны явно перечислить все свойства для вывода в аргументе -Property, даже те, которые не нуждаются в настраиваемой ширине.

Ответ 2

Если вы хотите обрезать данные за определенную длину и вручную указать ширину столбцов, вы можете передать свойство Width для каждого атрибута свойства.

Например, если вы хотите, чтобы ваши данные выглядели так:

Column 1    Column 2      Column 3      Column 4
--------    --------      --------      --------
Data        Lorem ip...   Lorem ip...   Important data

Вот основной синтаксис Format-Table со списком явных свойств:

$data | Format-Table -Property Col1, Col2, Col3, Col4 -AutoSize

Вместо того, чтобы просто передавать имена свойств, мы можем добавить некоторые дополнительные метаданные в Property:

$a = @{Expression={$_.Col1}; Label="Column 1"; Width=30}, 
     @{Expression={$_.Col2}; Label="Column 2"; Width=30}, 
     @{Expression={$_.Col3}; Label="Column 3"; Width=30}, 
     @{Expression={$_.Col4}; Label="Column 4"; Width=30}
$data | Format-Table -Property $a

Примечание. Я понимаю, что в нижней части mklement0 описан более полный ответ, но если это ваш вариант использования и вы быстро прокручиваете, я надеюсь, что это поможет выделить эту стратегию на высоком уровне.