我将总结并补充PetSerAl和Ansgar Wiechers的有用评论:
太长没看(tl;dr):
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pclist |
Sort-Object CSName |
Format-Table CSName, LastBootUpTime -AutoSize
-AutoSize
确保 CSName
(计算机名称)列的宽度足以显示所有值(除非这些值本身太长而无法放在单行上,此时必须使用 -Wrap
- 参见下文)。
Get-CimInstance
接受一个计算机名称的 数组,因此不需要循环;但是,由于目标计算机是 并行查询 的,返回的对象顺序通常不会与计算机名称的输入顺序匹配 - 这可以通过调用 Sort-Object CSName
来纠正。
要控制各个列的宽度:
# Instead of a simple property name, 'prop1', pass a *hashtable*
# (@{ ... }`) with a 'width' entry to Format-Table
PS> [pscustomobject] @{ prop1='1234567890'; prop2='other' } |
Format-Table -Property @{ e='prop1'; width = 5 }, prop2
prop1 prop2
----- -----
1234… other
注意:在Windows PowerShell中,您将只看到被截断的值
12...
,因为它使用3个单独的
.
字符来表示截断; 在PowerShell [Core] 6+中改进为使用一个单一字符
…
(水平省略号,
U+2026
)。
阅读以下内容以了解更多有关表格式化的信息。
在本质上,您的问题是关于如何控制制表符输出的输出列宽度,这适用于任何cmdlet的输出。
对于制表符输出,请直接使用Format-Table cmdlet(而不是Select-Object):Select-Object的目的是创建自定义对象,而不是格式化输出;如果这样的对象(通常是没有预定义格式视图的任何类型的实例)恰好具有4个或更少的属性,则默认情况下会使用Format-Table进行格式化(但您无法应用选项);否则,隐式使用的是Format-List。感谢
PetSerAl。
Format-Table
invariably limits output lines to the available screen width, which means:
- Columns may not get printed at all.
- Especially the last column that is printed may have its values truncated, with the missing part indicated by
...
/ …
- though note that all printed columns can have truncated values, as explained below.
If you want to create longer lines, pipe Format-Table
's output to | Out-File -Width <int>
or | Out-String -Stream -Width <int>
; note that if you print the latter to the screen, lines will wrap (but the extra line breaks won't be part of the data).
Caveat: On Windows PowerShell, do NOT use -Width ([int]::MaxValue)
, because table-formatted data for types with formatting data is unconditionally right-padded with spaces to the full width, which can consume inordinate amounts of memory / space in the output file and you may even run out of memory. In PowerShell Core, this has been fixed as of at least v6.1.
An alternative on Windows (does not work in PowerShell Core on Unix-like platforms) is to use [console]::BufferWidth = <column-count>
to widen the screen buffer to allow longer lines that don't wrap, but require horizontal scrolling.
Additionally, on Windows it only works in the regular console, not in the ISE.
To control column widths - which indirectly determines how many columns will fit - use the following parameters:
-AutoSize
... tells Format-Table
to make columns as wide as necessary to fit all data values, but note that this can result in fewer (less typically: more) columns getting displayed.
-Wrap
... makes column values span multiple lines, if needed, to avoid truncation; again, this can apply to all columnsThanks, zett42., not just the last one, namely in case an automatically determined or fixed column width (specified via a width
entry, as shown next) happens to be exceeded by specific values.
To specify custom column widths, pass a hashtable with a width
entry as an argument - a so-called calculated property to Format-Table
's -Property
parameter; e.g., the following example limits the 1st output column to 5 characters:
[pscustomobject] @{ prop1='1234567890'; prop2='other' } |
Format-Table -Property @{ e='prop1'; width = 5 }, prop2
If truncation occurs, which is applied to the end of values by default, the truncation indicator ...
/ …
invariably takes up the last 3 characters of the truncated value (in Windows PowerShell) / only the last character (in PowerShell [Core] 6+); in the example above, the prop1
value renders as 12...
/ 1234…
for a total of 5 chars.
To truncate the start of values instead, you must change the column to be right-aligned, with a alignment = 'right'
entry (default is 'left'
, 'center'
is the 3rd option; both of these truncate the end of values).
If you want to retain left alignment while still truncating at the start of values, you'll have to use a custom expression in a script block ({ ... }
) assigned to the e
(expression
) entry:
[pscustomobject] @{ prop1='1234567890'; prop2='other' } |
Format-Table -Property @{
n='prop1'; e={ $_.prop1 -replace '^.+(.{4})$', '…$1'}; width = 5
}, prop2
Note: Specifying at least one custom width means that you must explicitly enumerate all properties to output in the -Property
argument, even the ones that don't need custom widths.[1]
Caveats, as of PowerShell 7.1:
A bug prevents custom widths from taking effect unless the first column (also) has one; additionally, it never takes effect in the last column - see GitHub issue #14676.
As zett42 points out and demonstrates in this answer, if the first column is a calculated one that specifies a custom width, the remaining line width is evenly distributed among those remaining columns that do not themselves specify a column width, irrespective of how wide the values in those columns actually are - unless you also pass -AutoSize
. This unexpected behavior is discussed in GitHub issue #14677.
[1] 如zett42所指出,如果所有列都有相同的自定义宽度,则您可以在技术上绕过此要求,因为将属性名称字符串传递给e
(Expression
) 哈希表条目会被解释为通配符模式,因此字符串'*'
匹配所有属性名称; 例如:
[pscustomobject] @{ a=1; b=2 } | Format-Table @{ e='*'; width=10 }
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pclist | Format-Table csname, lastbootuptime -AutoSize
。 - user4003407Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pclist | Sort-Object csname -Ascending | Format-Table csname, lastbootuptime -AutoSize
。我这样做对吗?因为我收到了以下错误信息:Sort-Object: 找不到与参数名 'Ascending' 匹配的参数。
- screenslaverSort-Object
只有一个-Descending
参数。默认是升序排列,所以只需省略此参数即可。 - Ansgar WiechersGet-CimInstance
已经支持一次检查多台计算机,而且它是并行执行的,因此您不需要将此命令放入循环中。这样会导致结果失去顺序。 - user4003407