PowerShell Formatting Deep Dive
Download
Report
Transcript PowerShell Formatting Deep Dive
Thomas Lee ([email protected])
MCT
PowerShell MVP
FORMATTING WITH POWERSHELL
MCT
PowerShell MVP
Worked with, trained and written about PowerShell
for years!
SME on 6434 and TR on 10325 official MOC classes
I have 25 copies of PowerShell Plus
http://www.idera.com/Products/PowerShell/PowerShell-
Plus/ or
http://tinyurl.com/psplus
To win:
You need to email me with a code word.
2. Email me at [email protected]
3. The code word will be at the end of the presentation
1.
Know a bit (or more) about PowerShell
At least to the level of the earlier Summit session!
You know what a cmdlet is, what the pipeline does and
what objects are
And you want to do more with formatting
If you want to type-along with me, feel free!
Formatting by default
Formatting using Format-table, Format-List
Using .NET format Strings
.ToString()
Formatting using Hash Tables
Formatting XML
Other output mechanisms
Some thoughts on style etc
PowerShell formats output by default
Useful for simple queries
Formatting is controlled by Format.PS1XML files
Seven are installed by default
LS $PSHOME\*.Format.PS1.XML
You can
You can edit built in Format.PS1XML files - but don’t…
Instead, add new ones and ‘install’ in Profile
The default formatting process
Cmdlet or
Pipeline
Out-Default
Format-Table or
Format-List
Formatted Output
On Console
User Defined Formatting
Cmdlet or
Pipeline
Format-Table or
Format-List
Out-Default
Formatted Output
On Console
Other Options
Out-Gridview
Cmdlet or
Pipeline
Cmdlets
Text, CSV, XML
Cmdlets take objects from pipeline – create table/list
Default contents and ‘shape’ determined by .ps1xml
You can override defaults, for example:
GWMI win32_ComputerSystem | fl name,model
Can also take a hash table for precise format control
Used to print a single property as a table
The Format-* cmdlets format objects
Om the pipeline or via –Inputobject parameter
You can adjust the details of how you want your data to
appear using the cmdlets, hash tables, format strings, etc
They produce format objects
The Out-* cmdlets take format objects and output it
to the console (and elsewhere)
Format-Table
-Autosize
Waits till ALL objects are ready before formatting and autosizes the width of each column
-HidetableHeaders
Hides table headers
Format-List and Format-Table
-GroupBy
But you need to sort first
Objects in the pipeline are sent to Out-Default
Out-Default looks at the objects in the pipeline
If formatting instructions – send it to Out-Host
If objects - send to Format-List or Format-Table
Out-Default looks in .PS1XML for guidance
Select 1st view for guidance
Five or less properties – call Format-Table
Otherwise call Format-List
This creates format objects
Sent to Out-Default and then to the console
You can get basic output from PoweShell using
default formatting
You can see more/different using Format-table/list
directly
FL/FT typically used at the end of a pipeline
But PowerShell is built on .NET
Lets leverage .NET formatting
Composite String – with placeholders
"There are{0} ps1 files" –f
(ls C:\foo\*.ps1).count
Placeholder Syntax
{index[,alignment]{:formatstring}]
Simple placeholder examples
{0}
{0,20}
{0,-20:n}
Use these along with the –f operator
.NET formats values into the composite string!
Fixed decimal point
$a=123.4567898
"The Number is: {0:#.000}" –f $a
The Number is: 123.456
Currency
$a=123456.789123
"{0:c2}" –f $a
£123,456.79
Phone Number
$a=4255551212
"{0:(###) ###-####}" -f $a
(425) 555-1212
All types have a .ToString() method
Inherited from [Object]
Base types have power over how to format
Pass a format string to .ToString() to control
formatting
Example
$i = 23.123456
$i.tostring("N2")
23.12
Format output for a single related set of values
Number of files
Number of files and their total size
Also use it to format one line in a table
Foreach ($file in $files) {display some aspect(s) of each file}
.NET Formatting string used in
Composite format string
ToString()
Hash Tables (later in this talk)
Numeric format strings
http://msdn.microsoft.com/en-us/library/427bttx3(VS.71).aspx
Date and time format strings
http://msdn.microsoft.com/en-us/library/97x6twsz(VS.71).aspx
Enumeration format strings
http://msdn.microsoft.com/en-us/library/c3s1ez6e(VS.71).aspx
Simple Formatting
DEMO 1
Using FT/FL, you can create a ‘calculated field’
Field defined by a Hash Table with pre-defined key
names:
(or Label) - <string>
Expression - <string> or <script block>
FormatString - <string>
Width <int32>
Alignment - value can be "Left", "Center",
Name
or "Right")
Send FT/FL hash table vs a property name
$x1=@{label="Process Name";
Expression={$_.name};
alignment="right"}
$x2=@{label="CPU Used";
Expression={$_.CPU};
FormatString="N3"}
Get-Process notepad | Format-Table $x1,$x2 -auto
$x1=@{label="Process Name";Expression={$_.name};
alignment="right"}
$x2=@{label="CPU Used"; Expression={$_.CPU};FormatString="N3"}
Get-Process | Format-Table $x1,$x2 –autosize
$x3=@{label="Process Name"; Expression={$_.name}}
Get-Process | Format-List $x3,$x2
Give FT/FL better column/table headers
Sometimes property name is ugly/unhelpful
Display a calculated value
Covert a number into gb/mb etc
Expression = {$_.Length/1GB}
Coerce field into to nicer format easily
XML
Import-CliXML
Export-CliXML
ConvertTo-XML
CSV
Export-CSV (and Import-CSV)
Useful for interop with XML Applications
Uses WPF
You need latest .NET Framework
Creates sortable list in a separate window with
criteria
to help limit output
Out-GridView
(and PowerShell ISE) need .NET 3.51
The rest of PowerShell requires .NET 2.0
Out-Gridview and ISE use WPF
By default, Out-Gridview displays same columns as FT
Clone the object first to see all object properties
Get-Process | Select-Object * | Out-Gridview
Hash tables and FT/FL
DEMO 2
Seen default formatting
Used FT/FL and hash tables
Formatted using .NET
So let’s do create custom XML
Two types of ps1xml
Define/update types - *.types.ps1xml
Define/update formatting - *.format.ps1xml
Default Format XML shipped with PowerShell
Apps , OS additions, modules add to this default set
Stored in $PSHOME
DO NOT EDIT THESE FILES!
They are signed – editing breaks that!
Copy and edit them instead
Don’t like the way PowerShell formats a type?
Develop your own display XML
PowerShell ships with 7 format.ps1xml files
You can write your own
Define four views: table, list, wide, and complex
Do NOT edit existing files – make a copy and edit it
Run Update-FormatData to add new view
Add this to $profile to persist the change
<Name>
Identifies the name of the view.
<ViewSelectedBy>
Specifies the object type or types to which the view
applies.
<GroupBy>
Specifies how items in the view should be combined in
groups.
<TableControl> <ListControl> <WideControl> <ComplexControl>
Contain the tags that specify how each item is displayed.
Add-Type @'
public class aeroplane
{
public string Model =
public int
InFleet
public int
Range =
public int
Pax
=
}
'@
"Boeing 737";
= 12;
2400;
135;
But what about the display?
Use FormatData.ps1xml
<Configuration>
<ViewDefinitions>
<View> <name>Airplane</name>
<TableControl>…</TableControl>
</View>
<View> <name>Airplane</name>
<ListControl>…</ListControl>
</View>
</ViewDefinitions></Configuration>
Saved as
Aeroplane.formatdata.ps1xml
Imported as needed/when needed
<TableControl>
<TableHeaders>
<TableColumnHeader>
<label>Passengers</label><width>12</width>
</TableColumnHeader>
…
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<tableColumnItem><PropertyName>Pax</PropertyName</tablecolumnitem>
</TableRowEntry>
</TableRowEntries>
</TableControl>
…
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<PropertyName>Model</PropertyName>
</ListItem>
<ListItems>
<ListEntry>
</ListEntries>
</Listcontrol>
…
Save XML to C
Update-FormatData c:\foo\aeroplane.format.ps1xml
Then:
$Object = new-object aeroplane
$object
$object | fl
You can also extend existing types or add new ones
Create XML file describing your addition
Use Update-TypeData to incorporate it
Persist the change by updating $Profile
<Types>
<Type>
<Name>System.Object</Name>
<Members>
<ScriptMethod>
<Name>MSDN</Name>
<Script>
if (($global:MSDNViewer -eq $null) -or ($global:MSDNViewer.HWND -eq $null)) {
$global:MSDNViewer = new-object -ComObject InterNetExplorer.Application}
$Uri = "http://msdn2.microsoft.com/library/" + $this.GetType().FullName + ".ASPX"
$global:MSDNViewer.Navigate2($Uri)
$global:MSDNViewer.Visible = $TRUE
</Script>
</ScriptMethod>
</Members>
</Type>
</Types>
Create the XML
On your workstation
XCOPY during logon script?
Store it somewhere useful
C:\foo
Somewhere else??
Add the type/format information to your $Profile
Update-TypeData
-Path <path>
Update-FormatData –Path <path>
Formatting can be simple or complex
Lots of alternatives – have it your way
Keep it simple and extend to meet your needs
I have free copies of PowerShell Pro
Idera’s PowerShell Development Tool
The first 25 folks to email me will get a link to
download the software (and a license).
I gave you the email address at the start of this
presentation
The codeword is “POWERSHELLISAWESOME!”
The first 25 to mail that code word to the address I
gave earlier will win their prize!
Adding .MSDN() to types
http://blogs.msdn.com/powershell/archive/2006/06/24/644987
Formatting - see TFL’s articles on formatting
http://tfl09.blogspot.com/2010/02/formatting-with-
powershell.html
.NET Formatting
http://msdn.microsoft.com/en-us/library/txafckwd(VS.71).aspx
Thomas Lee’s Blogs/PowerShell site
http://tfl09.blogspot.com
http://pshscripts.blogspot.com
http://www.reskit.net/psmc
THE END