问题
I am trying to get the last reboot time of some PCs from a list. When I use
foreach ($pc in $pclist) {
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pc |
select csname, lastbootuptime
}
The output comes as following.
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
Which is neat, but if the PC name is long, I am unable to see the full name.
So I pipelined Format-Table
:
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pc |
select csname, lastbootuptime |
Format-Table -HideTableHeaders
And this is what I get:
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
There are two problems here.
There is no heading. If I remove
-HideTableHeaders
there will be heading for every output which is not required.There is a lot of white spaces in between.
Basically I just need to get an output similar to the first one, but without truncating the full names. How can I fix these?
回答1:
To summarize and complement the helpful comments made by PetSerAl and Ansgar Wiechers:
tl;dr
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pclist |
Sort-Object CSName |
Format-Table CSName, LastBootUpTime -AutoSize
-AutoSize
is what ensures that the CSName
(computer name) column is as wide as it needs to be to show all values in full.
Get-CimInstance
takes an array of computer names, so there's no need for a loop; however, since the target computers are queried in parallel, the order of objects returned will typically not match the input order of computer names - this is rectified with the Sort-Object CSName
call.
Read on to learn more about table formatting.
At its core, your question is about how to control the output column width of tabular output, which applies to any cmdlet's output.
Use the Format-Table
cmdlet (directly) for tabular output, not Select-Object
: the purpose of Select-Object
is to create custom objects, not to format output; if such objects (generally, instances of any type without predefined formatting views) happen to haven 4 or fewer properties, they are by default formatted with Format-Table
behind the scenes (but you don't get to apply options); otherwise, it is Format-List
that is implicitly used. Thanks, PetSerAl.
Format-Table
invariably limits output lines to the available screen width, which means:- Columns may not get printed at all.
- The last column that is printed may have its value truncated, with the missing part indicated by
...
(though note that all printed columns can have truncated values).
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
... tellsFormat-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 the values of the last column printed span multiple lines, if needed, to avoid truncation.To specify custom column widths, pass a hashtable with a
Width
property as an element toFormat-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, the truncation indicator...
invariably takes up the last 3 characters of the truncated value; in the example above, theprop1
value renders as12...
for a total of 5 chars.
Also, 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.
回答2:
If you want trim data past a certain length and manually specify column widths, you can pass a Width
property for each property attribute.
For example, if you wanted your data to look like this:
Column 1 Column 2 Column 3 Column 4
-------- -------- -------- --------
Data Lorem ip... Lorem ip... Important data
Here's the basic Format-Table
syntax, with a list of explicit properties:
$data | Format-Table -Property Col1, Col2, Col3, Col4 -AutoSize
Instead of just passing in the property names, we can add some additional metadata to 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
Note: I realize this is covered at the bottom of mklement0's more complete answer, but if this is your use case and you're scrolling quickly, I hope this helps highlight this strategy at a high level
来源:https://stackoverflow.com/questions/38554966/controlling-column-widths-with-format-table