Automating the world one-liner at a time…
<Edited 7/2/2006 with tags and categories>PSMDTAG:FAQ: Why doesn't output expand when I expand the width of the console?PSMDTAG:FAQ: Why doesn't output expand when I use -noElements on GROUP?
Consider the example:
PS> gps |group company
Count Name Group----- ---- ----- 34 Microsoft Corporation {alg, CcmExec, ctfmon, dsamain...} 1 Adobe Systems Incorpor... {apdproxy} 2 Alps Electric Co., Ltd. {ApntEx, Apoint} 4 {csrss, Idle, System, winlogon} 1 Alcor Micro, Corp. {DrvMon} 2 Microsoft (R) Corporation {FwcAgent, FwcMgmt} 3 Computer Associates In... {InoRpc, InoRT, InoTask} 1 Intel Corporation {ZCfgSvc}
Notice that the Company Name is truncated in the output. This blog will address 2 questions:
Let's review the basic model. In the Console host (PowerShell.exe), cmdlets emit objects which go to the out-default. Out-Default looks at the type of the object and looks for registered views for this type and calls the appropriate formatter. If you ever want to find the view defintion for the object you find the object's PSTypeNames then look for those entries in the *FORMAT.PS1XML files in $PSHOME. Note that the out-default will walk down the array of PSTypeNames until it finds a match so if you don't find a view for the first value in this array, search for the next.
PS> (gps |group company)[0].pstypenamesMicrosoft.PowerShell.Commands.GroupInfoSystem.ObjectPS> cd $pshomePS> Select-String Microsoft.PowerShell.Commands.GroupInfo *format.ps1xml
PowerShellCore.format.ps1xml:93: <Name>Microsoft.PowerShell.Commands.GroupInfo</Name>PowerShellCore.format.ps1xml:95: <TypeName>Microsoft.PowerShell.Commands.GroupInfo</TypeName>PowerShellCore.format.ps1xml:128: <Name>Microsoft.PowerShell.Commands.GroupInfoNoElement</Name>PowerShellCore.format.ps1xml:130: <TypeName>Microsoft.PowerShell.Commands.GroupInfoNoElement</TypeName>PowerShellCore.format.ps1xml:917: <Name>Microsoft.PowerShell.Commands.GroupInfo</Name>PowerShellCore.format.ps1xml:919: <TypeName>Microsoft.PowerShell.Commands.GroupInfo</TypeName>PowerShellCore.format.ps1xml:946: <Name>Microsoft.PowerShell.Commands.GroupInfoNoElement</Name>PowerShellCore.format.ps1xml:948: <TypeName>Microsoft.PowerShell.Commands.GroupInfoNoElement</TypeName>PS> Notepad PowerShellCore.Format.ps1xml
Here is that you'll find in PowerShellCore.Format.ps1xml:
<View> <Name>Microsoft.PowerShell.Commands.GroupInfo</Name> <ViewSelectedBy> <TypeName>Microsoft.PowerShell.Commands.GroupInfo</TypeName> </ViewSelectedBy>
<TableControl> <TableHeaders> <TableColumnHeader> <Label>Count</Label> <Alignment>Right</Alignment> <Width>5</Width> </TableColumnHeader> <TableColumnHeader> <Width>25</Width> </TableColumnHeader> <TableColumnHeader/> </TableHeaders> <TableRowEntries> <TableRowEntry> <TableColumnItems> <TableColumnItem> <PropertyName>Count</PropertyName> </TableColumnItem> <TableColumnItem> <PropertyName>Name</PropertyName> </TableColumnItem> <TableColumnItem> <PropertyName>Group</PropertyName> </TableColumnItem> </TableColumnItems> </TableRowEntry> </TableRowEntries> </TableControl></View>
What this is showing you is that you have a view which is selected by the groupinfo type, that this object should be rendered as a table, it defines the headers and the data for that table. Examine the TableHeaders section and you'll see that the first 2 TableColumnHeaders provide a LABEL and a WIDTH but the last one does not. When no LABEL is specified, the name of the property is used
PSMDTAG:PHILOSOPHY: - IT IS STRONGLY RECOMMENDED THAT YOU NEVER PROVIDE A LABEL. One of the great things about Windows PowerShell is its transparency and discoverability The views are critical to that. The output is what tells the user what properties they can expect to get from an object. If your label is different than the object, then you misset their expectations. We realized this after the fact otherwise there is a strong chance we would not have allowed you to use a LABEL. Now one of the reasons why you might be tempted to use a label is because in the data definitions, you might want to use a SCRIPT to calculate a value - THIS IS A BAD IDEA TOO [I know because I've stepped on that rake]. If you ever find yourself wanting to do this, the best thing to do is to extend the type itself with a scriptproperty and then specify that script property in formating.
The way formatting works is that it calculates the widths of the fields based upon the data in this view and the width of the console host. You can see this by doing a dir of some long names and then change your CONSOLE properties to vary the WIDTH of the console (this is under the LAYOUT TAB). Make it large and small and do the same diff every time and you'll see what I mean.
The formatter looks at the console width and then allocates the space explicitly reserved by the view (in this case Count reserves 5 spaces and Name reserves 25) and then allocates the remaining space evenly between all the other fields. This explains a couple of things:
You might think that specifying -NoElement on the group command will fix this. The GROUP command creates GroupInfo objects which give you a NAME (which is the VALUE of the property you are groupping by), the COUNT, and then the GROUP. The GROUP is an array of all the original elements (objects) that where grouped into this GroupInfo. There are lots of cases where that is really useful but it can be expensive so we provided the -NOELEMENT Switch which does not create this array. That said, we still emit a GROUPINFO object and thus it still binds the the same view and thus it still allocates 25 characters for the Name.
There are a couple of ways around this:
Enjoy!Jeffrey SnoverWindows PowerShell ArchitectPSMDTAG:CMDLET:FORMAT: truncating data, use of formatting metadataPSMDTAG:INTERNAL: How formating uses metadataPSMDTAG:CMDLET:FORMAT: How formating uses metadata
Summary: Solving issues with implementing a PowerShell script that generates PowerShell code with correct
PingBack from http://dmitrysotnikov.wordpress.com/2007/05/14/too-much-xml-formatting-for-powershell-is-a-bad-idea/
So I've run into a problem with this. It works fine with most objects to override by passing to FT or a custom view. However, if I have a list of items in a text file (one per line) and I pass it to the Group command, no amount of passing it to another view formatter seems to untruncate it.
In my case, I have a list of computer names gleaned from a log and I am trying to determine how many times each name appears in the log. I have trimmed out all the white space and empty lines. When I pass it to the group cmdlet, it correctly groups the names and provides a count...it just truncates the name of the computer whether I use -noelement or not and regardless of which format command I use.
If you would like more details or a detailed transaction log showing my steps, I would be happy to provide, just drop me an email to merddyn(at)email(dot)com. Any help is much appreciated as this seemingly simple task is starting to push my buttons.