1
00:00:01,040 --> 00:00:06,140
Now it's time to look at dates.

2
00:00:06,140 --> 00:00:07,950
And anything that we're going to do with dates should

3
00:00:07,950 --> 00:00:10,310
probably start with the Get‑Date cmdlet.

4
00:00:10,310 --> 00:00:12,640
This is why I encourage you to read the help.

5
00:00:12,640 --> 00:00:15,520
You may have run Get‑Date and you just get the current datetime,

6
00:00:15,520 --> 00:00:19,420
but there are a number of parameters that you can use in order to

7
00:00:19,420 --> 00:00:22,830
format the way that the datetime is presented to you,

8
00:00:22,830 --> 00:00:24,770
and I'm going to go through some of these.

9
00:00:24,770 --> 00:00:30,590
So I can run Get‑Date and say format it using a .NET format of g,

10
00:00:30,590 --> 00:00:31,740
and this is lowercase.

11
00:00:31,740 --> 00:00:35,020
These format parameters are case sensitive.

12
00:00:35,020 --> 00:00:37,830
This gives me the date in this format,

13
00:00:37,830 --> 00:00:40,070
and the format will be appropriate to your culture.

14
00:00:40,070 --> 00:00:46,040
Because I am in North America, my format is month, day, year.

15
00:00:46,040 --> 00:00:50,440
If I do capital G, then I get that particular format.

16
00:00:50,440 --> 00:00:56,240
A lowercase u for the format will give me a UTC string.

17
00:00:56,240 --> 00:00:59,530
If you come from a UNIX background or Linux background,

18
00:00:59,530 --> 00:01:03,420
there is a uformat parameter, specify a UNIX‑type format,

19
00:01:03,420 --> 00:01:06,460
again, this too is case sensitive, so I'm telling PowerShell,

20
00:01:06,460 --> 00:01:10,000
get me the date formatted as year, underscore,

21
00:01:10,000 --> 00:01:11,190
and then the month.

22
00:01:11,190 --> 00:01:13,700
We can also create dates.

23
00:01:13,700 --> 00:01:17,080
So let's say that I have a string, maybe something I've created,

24
00:01:17,080 --> 00:01:21,340
or that I've read from a file, or pulled from somewhere.

25
00:01:21,340 --> 00:01:25,550
I can use Get‑Date to actually turn that into a datetime object.

26
00:01:25,550 --> 00:01:27,120
Don't try to fuss with the string to, say,

27
00:01:27,120 --> 00:01:29,120
pull out a year, or a month, or something,

28
00:01:29,120 --> 00:01:31,520
turn it into a datetime object,

29
00:01:31,520 --> 00:01:35,940
and then use the datetime things I'm going to show you.

30
00:01:35,940 --> 00:01:40,590
So let's do this, let's do Get‑Date and give it a year, a month, and a day.

31
00:01:40,590 --> 00:01:45,550
And here's another way that I can create a datetime object, so there's $b.

32
00:01:45,550 --> 00:01:50,640
Because I specified no time, it just defaults to 12:00 a.m.

33
00:01:50,640 --> 00:01:52,800
Now, this is just another type of object,

34
00:01:52,800 --> 00:01:56,430
so I'm going to look at all of the properties using

35
00:01:56,430 --> 00:01:58,970
Select‑Object and not necessarily using Get‑Member.

36
00:01:58,970 --> 00:02:00,850
Now that I see what these are,

37
00:02:00,850 --> 00:02:06,140
I could then access any of these properties in my PowerShell work.

38
00:02:06,140 --> 00:02:08,670
There are methods as well that we can use.

39
00:02:08,670 --> 00:02:12,240
So I'm just going to look at the methods of a DateTime object.

40
00:02:12,240 --> 00:02:16,040
Now, some of these are just things that are part of the .NET Framework,

41
00:02:16,040 --> 00:02:18,000
which we won't necessarily get into,

42
00:02:18,000 --> 00:02:21,840
but I will show you some ones that probably are of use to you.

43
00:02:21,840 --> 00:02:25,260
Any of these ones that say, To something,

44
00:02:25,260 --> 00:02:29,630
ShortDateString or LongDateString, those are things that you will want to use,

45
00:02:29,630 --> 00:02:33,040
or maybe something like this, hey, is $b,

46
00:02:33,040 --> 00:02:35,190
is it in daylight savings time?

47
00:02:35,190 --> 00:02:40,540
And gives me True or False and January 1st is not in daylight savings time.

48
00:02:40,540 --> 00:02:49,540
Or want to format this as a string, so I can format the date to a LongDateString.

49
00:02:49,540 --> 00:02:52,880
Maybe this is an easier way than using the format parameter,

50
00:02:52,880 --> 00:02:57,740
but these are methods that you probably are likely to use.

51
00:02:57,740 --> 00:03:04,440
There are a number of Add methods, AddDays, AddHours, AddMinutes, and so on.

52
00:03:04,440 --> 00:03:09,540
What day is it 45 days from now, or 45 days from $b?

53
00:03:09,540 --> 00:03:12,940
And I get a new datetime object.

54
00:03:12,940 --> 00:03:17,940
Or I want, say, I need what's the datetime in 1000 hours from now?

55
00:03:17,940 --> 00:03:23,740
Sometimes we want to go backwards and say, what time was it five months ago?

56
00:03:23,740 --> 00:03:27,590
My recommendation is, don't try to use the Subtract methods that you'll see,

57
00:03:27,590 --> 00:03:32,040
use the Add method and just add a negative number.

58
00:03:32,040 --> 00:03:38,040
So five months prior to $b is that, Sunday August 1st, 2021.

59
00:03:38,040 --> 00:03:40,400
This is the type of thing that you might need if you're working,

60
00:03:40,400 --> 00:03:43,740
for example, with user accounts in Active Directory.

61
00:03:43,740 --> 00:03:47,190
Any discussion of dates also needs to include timespans,

62
00:03:47,190 --> 00:03:50,390
how much time has occurred between two particular

63
00:03:50,390 --> 00:03:54,440
datetime objects or two datetime events.

64
00:03:54,440 --> 00:03:56,200
So I'm going to create a new datetime object,

65
00:03:56,200 --> 00:03:57,860
this is another way that you can do it,

66
00:03:57,860 --> 00:04:02,810
I'm going to create the variable $c and make it a datetime object.

67
00:04:02,810 --> 00:04:08,740
PowerShell will treat this string into a datetime value.

68
00:04:08,740 --> 00:04:11,300
Now, there's a cmdlet that we can use, New‑TimeSpan,

69
00:04:11,300 --> 00:04:14,250
and I'll let you read the help here.

70
00:04:14,250 --> 00:04:19,610
So I'm going to create a New‑TimeSpan variable and the Start will be $b,

71
00:04:19,610 --> 00:04:22,640
and the ending date will be $c.

72
00:04:22,640 --> 00:04:24,140
So what is that?

73
00:04:24,140 --> 00:04:25,250
All right, so there is the object.

74
00:04:25,250 --> 00:04:27,740
That is a TimeSpan object.

75
00:04:27,740 --> 00:04:29,750
You can see the Days, Hours, Minutes,

76
00:04:29,750 --> 00:04:33,850
as well as more granular approach with the TotalDays,

77
00:04:33,850 --> 00:04:35,640
TotalSeconds, and so on.

78
00:04:35,640 --> 00:04:38,150
This is another type of object, so if I wanted to,

79
00:04:38,150 --> 00:04:41,430
I could say, hey, I just want to know the Days property,

80
00:04:41,430 --> 00:04:43,340
161.

81
00:04:43,340 --> 00:04:47,840
The other way that you can create a TimeSpan is just simple subtraction.

82
00:04:47,840 --> 00:04:54,240
I can subtract $b from $c and get the same result.

83
00:04:54,240 --> 00:04:58,530
Now, TimeSpans, when we use them in our PowerShell work,

84
00:04:58,530 --> 00:05:01,440
typically will be displayed as a string,

85
00:05:01,440 --> 00:05:04,270
although you can also format it as a string,

86
00:05:04,270 --> 00:05:06,240
like this.

87
00:05:06,240 --> 00:05:10,740
I have some examples coming up where you'll see this again in action.

88
00:05:10,740 --> 00:05:14,340
So how about a practical example of using datetime values?

89
00:05:14,340 --> 00:05:23,140
I'm going to create a variable, and I'm going to list some file extensions.

90
00:05:23,140 --> 00:05:26,240
Now, what I want to do is use that,

91
00:05:26,240 --> 00:05:30,240
and I'm going to do Get‑ChildItem on my scripts folder,

92
00:05:30,240 --> 00:05:32,820
and I'm going to recursively search all files,

93
00:05:32,820 --> 00:05:38,140
but I only want these particular file types that I see in $in.

94
00:05:38,140 --> 00:05:40,350
I'm then going to group the results,

95
00:05:40,350 --> 00:05:43,740
and I'm going to group them on a custom property.

96
00:05:43,740 --> 00:05:48,840
So every file object has a CreationTime property, which is a datetime.

97
00:05:48,840 --> 00:05:53,160
I want to get the Year property of that datetime object,

98
00:05:53,160 --> 00:05:55,540
so we're grouping on a custom property,

99
00:05:55,540 --> 00:06:01,940
which will be the year that each of these files was created.

100
00:06:01,940 --> 00:06:06,340
I'm then going to select from that group object result,

101
00:06:06,340 --> 00:06:08,480
I'm going to create a property called Year,

102
00:06:08,480 --> 00:06:12,640
which will be the Name value from the Group‑Object,

103
00:06:12,640 --> 00:06:17,540
and then I'm going to create Size, so I'm going to take the group,

104
00:06:17,540 --> 00:06:21,840
and I'm going to pipe it to Measure‑Object and measure the length and the sum.

105
00:06:21,840 --> 00:06:22,910
Now, I want to point out here,

106
00:06:22,910 --> 00:06:27,040
here's another example where I'm leveraging the standard notation.

107
00:06:27,040 --> 00:06:33,140
Notice that the $_.Group piped Measure‑Object is all in parentheses.

108
00:06:33,140 --> 00:06:36,740
PowerShell is going to return that as an object.

109
00:06:36,740 --> 00:06:38,600
That object is a measurement object, right?

110
00:06:38,600 --> 00:06:43,640
We've seen that, that measurement object has a property called sum.

111
00:06:43,640 --> 00:06:47,060
This technique that I'm using here is a way of getting just the

112
00:06:47,060 --> 00:06:53,040
sum value all in line as I run the command,

113
00:06:53,040 --> 00:06:54,790
and then we'll do something similar,

114
00:06:54,790 --> 00:06:57,640
and this is another way of using Measure‑Object.

115
00:06:57,640 --> 00:06:59,890
I am going to take the Group, and remember,

116
00:06:59,890 --> 00:07:03,830
the Group property of the Group object is all the files

117
00:07:03,830 --> 00:07:06,290
that go to each of these file extensions,

118
00:07:06,290 --> 00:07:09,780
and I'm going to get the content of every file because these are

119
00:07:09,780 --> 00:07:13,660
all txt files and measure the number of lines,

120
00:07:13,660 --> 00:07:17,240
ignoring whitespace, and do the same thing.

121
00:07:17,240 --> 00:07:20,540
That whole command is in parentheses,

122
00:07:20,540 --> 00:07:23,750
which is going to give me a measurement object that has a Lines property,

123
00:07:23,750 --> 00:07:31,940
but all I want is the Lines value that will be used for the value for Lines.

124
00:07:31,940 --> 00:07:36,340
And then lastly, I'm going to format the results as a table,

125
00:07:36,340 --> 00:07:40,570
and I'm going to create a custom header for Format-Table called path,

126
00:07:40,570 --> 00:07:44,330
and I'm going to use my Scripts path as the value for that,

127
00:07:44,330 --> 00:07:46,380
and I'll AutoSize it to make it nice, and pretty,

128
00:07:46,380 --> 00:07:47,830
and easy to read.

129
00:07:47,830 --> 00:07:52,520
This will take a minute or so to run because I have to get all the files,

130
00:07:52,520 --> 00:07:55,490
group them, measure all the contents,

131
00:07:55,490 --> 00:07:57,320
and what's probably taking the longest amount of

132
00:07:57,320 --> 00:08:02,110
time is I have to take every file, read the contents,

133
00:08:02,110 --> 00:08:03,640
and then measure that.

134
00:08:03,640 --> 00:08:08,420
I'm creating a custom object that PowerShell will then pass on to Format-Table,

135
00:08:08,420 --> 00:08:11,090
which has to do its thing, and then finally,

136
00:08:11,090 --> 00:08:15,540
I will get the results written to the console here,

137
00:08:15,540 --> 00:08:16,640
and there we go.

138
00:08:16,640 --> 00:08:20,700
So now I have report that shows me the number of files for every year,

139
00:08:20,700 --> 00:08:24,440
how big they are, and the total number of lines.

140
00:08:24,440 --> 00:08:27,320
This is the type of thing that if I need this often or

141
00:08:27,320 --> 00:08:29,020
I want to share with someone else,

142
00:08:29,020 --> 00:08:31,950
I'm then going to build a PowerShell function around it.

143
00:08:31,950 --> 00:08:34,740
But if this doesn't work in the PowerShell console,

144
00:08:34,740 --> 00:08:36,220
you know, the function is not going to work,

145
00:08:36,220 --> 00:08:44,000
and I won't be able to do that. So doing this in the console, as I've done here, is always the first step.

