Let's jump into the PowerShell console and explore some of those
concepts we just covered in the last clip.
First up, if you recall in the formatting workflow diagram,
if we have an object that's a string,
Out‑Default will just pipe it straight to Out‑Host.
Let me create a string here with a variable of $mystring,
and I'll just put the value as This is a string of text.
Nothing too exciting.
If I grab $mystring and pipe that to Get‑Member and just scroll up there,
we can see the type of object here is indeed System.String.
If I just run $mystring,
we get the value of that string output back on the screen.
Behind the scenes here, that is going to Out‑Default and Out‑Host.
If I pipe it to one of the format commands,
like Format‑Table, normally you'd expect to see a table as the output,
but because this is just a string and not an object with properties,
there's nothing to format in a table.
And just to prove that point further, same deal with Format‑List.
We'll look more at Format‑List and Format‑Table in the upcoming clips.
Now remember I mentioned,
every time you run a command it gets output to Out‑Default,
which will then, by default, pipe it to Out‑Host.
Let's run a command like Get‑NetAdapter,
and this will list the network adapters on the machine.
By default, this type of object gets formatted as a table.
You can pipe that to Out‑Default, and you get exactly the same thing,
because that actually happened anyway when we ran it the first time,
you just didn't see it.
And finally, we can also explicitly pipe that to Out‑Host,
but again, you will get exactly the same thing,
because even though you didn't see it,
Out‑Host was added on the end of the previous two
commands by PowerShell automatically.
Let's take a look at how the formatting data works
that I mentioned in the last clip.
If I run Get‑Process, the default formatting is a table.
If I scroll up, you can see the table headers there,
and take note of these table headers,
especially things like this K and M in the brackets there.
If I run Get‑Process again and pipe it to Get‑Member,
and I'm just going to pipe that to the more command so
it doesn't escape off the screen,
here we can see the type name for this object is System.Diagnostics.Process.
I'm going to highlight that and copy it to my clipboard using
Ctrl+C because I want to use that again in a moment.
One of the cmdlets I briefly introduced in the last clip was Get‑FormatData,
which allows us to explore some of the default formatting
rules PowerShell has in its system.
Let's explore that by running Get‑FormatData with no parameters at all.
The list we get back is of all the different types of objects that
PowerShell has some specific formatting instructions for.
We can narrow this down by specifying the object type.
So, I'll run Get‑FormatData again, and this time use the TypeName parameter,
and then press Ctrl+V to paste in the process object
that I copied a few moments ago.
One of the tips that you'll see if you dig into the help for Get‑FormatData
is to always include the PowerShell version parameter with the value as 5.1
when using a local invocation of Get‑FormatData.
The result we get back here indicates there are several different
FormatViewDefinitions for the System.Diagnostics.Process object type.
Let me up arrow to get that back,
and then I'll press the Home button to go to the start of the command,
and I'm going to put that in a variable named $formatdata.
We can then run $formatdata.FormatViewDefinition to
look at the values of that property,
and we can see the four different ViewDefinitions,
three of which are specified as TableControl and one of
which is specified as WideControl.
If I run that again and then get the first object
and look at the control property,
this is now getting down into the nitty‑gritty of that first definition,
and we can start to see properties like headers,
rows, so on, and so forth.
If I up arrow to get that last command back and then
check out the Headers property,
you'll notice we're now listing the values of the headers that
are going to be in the formatted output,
as well as some of the format instructions like how many pixels wide will it be,
and what's the alignment going to be, that sort of thing.
Remember when we ran Get‑Process a minute ago, these were the headings for
the table columns that were displayed on our screen.
We could keep digging around in the console here,
but all of this information can be exported to XML,
which, and I thought I'd never say this,
can be a little bit easier to read.
Let me just create a new folder in C:\Docs by running New‑Item,
and I'll set the type to a Directory.
Let's again run Get‑FormatData, and we'll specify the TypeName parameter,
and I'll paste the value that's still on my clipboard,
and we'll specify the PowerShell version.
From there, we can pipe that across to Export‑FormatData,
specify the path as C:\Docs/process.xml.
Now you are meant to export these as ps1 XMLs,
but plain old XML will work fine just for our purpose here.
And then there's a parameter to include the script block,
which it isn't done by default,
but I know this view uses them and I want to show you those,
so I'm going to include it.
Okay, awesome, let's crack open that file in Notepad,
and let me just make that full screen,
and I'll bump up the font size here so we can actually see this as well.
What we're looking at here are the formatting ViewDefinitions in XML format
that PowerShell will use for the process object type.
So we can see at the top here that this first view
that's defined is named process.
And then it starts defining the formatting information for how
that table should be constructed by PowerShell.
If I scroll down a little bit,
we can see here that there are script blocks included for the table columns.
So on the fly, when PowerShell is formatting this data,
it is also taking these raw properties of each object like PM and
WS, and then dividing them by 1MB to manipulate the output we end
up getting shown by PowerShell.
So the person that created this view is going to a lot of effort for us to
modify and present the data to make it nicer to read by default.
This does also highlight something to be aware of.
Sometimes when you run a command,
you'll see a heading in the output that isn't actually
the name of an underlying property,
and that's because the view is formatting it differently.
Occasionally, you'll try and do something with that
sub‑property with the name that you see in the output,
only to find that it's not actually the name of the underlying property.
So if you ever get into that situation,
make sure you pipe the command to Get‑Member,
and that will show you the actual property names of the object.
Okay,
now, let's jump back to the PowerShell console and take a look
at an example of what PowerShell does when there are no
formatting rules for an object type.
I'm going to run Test‑NetConnection, and I'm going to specify the ComputerName,
which is really just a target, as www.google.com.
And I'm going to test if I can connect to google.com on the common port of HTTP.
The result comes back okay there, and I can see that that's come back as a list,
and we're looking at six properties in total.
Let's pipe that across to Get‑Member, and if I scroll up a touch,
the TypeName is Test‑NetConnectionResult.
As far as I'm aware,
there's no formatting rule for that type, so this is where
if there are four properties or less, PowerShell will do a table,
but if there are five or more, it will do a list.
Let's test out that theory by running the command again,
but this time I'm going to pipe it to Select‑Object
to select specific properties.
I'll pick the ComputerName, the RemoteAddress,
the RemotePort and the SourceAddress.
What do you think is going to happen here?
If you think that we'll get a table as a result, you are absolutely correct.
Let me up arrow to get that last command back,
and then I'm going to add a fifth property.
I'll choose PingSucceeded.
What do you think is going to happen now?
If you thought it will format as a list, then again, you are spot on.
We can override the formatting system as well.
So,
if I press the up arrow again to get that command back
that's selecting five properties, so by default this is a list,
I can explicitly pipe that to Format‑Table to tell
PowerShell that I definitely want a table,
and because I've overridden the formatting system, I'll get the table as an output, which is exactly what I wanted.