1
00:00:01,040 --> 00:00:03,840
When you're getting started with formatting in PowerShell,

2
00:00:03,840 --> 00:00:05,440
there are a few things I often see,

3
00:00:05,440 --> 00:00:09,440
and I absolutely ran into these when I got started as well.

4
00:00:09,440 --> 00:00:10,060
Hopefully,

5
00:00:10,060 --> 00:00:12,460
I can show you a couple of things to be aware of to

6
00:00:12,460 --> 00:00:15,240
save you some pain and confusion.

7
00:00:15,240 --> 00:00:18,280
Firstly, when you think of formatting in PowerShell,

8
00:00:18,280 --> 00:00:20,940
always remember to format right.

9
00:00:20,940 --> 00:00:26,040
I don't mean format correctly; I mean format right, as in the direction.

10
00:00:26,040 --> 00:00:29,450
What is meant by that is that any formatting you want to do

11
00:00:29,450 --> 00:00:31,800
should be the last thing on your pipeline,

12
00:00:31,800 --> 00:00:35,440
which is always to the very right‑hand side of the pipeline.

13
00:00:35,440 --> 00:00:38,460
The reason is that pretty much the only thing you can do with

14
00:00:38,460 --> 00:00:41,840
formatted data is send it to an Out cmdlet.

15
00:00:41,840 --> 00:00:43,600
Let's look at an example of that.

16
00:00:43,600 --> 00:00:47,240
I'll run Get‑Process and pipe that to Format‑List.

17
00:00:47,240 --> 00:00:52,160
At this point, I might be like, I really only want the name and id properties,

18
00:00:52,160 --> 00:00:54,470
so I'll just pipe that across to select,

19
00:00:54,470 --> 00:00:58,110
which is shorthand for select object, and grab the name and id.

20
00:00:58,110 --> 00:01:01,740
When I run that, there's nothing in the output here.

21
00:01:01,740 --> 00:01:05,490
If I scroll all the way back up, I have columns for the name and id,

22
00:01:05,490 --> 00:01:07,940
but no values are coming through.

23
00:01:07,940 --> 00:01:12,130
Similarly, if you tried to do the same but pipe it to something like Sort‑Object,

24
00:01:12,130 --> 00:01:14,650
this time we're going to get a hard error.

25
00:01:14,650 --> 00:01:18,560
And if you read the error, you'll actually get a hint as to what is going on.

26
00:01:18,560 --> 00:01:21,330
It's complaining that the object type,

27
00:01:21,330 --> 00:01:24,630
which is this internal formatting object here,

28
00:01:24,630 --> 00:01:27,500
is not valid or not in the correct sequence,

29
00:01:27,500 --> 00:01:31,490
which is likely caused by a user‑specified format command

30
00:01:31,490 --> 00:01:33,660
conflicting with the default formatting.

31
00:01:33,660 --> 00:01:38,230
Quick sidebar: Make sure to take the time to read errors in PowerShell.

32
00:01:38,230 --> 00:01:39,880
They actually do help.

33
00:01:39,880 --> 00:01:41,640
So let's distill that down.

34
00:01:41,640 --> 00:01:43,340
Why is this happening?

35
00:01:43,340 --> 00:01:46,630
Well, let's run Get‑Process and pipe that to Get‑Member,

36
00:01:46,630 --> 00:01:49,090
and I'm going to pipe that to the more command so it

37
00:01:49,090 --> 00:01:51,040
doesn't scroll off the screen.

38
00:01:51,040 --> 00:01:51,480
Remember,

39
00:01:51,480 --> 00:01:54,300
the object types we get from running Get‑Process are

40
00:01:54,300 --> 00:01:56,860
these system diagnostic process objects,

41
00:01:56,860 --> 00:02:00,640
and they all have these properties that are listed on the screen here.

42
00:02:00,640 --> 00:02:03,540
If I press space a few times to page through the results,

43
00:02:03,540 --> 00:02:07,340
we'll see lots of different properties on the process object.

44
00:02:07,340 --> 00:02:12,140
Those properties are all available as that object is sent down the pipeline.

45
00:02:12,140 --> 00:02:16,040
But look at what happens when we pipe Get‑Process to Format‑List.

46
00:02:16,040 --> 00:02:18,460
We'll pipe that to Get‑Member,

47
00:02:18,460 --> 00:02:21,050
and you might be expecting to see the same process

48
00:02:21,050 --> 00:02:23,180
object types here and the properties.

49
00:02:23,180 --> 00:02:26,560
But what's actually in the pipeline now are these internal

50
00:02:26,560 --> 00:02:29,770
formatting types and properties because we've sent our

51
00:02:29,770 --> 00:02:32,040
objects to a format command.

52
00:02:32,040 --> 00:02:32,990
So, really,

53
00:02:32,990 --> 00:02:37,010
the rule to remember here is always have your format command as

54
00:02:37,010 --> 00:02:40,840
the last command in the chain or to the right.

55
00:02:40,840 --> 00:02:42,960
So if we repeat Get‑Process,

56
00:02:42,960 --> 00:02:46,320
this time pipe it to the select command to grab the name and id,

57
00:02:46,320 --> 00:02:51,540
and then send it down to Format‑List, we get the output we expected.

58
00:02:51,540 --> 00:02:53,980
Now that I've told you to always format last,

59
00:02:53,980 --> 00:02:55,700
there is one exception to that,

60
00:02:55,700 --> 00:02:59,830
and we've been using it already in this demo without really realizing it.

61
00:02:59,830 --> 00:03:03,040
But the exception here is that you can send formatted

62
00:03:03,040 --> 00:03:05,730
data to PowerShell's Out cmdlets.

63
00:03:05,730 --> 00:03:10,840
Remember, Out‑Default and Out‑Host are always bolted on to the end.

64
00:03:10,840 --> 00:03:11,530
Technically,

65
00:03:11,530 --> 00:03:15,140
we've been sending the data to both of those in all of these examples.

66
00:03:15,140 --> 00:03:21,040
The Out cmdlets know how to deal with formatted data coming down the pipeline.

67
00:03:21,040 --> 00:03:23,770
Let's use a specific example of Out‑File,

68
00:03:23,770 --> 00:03:26,790
which will take the formatted data and simply pass

69
00:03:26,790 --> 00:03:29,240
it to an unstructured text file.

70
00:03:29,240 --> 00:03:32,260
So I'll grab that last command, which ends with Format‑List,

71
00:03:32,260 --> 00:03:34,540
and then pipe it to Out‑File.

72
00:03:34,540 --> 00:03:40,140
I'll drop this in C:\Docs and just call it processes.txt.

73
00:03:40,140 --> 00:03:42,360
No errors and no warnings.

74
00:03:42,360 --> 00:03:45,230
So let's read that back in by running Get‑Content and

75
00:03:45,230 --> 00:03:48,040
specifying the path to the text file we created.

76
00:03:48,040 --> 00:03:52,440
And, yep, there's the data we sent out in the list format.

77
00:03:52,440 --> 00:03:54,770
Let's just pause here and summarize because I need

78
00:03:54,770 --> 00:03:56,280
to hit you with another caveat.

79
00:03:56,280 --> 00:04:01,140
So, firstly, leave your formatting until last or to the right.

80
00:04:01,140 --> 00:04:04,740
The exception to that is if you're piping the results to an Out command,

81
00:04:04,740 --> 00:04:09,540
in which case it's okay to have the format command piped to an Out command.

82
00:04:09,540 --> 00:04:14,130
The caveat here is a specific Out command named Out‑GridView,

83
00:04:14,130 --> 00:04:17,430
which is a command that we'll look out in more depth in the next module,

84
00:04:17,430 --> 00:04:21,640
but Out‑GridView cannot accept formatted data.

85
00:04:21,640 --> 00:04:24,230
Let me press the up arrow to bring that command back,

86
00:04:24,230 --> 00:04:28,540
and this time I'll pipe Format‑List to Out‑GridView.

87
00:04:28,540 --> 00:04:33,290
Yeah, we get an error that the data format is not supported by Out‑GridView.

88
00:04:33,290 --> 00:04:36,910
Out‑GridView is expecting unformatted data.

89
00:04:36,910 --> 00:04:41,640
So if we get rid of our format command, it'll pop up just fine.

90
00:04:41,640 --> 00:04:43,660
The final thing here that I'd like to mention,

91
00:04:43,660 --> 00:04:46,350
and this really only applies if you're starting to

92
00:04:46,350 --> 00:04:48,060
build your own scripts or functions,

93
00:04:48,060 --> 00:04:52,720
but please do not use any of the format commands inside of a

94
00:04:52,720 --> 00:04:55,840
script or function that you might end up authoring.

95
00:04:55,840 --> 00:04:58,680
You should always be returning PowerShell objects,

96
00:04:58,680 --> 00:05:01,040
and then you can leave it up to the user to decide on

97
00:05:01,040 --> 00:05:05,240
what they want to do with the data, which may or may not be to format it.

98
00:05:05,240 --> 00:05:07,160
When you hardcode formatting in,

99
00:05:07,160 --> 00:05:10,940
you severely limit the usefulness of that script or command.

100
00:05:10,940 --> 00:05:13,540
If you want to provide custom formatting for the code you're

101
00:05:13,540 --> 00:05:20,000
writing, then I'd suggest you look into skilling up on creating the custom view definitions.

