Let’s quickly review. You know that PowerShell cmdlets produce objects and that those objects often contain more properties than PowerShell shows by default. You know how to use gm
to get a list of all of an object’s properties, and you know how to use Select-Object
to specify the properties you want to see. Up to this point in the book, you’ve relied on PowerShell’s default configuration and rules to determine how the final output will appear on the screen (or in a file, or in hard-copy form). In this chapter, you’ll learn to override those defaults and create your own formatting for your commands’ output.
We don’t want to give the impression that PowerShell is a full-fledged management-reporting tool, because it isn’t. But PowerShell has good capabilities for collecting information, and, with the right output, you can certainly produce reports using that information. The trick is getting the right output, and that’s what formatting is all about.
On the surface, PowerShell’s formatting system can seem easy to use—and for the most part that’s true. But the formatting system also contains some of the trickiest “gotchas” in the entire shell, so we want to make sure you understand how it works and why it does what it does. We’re not just going to show you a few new commands here; rather, we’ll explain how the entire system works, how you can interact with it, and what limitations you might run into.
Run our old friend Get-Process
again, and pay special attention to the column headers. Notice that they don’t exactly match the property names. Instead, each header has 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 PowerShell. Specifically, formatting directions for process objects are in DotNetTypes.format.ps1xml.
Try it Now You 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, specifically, where PSReadLine is, and opening PSReadLine.format.ps1xml. PSReadLine is a PowerShell module that provides the experience when you type in a PowerShell console. It adds a bunch of fancy keyboard shortcuts and syntax highlighting, and is customizable. 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.
TIP You might get a warning code: The
term
'code'
is
not
recognized
as
a name
of
a
cmdlet,
function,
script
file,
or
executable
program.
To fix this, open the command palette and run the following shell command: Shell Command:
Install
'code'
command
in
PATH
.
Next, find out the exact type of object returned by Get-PSReadLineKeyHandler
:
Copy and paste the complete type name, Microsoft.PowerShell.KeyHandler
, to the clipboard.
Switch over to Visual Studio Code and press Cmd-F (or Ctrl-F on Windows) to open the Search dialog.
In the Search dialog, paste in the type name you copied to the clipboard. Press Enter.
You should see Microsoft.PowerShell.KeyHandler
in the file. Figure 11.1 shows what you should find.
What you’re now looking at in Visual Studio Code is the set of directions that govern how a key handler is displayed by default. Scroll down, and you’ll see the definition for a table view, which you should expect because you already know that key handlers 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 finished browsing, close Visual Studio Code, being careful not to save any changes that you may have accidentally made to the file, and go back to PowerShell.
Try it Now You can also get this format data by running the following command. You can mess around with the object you get back, but we won’t be focusing on it.
PS /Users/jamesp/> Get-FormatData -PowerShellVersion 7.1 -TypeName ➥ Microsoft.PowerShell.KeyHandler
When you run Get-PSReadLineKeyHandler
, here’s what happens in the shell:
The cmdlet places objects of the type Microsoft.PowerShell.KeyHandler
into the pipeline.
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.
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 theory, someone could write a shell that uses files or printers as the default output instead, but nobody has (that we know of).
Most of the Out-
cmdlets are incapable of working with standard objects. Instead, they’re designed to work with special formatting instructions. So, when Out-Host
sees that it has been handed standard objects, it passes them to the formatting system.
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 produce formatting instructions, which are passed back to Out-Host
.
Once Out-Host
sees that it has formatting instructions, it follows those instructions 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 formatting 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 anytime objects need to be converted into human-readable textual output.
What rules does the formatting system follow in step 5? For the first formatting rule, the system looks to see whether the type of object it’s dealing with has a predefined view. That’s what you saw in PSReadLine.format.ps1xml: a predefined view for a KeyHandler
object. A few other .format.ps1xml files are installed with PowerShell, and they’re all loaded by default when the shell starts. You can create your own predefined 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. In this case, it’s looking for the view that handles Microsoft .PowerShell.KeyHandler
objects.
What if there’s no predefined view? Let’s find out using the System.Uri
type, which doesn’t have an entry in a format.ps1xml file (we promise!). Try running this:
This is using a concept called “casting,” where we say, “Hey, PowerShell, I’ve got this string that looks like a URI. Can you just treat it like the type System.Uri
?” And PowerShell replies, “You got it!” and gives you a Uri
object. You might notice we didn’t have to specify System
in the line that we ran. That’s because PowerShell tacks on System
to the front if it can’t find a type just called Uri
. Clever PowerShell! Anyway, the output of that is a long list of properties like so:
AbsolutePath : / AbsoluteUri : https://github.com/ LocalPath : / Authority : github.com HostNameType : Dns IsDefaultPort : True IsFile : False IsLoopback : False PathAndQuery : / Segments : {/} IsUnc : False Host : github.com Port : 443 Query : Fragment : Scheme : https OriginalString : https://github.com DnsSafeHost : github.com IdnHost : github.com IsAbsoluteUri : True UserEscaped : False UserInfo :
The formatting is not too bad for something that doesn’t have any special formatting. That’s because PowerShell will look at the properties of the type and show them in a friendly view. We can control which properties we see here by introducing a format .ps1xml for this type, or we can allow the formatting system to take its next step, or what we call the second formatting rule : It looks to see whether anyone has declared a default display property set for that type of object. You’ll find those in a different configuration file, types.ps1xml. Since we’re not going to dive deep into writing our own format and types files, we’re going to give you one to load in, and we’ll just see how it affects the output. First, let’s create and open up a new file called Uri.Types.ps1xml file in Visual Studio Code:
Now, paste in the following content and save the file:
<?xml version="1.0" encoding="utf-8" ?> <Types> <Type> <Name>System.Uri</Name> <Members> <MemberSet> <Name>PSStandardMembers</Name> <Members> <PropertySet> <Name>DefaultDisplayPropertySet</Name> <ReferencedProperties> <Name>Scheme</Name> <Name>Host</Name> <Name>Port</Name> <Name>AbsoluteUri</Name> <Name>IsFile</Name> </ReferencedProperties> </PropertySet> </Members> </MemberSet> </Members> </Type> </Types>
Excellent, now, see the DefaultDisplayPropertySet
? Make a note of the five properties listed there. Then go back to PowerShell and run this:
We’ve just loaded that Types.ps1xml file we just created. Now let’s run the original line again and see what it gets us:
PS /Users/jamesp/> [Uri]"https://github.com" Scheme : https Host : github.com Port : 443 AbsoluteUri : https://github.com/ IsFile : False
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’ll 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 the kind of output to create. If the formatting system displays four or fewer properties, it uses a table. If there are five or more properties, it uses a list. That’s why the System.Uri
object wasn’t displayed as a table: its five properties trigger 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 automatically trigger the formatting system so that they can get the formatting instructions they need. Next let’s look at how to control that formatting system ourselves and override the defaults.
Oh, and by the way, the formatting system is why PowerShell sometimes seems to “lie.” For example, run Get-Process
and look at the column headers. See the one labeled PM(K)
? Well that’s a lie, sort of, because there’s no property called PM(K)
. There’s a property called PM
. The lesson here is that formatted column headers are just that—column headers. They aren’t necessarily the same as the underlying property names. The only safe way to see property names is to use Get-Member
.
PowerShell has four formatting cmdlets, and we’ll work with the three that provide the most day-to-day formatting capability (the fourth is briefly discussed in an “Above and beyond” sidebar near the end of this chapter). First up is Format-Table
, which has an alias, ft
.
If you read the help file for Format-Table
, you’ll notice that it has several parameters. These are some of the most useful ones, along with examples of how to use them:
-Property
—This parameter accepts a comma-separated list of properties that should be included in the table. These properties aren’t case sensitive, but the shell will use whatever you type as the column headers, so you can get nicer-looking output by properly casing the property names (e.g., CPU instead of cpu). This parameter accepts wildcards, meaning you can specify *
to include all properties in the table, or something like c*
to include all properties starting with c. Notice that the shell will still display only the properties it can fit in the table, so not every property you specify may display. This parameter is positional, so you don’t have to type the parameter name, provided the property list is in the first position. Try these examples (the second example from the help file for Format-Table
is shown here):
Get-Process | Format-Table -Property * Get-Process | Format-Table -Property ID,Name,Responding Get-Process | Format-Table * Id Name Responding -- ---- ---------- 20921 XprotectService True 1242 WiFiVelocityAge True 434 WiFiAgent True 89048 VTDecoderXPCSer True 27019 VTDecoderXPCSer True 506 ViewBridgeAuxil True 428 usernoted True 407 UserEventAgent True 544 useractivityd True 710 USBAgent True 1244 UsageTrackingAg True 416 universalaccess True 468 TrustedPeersHel True 412 trustd True 24703 transparencyd True 1264 TextInputMenuAg True 38115 Telegram True 425 tccd True 504 talagent True 1219 SystemUIServer True
-GroupBy
—This parameter generates a new set of column headers each time the specified property value changes. This works well only when you’ve first sorted the objects on that same property. An example is the best way to show how this works (this one will group Azure VMs based on whether they are running or stopped):
PS /Users/jamesp/> Get-AzVM -Status | Sort-Object PowerState | ➥ ft -Property Name,Location,ResourceGroupName -GroupBy PowerState PowerState: VM running Name Location ResourceGroupName ---- -------- ----------------- MyUbuntuVM eastus2 MYUBUNTUVM PowerState: VM deallocated Name Location ResourceGroupName ---- -------- ----------------- MyUbuntuVM2 eastus2 MYUBUNTUVM WinTestVM2 westus2 WINTESTVM2
-Wrap
—If the shell has to truncate information in a column, it’ll end that column with ellipses (. . .
) to visually indicate that information was suppressed. This parameter enables the shell to wrap information, which makes the table longer but preserves all the information you want to display. Here’s an example:
PS /Users/jamesp/> Get-Command | Select-Object Name,Source | ft -Wrap Name Source ---- ------ Compress-Archive Microsoft.P owerShell.A rchive Configuration PSDesiredSt ateConfigur ation Expand-Archive Microsoft.P owerShell.A rchive Expand-GitCommand posh-git Find-Command PowerShellG et Find-DscResource PowerShellG et Find-Module PowerShellG et Find-RoleCapability PowerShellG et
Try it Now You should run through all of these examples in the shell, and feel free to mix and match these techniques. Experiment to see what works and what sort of output you can create. These commands will only work if you have already connected to an Azure account and if you have existing virtual machines in Azure.
Sometimes you need to display more information than will fit horizontally in a table, which can make a list useful. Format-List
is the cmdlet you’ll turn to, or you can use its alias, fl
.
This cmdlet supports some of the same parameters as Format-Table
, including -Property
. In fact, fl
is another way of displaying the properties of an object. Unlike gm
, fl
will also display the values for those properties so that you can see what kind of information each property contains:
Get-Verb | Fl * ... Verb : Remove AliasPrefix : r Group : Common Description : Deletes a resource from a container Verb : Rename AliasPrefix : rn Group : Common Description : Changes the name of a resource Verb : Reset AliasPrefix : rs Group : Common Description : Sets a resource back to its original state Verb : Resize AliasPrefix : rz Group : Common Description : Changes the size of a resource Verb : Search AliasPrefix : sr Group : Common Description : Creates a reference to a resource in a container Verb : Select AliasPrefix : sc Group : Common Description : Locates a resource in a container ...
We often use fl
as an alternative way of discovering the properties of an object.
Try it Now Read the help for Format-List
, and try experimenting with its parameters.
The last cmdlet, Format-Wide
(or its alias, fw
), displays a wider, multicolumn list. It’s able to display only the values of a single property, so its -Property
parameter accepts only one property name, not a list, and it can’t accept wildcards.
By default, Format-Wide
looks for an object’s Name
property, because Name
is a commonly used property and usually contains useful information. The display generally defaults to two columns, but a -Columns
parameter can be used to specify more columns:
Get-Process | Format-Wide name -col 4 iTerm2 java keyboardserv... Keychain Ci... knowledge-ag... LastPass LocationMenu lockoutagent loginwindow lsd Magnet mapspushd mdworker mdworker_sha... mdworker_sha... mdworker_sh... mdworker_sha... mdworker_sha... mdworker_sha... mdworker_sh... mdworker_sha... mdworker_sha... mdworker_sha... mdwrite media-indexer mediaremotea... Microsoft Ed... Microsoft E... Microsoft Ed... Microsoft Ed... Microsoft Ed... Microsoft E... Microsoft Ed... Microsoft Ed... Microsoft Ed... Microsoft E...
Try it Now Read the help for Format-Wide
, and try experimenting with its parameters.
Flip back to the previous chapter and review section 10.5. In that section, we showed you how to use a hash table construct to add custom properties to an object. Both Format-Table
and Format-List
can use those same constructs to create custom table columns or custom list entries.
You might do this to provide a column header that’s different from the property name being displayed:
Get-AzStorageAccount | Format-Table @{name='Name';expression= {$_.StorageAccountName}},Location,ResourceGroupName Name Location ResourceGroupName ---- -------- ----------------- myubuntuvmdiag eastus2 MyUbuntuVM ismtrainierout westus ismtrainierout cs461353efc2db7x45cbxa2d westus cloud-shell-storage... mtnbotbmyhfk westus mtnbot pssafuncapp westus pssafuncapp
Note This will only work if an Azure connection and storage account already exists.
Or, you might put a more complex mathematical expression in place:
We admit, we’re cheating a little bit by throwing in a bunch of stuff that we haven’t talked about yet. We might as well talk about it now:
Obviously, we’re starting with Get-Process
, a cmdlet you’re more than familiar with by now. If you run Get-Process
|
fl
*
, you’ll see that the VM
property is in bytes, although that’s not how the default table view displays it.
We’re telling Format-Table
to start with the process’s Name
property.
Next we’re using a special hash table to create a custom column that will be labeled VM(MB)
. That’s the first part up to the semicolon, which is a separator. The second part defines the value, or expression, for that column by taking the object’s normal VM
property and dividing it by 1
MB
. The slash is PowerShell’s division operator, and PowerShell recognizes the shortcuts KB
, MB
, GB
, TB
, and PB
as denoting kilobyte, megabyte, gigabyte, terabyte, and petabyte, respectively.
The result of that division operation will have a decimal component that we don’t want to see. The -as
operator enables us to change the data type of that result from a floating-point value to, in this case, an integer value (specified by [int]
). The shell will round up or down, as appropriate, when making that conversion. The result is a whole number with no fractional component:
We show you this little division-and-changing trick because it can be useful in creating nicer-looking output. We won’t spend much more time in this book on these operations (although we’ll tell you that *
is used for multiplication, and as you might expect, +
and -
are for addition and subtraction, respectively).
Unlike Select-Object
, whose hash tables can accept only a Name
and Expression
key (although they’ll also accept N
, L
, and Label
for Name
, and will accept E
for Expression
), the Format-
commands can handle additional keys that are intended to control the visual display. These additional keys are most useful with Format-Table
:
FormatString
specifies a formatting code, causing the data to be displayed according to the specified format. This is mainly useful with numeric and date data. Go to the documentation on formatting types at http://mng.bz/XWy1 to review the available codes for standard numeric and date formatting and for custom numeric and date formatting.
Alignment
specifies the desired column alignment, either Left
or Right
.
Using those additional keys makes it easier to achieve the previous example’s results, and even to improve them:
Get-Process | ➥ Format-Table Name, ➥ @{name='VM(MB)';expression={$_.VM};formatstring='F2';align='right'} ➥ -AutoSize
Now we don’t have to do the division, because PowerShell will format the number as a fixed-point value having two decimal places, and it will right-align the result.
Once something is formatted, you have to decide where it’ll go. If a command line ends in a Format-
cmdlet, the formatting instructions created by the Format-
cmdlet go to Out-Default
, which forwards them to Out-Host
, which displays them on the screen:
You could also manually pipe the formatting instructions to Out-Host
, which accomplishes exactly the same thing:
Alternatively, you can pipe formatting instructions to Out-File
to direct formatted output to a file. As you’ll read in section 11.9, only one of those two Out-
cmdlets should ever follow a Format-
cmdlet on the command line.
Keep in mind that Out-File
defaults to a specific character width for output, which means a text file might look different from an onscreen display. The cmdlet has a -Width
parameter that enables you to change the output width, if desired, to accommodate wider tables.
In the old days of Windows PowerShell, there was a cmdlet that was included called Out-GridView
,
which provides another useful form of output—a graphical user interface (GUI). For PowerShell 6+, a cross-platform version of this cmdlet was created, but it exists in the PowerShell Gallery in the form of a module. You can install this cmdlet by running
Note that Out-GridView
isn’t technically formatting; in fact, Out-GridView
entirely bypasses the formatting subsystem. No Format-
cmdlets are called, no formatting instructions are produced, and no text output is displayed in the console window. Out-GridView
can’t receive the output of a Format-
cmdlet—it can receive only the regular objects output by other cmdlets.
Figure 11.2 shows what happens when we run the command Get-Process | Out-GridView
.
As we mentioned at the start of this chapter, the formatting system has most of the gotchas that trip up PowerShell newcomers. They tend to run across two issues, so we’ll try to help you avoid them.
It’s incredibly important that you remember one rule from this chapter: format right. Your Format-
cmdlet should be the last thing on the command line, with Out-File
as the only exception. The reason for this rule is that the Format-
cmdlets produce formatting instructions, and only an Out-
cmdlet can properly consume those instructions. If a Format-
cmdlet is last on the command line, the instructions will go to Out-Default
(which is always at the end of the pipeline), which will forward them to Out-Host
, which is happy to work with formatting instructions. Try running this command to illustrate the need for this rule:
Get-History | Format-Table | gm TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object ➥ obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() autosizeInfo Property Microsoft.PowerShell.Commands.Internal.Format.AutosizeInfo, ➥ System.Management.Automation, Version=7.0.0.0,... ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ➥ ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;} groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry, ➥ System.Management.Automation, Version=7.0.0.0... pageFooterEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageFooterEntry, ➥ System.Management.Automation, Version=7.0.0... pageHeaderEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageHeaderEntry, ➥ System.Management.Automation, Version=7.0.0... shapeInfo Property Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo, ➥ System.Management.Automation, Version=7.0.0.0, Cu... TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object ➥ obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;} groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry, ➥ System.Management.Automation, Version=7.0.0.0... shapeInfo Property ➥ Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo, ➥ System.Management.Automation, Version=7.0.0.0, Cu...
You’ll notice that gm
isn’t displaying information about your history objects because the Format-Table
cmdlet doesn’t output history objects. It consumes the history objects you pipe in, and it outputs formatting instructions—which is what gm
sees and reports on. Now try this:
Get-History | Select-Object Id,Duration,CommandLine | Format-Table | ConvertTo-Html | Out-File history.html
Go ahead and open history.html in a browser, and you’ll see some crazy results. You didn’t pipe history objects to ConvertTo-Html
; you piped formatting instructions, so that’s what got converted to HTML. This illustrates why a Format-
cmdlet, if you use one, has to be either the last thing on the command line or the second-to-last, with the last cmdlet being Out-File
.
Also know that Out-GridView
is unusual (for an Out-
cmdlet, at least), in that it won’t accept formatting instructions and will accept only standard objects. Try these two commands to see the difference:
That’s why we explicitly mentioned Out-File
as the only cmdlet that should follow a Format-
cmdlet (technically, Out-Host
can also follow a Format-
cmdlet, but there’s no need because ending the command line with the Format-
cmdlet will get the output to Out-Host
anyway).
The next thing to avoid is putting multiple kinds of objects into the pipeline. The formatting system looks at the first object in the pipeline and uses the type of that object to determine what formatting to produce. If the pipeline contains two or more kinds of objects, the output won’t always be complete or useful.
PS /Users/jamesp/> Get-Process; Get-History NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- ... 0 0.00 1.74 0.25 1244 1 UsageTrackingAg 0 0.00 0.68 0.19 710 1 USBAgent 0 0.00 4.12 6.37 544 1 useractivityd 0 0.00 5.44 8.00 407 1 UserEventAgent 0 0.00 7.50 3.43 428 1 usernoted 0 0.00 3.44 8.71 506 1 ViewBridgeAuxil 0 0.00 5.91 0.08 27019 ...19 VTDecoderXPCSer 0 0.00 5.92 0.07 89048 ...48 VTDecoderXPCSer 0 0.00 10.79 50.02 434 1 WiFiAgent 0 0.00 1.11 0.20 1242 1 WiFiVelocityAge 0 0.00 10.28 4.30 20921 ...21 XprotectService Id : 1 CommandLine : Update-TypeData -Path /tmp/Uri.Types.ps1xml ExecutionStatus : Completed StartExecutionTime : 9/21/2019 12:20:03 PM EndExecutionTime : 9/21/2019 12:20:03 PM Duration : 00:00:00.0688690 Id : 2 CommandLine : Update-TypeData -Path /tmp/Uri.Types.ps1xml ExecutionStatus : Completed StartExecutionTime : 9/21/2019 12:21:07 PM EndExecutionTime : 9/21/2019 12:21:07 PM Duration : 00:00:00.0125330eyp
That semicolon allows us to put two commands onto a single command line, without piping the output of the first cmdlet into the second one. This means both cmdlets run independently, but they put their output into the same pipeline. As you see, the output starts out fine, displaying process objects. But the output breaks down when it’s time to display the history objects. Rather than producing the table you’re used to, PowerShell reverts to a list. The formatting system isn’t designed to take multiple kinds of objects and make the results look as attractive as possible.
What if you want to combine information drawn from two (or more) places into a single form of output? You absolutely can, and you can do so in a way that the formatting system can deal with nicely. But that’s an advanced topic that we won’t get to in this book.
Note For this lab, you need any computer running PowerShell 7.1 or later.
See if you can complete the following tasks:
Display a table of processes that includes only the process names, IDs, and whether they’re responding to Windows (the Responding
property has that information). Have the table take up as little horizontal room as possible, but don’t allow any information to be truncated.
Display a table of processes that includes the process names and IDs. Also include columns for virtual and physical memory usage, expressing those values in megabytes (MB).
Use Get-Module
to get a list of loaded modules. Format the output as a table that includes, in this order, the module name and the version. The column headers must be ModuleName
and ModuleVersion
.
Use Get-AzStorageAccount
and Get-AzStorageContainer
to display all of your storage containers so that a separate table is displayed for storage containers that are accessible to the public and storage containers that are not. (Hint: Piping is your friend . . . use a -GroupBy
parameter.)
Display a four-column-wide list of all directories in the home directory.
Create a formatted list of all .dll files in $pshome
, displaying the name, version information, and file size. PowerShell uses the Length
property, but to make it clearer, your output should show Size
.
Get-Process | Format-Table Name,ID,
Get-AzStorageAccount | Get-AzStorageContainer | ft -GroupBy PublicAccess
Format-List Name,VersionInfo,@{Name="Size";Expression={$_.length}}
This is the perfect time to experiment with the formatting system. Try using the three main Format-
cmdlets to create different forms of output. The labs in upcoming chapters will often ask you to use specific formatting, so you might as well hone your skills with these cmdlets and start memorizing the more-often-used parameters covered in this chapter.
3.138.204.186