When you're getting started with formatting in PowerShell,
there are a few things I often see,
and I absolutely ran into these when I got started as well.
Hopefully,
I can show you a couple of things to be aware of to
save you some pain and confusion.
Firstly, when you think of formatting in PowerShell,
always remember to format right.
I don't mean format correctly; I mean format right, as in the direction.
What is meant by that is that any formatting you want to do
should be the last thing on your pipeline,
which is always to the very right‑hand side of the pipeline.
The reason is that pretty much the only thing you can do with
formatted data is send it to an Out cmdlet.
Let's look at an example of that.
I'll run Get‑Process and pipe that to Format‑List.
At this point, I might be like, I really only want the name and id properties,
so I'll just pipe that across to select,
which is shorthand for select object, and grab the name and id.
When I run that, there's nothing in the output here.
If I scroll all the way back up, I have columns for the name and id,
but no values are coming through.
Similarly, if you tried to do the same but pipe it to something like Sort‑Object,
this time we're going to get a hard error.
And if you read the error, you'll actually get a hint as to what is going on.
It's complaining that the object type,
which is this internal formatting object here,
is not valid or not in the correct sequence,
which is likely caused by a user‑specified format command
conflicting with the default formatting.
Quick sidebar: Make sure to take the time to read errors in PowerShell.
They actually do help.
So let's distill that down.
Why is this happening?
Well, let's run Get‑Process and pipe that to Get‑Member,
and I'm going to pipe that to the more command so it
doesn't scroll off the screen.
Remember,
the object types we get from running Get‑Process are
these system diagnostic process objects,
and they all have these properties that are listed on the screen here.
If I press space a few times to page through the results,
we'll see lots of different properties on the process object.
Those properties are all available as that object is sent down the pipeline.
But look at what happens when we pipe Get‑Process to Format‑List.
We'll pipe that to Get‑Member,
and you might be expecting to see the same process
object types here and the properties.
But what's actually in the pipeline now are these internal
formatting types and properties because we've sent our
objects to a format command.
So, really,
the rule to remember here is always have your format command as
the last command in the chain or to the right.
So if we repeat Get‑Process,
this time pipe it to the select command to grab the name and id,
and then send it down to Format‑List, we get the output we expected.
Now that I've told you to always format last,
there is one exception to that,
and we've been using it already in this demo without really realizing it.
But the exception here is that you can send formatted
data to PowerShell's Out cmdlets.
Remember, Out‑Default and Out‑Host are always bolted on to the end.
Technically,
we've been sending the data to both of those in all of these examples.
The Out cmdlets know how to deal with formatted data coming down the pipeline.
Let's use a specific example of Out‑File,
which will take the formatted data and simply pass
it to an unstructured text file.
So I'll grab that last command, which ends with Format‑List,
and then pipe it to Out‑File.
I'll drop this in C:\Docs and just call it processes.txt.
No errors and no warnings.
So let's read that back in by running Get‑Content and
specifying the path to the text file we created.
And, yep, there's the data we sent out in the list format.
Let's just pause here and summarize because I need
to hit you with another caveat.
So, firstly, leave your formatting until last or to the right.
The exception to that is if you're piping the results to an Out command,
in which case it's okay to have the format command piped to an Out command.
The caveat here is a specific Out command named Out‑GridView,
which is a command that we'll look out in more depth in the next module,
but Out‑GridView cannot accept formatted data.
Let me press the up arrow to bring that command back,
and this time I'll pipe Format‑List to Out‑GridView.
Yeah, we get an error that the data format is not supported by Out‑GridView.
Out‑GridView is expecting unformatted data.
So if we get rid of our format command, it'll pop up just fine.
The final thing here that I'd like to mention,
and this really only applies if you're starting to
build your own scripts or functions,
but please do not use any of the format commands inside of a
script or function that you might end up authoring.
You should always be returning PowerShell objects,
and then you can leave it up to the user to decide on
what they want to do with the data, which may or may not be to format it.
When you hardcode formatting in,
you severely limit the usefulness of that script or command.
If you want to provide custom formatting for the code you're
writing, then I'd suggest you look into skilling up on creating the custom view definitions.