PowerShell Formatting Deep Dive

Report
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

similar documents