Formatting—and why it’s done on the right
10.2 About the default formatting
Run our old friend Get-Process again, and pay special attention to the column head- ers. Notice that they don’t exactly match the property names. Instead, they each have a specific width, alignment, and so forth. All that configuration stuff has to come from someplace, right? You’ll find it in one of the .format.ps1xml files that install with Pow- erShell. Specifically, formatting directions for process objects are in DotNetTypes.for- mat.ps1xml.
TRY IT NOW You’ll definitely want to have PowerShell open so that you can follow along with what we’re about to show you. This will help you understand what the formatting system is up to under the hood.
We’ll begin by changing to the PowerShell installation folder and opening DotNet- Types.format.ps1xml. Be careful not to save any changes to this file. It’s digitally signed, and any changes that you save—even a single carriage return or space added to the file—will break the signature and prevent PowerShell from using the file.
PS C:\>cd $pshome
PS C:\>notepad dotnettypes.format.ps1xml
Next, find out the exact type of object returned by Get-Process:
PS C:\>get-process | gm
Now follow these steps:
1 Copy and paste the complete type name, System.Diagnostics.Process, to the
clipboard. To do so, use your cursor to highlight the type name, and press Return to copy it to the clipboard.
2 Switch over to Notepad and press Ctrl-F to open the Find window.
3 In the Find window, paste in the type name you copied to the clipboard. Click
Find Next.
4 The first thing you find will probably be a ProcessModule object, not a Process
object, so click Find Next again and again until you locate System.Diagnostics .Process in the file. Figure 10.1 shows what you should have found.
Figure 10.1 Locating the process view in Windows Notepad
What you’re now looking at in Notepad is the set of directions that govern how a process is displayed by default. Scroll down a bit, and you’ll see the definition for a
table view, which you should expect because you already know that processes display in
a multicolumn table. You’ll see the familiar column names, and if you scroll down a bit more you’ll see where the file specifies which property will display in each column. You’ll see definitions for column widths and alignments too. When you’re done browsing, close Notepad, being careful not to save any changes that you may have accidentally made to the file, and go back to PowerShell.
When you run Get-Process, here’s what happens in the shell:
1 The cmdlet places objects of the type System.Diagnostics.Process into the
pipeline.
2 At the end of the pipeline is an invisible cmdlet called Out-Default. It’s always
there, and its job is to pick up whatever objects are in the pipeline after all of your commands have run.
3 Out-Default passes the objects to Out-Host, because the PowerShell console is
designed to use the screen (called the host) as its default form of output. In the- ory, someone could write a shell that uses files or printers as the default output instead, but nobody has that we know of.
4 Most of the Out- cmdlets are incapable of working with normal objects. Instead,
they’re designed to work with special formatting instructions. So when Out-Host sees that it has been handed normal objects, it passes them to the for- matting system.
5 The formatting system looks at the type of the object and follows an internal set
of formatting rules (we’ll cover those in a moment). It uses those rules to pro- duce formatting instructions, which are passed back to Out-Host.
6 Once Out-Host sees that it has formatting instructions, it follows those instruc-
tions to construct the onscreen display.
All of this happens whenever you manually specify an Out- cmdlet, too. For example, run Get-Process | Out-File procs.txt, and Out-File will see that you’ve sent it some normal objects. It will pass those to the formatting system, which creates format- ting instructions and passes them back to Out-File. Out-File then constructs the text file based on those instructions. So the formatting system becomes involved any time objects need to be converted into human-readable textual output.
What rules does the formatting system follow in step 5, above? For the first format- ting rule, the system looks to see if the type of object it’s dealing with has a predefined view. That’s what you saw in DotNetTypes.format.ps1xml: a predefined view for a Process object. There are a few other .format.ps1xml files installed with PowerShell, and they’re all loaded by default when the shell starts. You can create your own pre- defined views as well, although doing so is beyond the scope of this book.
The formatting system looks for predefined views that specifically target the object type it’s dealing with—meaning that in this case it’s looking for the view that handles System.Diagnostics.Process objects.
What if there is no predefined view? For example, try running this:
Get-WmiObject Win32_OperatingSystem | Gm
Grab that object’s type name (or at least the “Win32_OperatingSystem” part), and try to find it in one of the .format.ps1xml files. We’ll save you some time by telling you that you won’t find it.
This is where the formatting system takes its next step, or what we call the second formatting rule: it looks to see if anyone has declared a default display property set for that type of object. You’ll find those in a different configuration file, Types.ps1xml. Go ahead and open it in Notepad now (again, be careful not to save any changes to this file) and use the Find function to locate Win32_OperatingSystem. Once you do, scroll down a bit and you’ll see DefaultDisplayPropertySet. It’s shown in figure 10.2. Make a note of the six properties listed there.
Now, go back to PowerShell and run this:
Get-WmiObject Win32_OperatingSystem
Do the results look familiar? They should: the properties you see are there solely because they’re listed as defaults in Types.ps1xml. If the formatting system finds a default display property set, it will use that set of properties for its next decision. If it doesn’t find one, the next decision will consider all of the object’s properties.
That next decision—the third formatting rule—is about what kind of output to create. If the formatting system will display four or fewer properties, it will use a table. If there are five or more properties, it will use a list. That’s why the Win32 _OperatingSystem object wasn’t displayed as a table: there were six properties, trig- gering a list. The theory is that more than four properties might not fit well into an ad hoc table without truncating information.
Now you know how the default formatting works. You also know that most Out- cmdlets will automatically trigger the formatting system, so that they can get the for- matting instructions they need. Next let’s look at how we can control that formatting system ourselves, and override the defaults.
Figure 10.2 Locating a
DefaultDisplayPropertySet in Notepad