1
00:00:01,040 --> 00:00:03,220
Now we're getting to the meaty part, the

2
00:00:03,220 --> 00:00:05,470
part you've no doubt been waiting for.

3
00:00:05,470 --> 00:00:07,920
Let's go and find and install some modules

4
00:00:07,920 --> 00:00:10,680
from the PowerShell Gallery. Another key

5
00:00:10,680 --> 00:00:12,910
command in the PowerShellGet module is

6
00:00:12,910 --> 00:00:15,680
named Find‑Module, and I'm sure you'll be

7
00:00:15,680 --> 00:00:17,610
shocked to hear that this is the command

8
00:00:17,610 --> 00:00:20,540
we use to find modules in a repository.

9
00:00:20,540 --> 00:00:21,910
Let's take a look at the help for

10
00:00:21,910 --> 00:00:24,420
Find‑Module. Interestingly, there are no

11
00:00:24,420 --> 00:00:26,570
required parameters here, but there are

12
00:00:26,570 --> 00:00:28,670
some interesting parameters here, such as

13
00:00:28,670 --> 00:00:31,270
MinimumVersion, MaximumVersion, and the

14
00:00:31,270 --> 00:00:33,920
RequiredVersion. There's also one that I

15
00:00:33,920 --> 00:00:35,240
want to point out to you here that we

16
00:00:35,240 --> 00:00:36,840
don't actually work within this course,

17
00:00:36,840 --> 00:00:39,020
but I do want you to be aware of it, which

18
00:00:39,020 --> 00:00:41,880
is IncludeDependencies. Sometimes you'll

19
00:00:41,880 --> 00:00:43,890
come across a PowerShell module which

20
00:00:43,890 --> 00:00:46,300
depends on another PowerShell module for

21
00:00:46,300 --> 00:00:48,710
it to function fully. You can use the

22
00:00:48,710 --> 00:00:51,190
IncludeDependencies parameter to get shown

23
00:00:51,190 --> 00:00:53,500
if modules have dependencies, and if they

24
00:00:53,500 --> 00:00:56,690
do, what they are. Similarly, when it

25
00:00:56,690 --> 00:00:58,830
comes time to install modules, if you

26
00:00:58,830 --> 00:01:00,870
install one that has a dependency on

27
00:01:00,870 --> 00:01:03,250
another module, it will often install that

28
00:01:03,250 --> 00:01:06,240
dependency for you in the background.

29
00:01:06,240 --> 00:01:08,740
Let's run Find‑Module with no parameters,

30
00:01:08,740 --> 00:01:11,700
as the help told me this should work. And

31
00:01:11,700 --> 00:01:14,720
yep, here we go. This will go and find

32
00:01:14,720 --> 00:01:17,850
every single module that exists in the

33
00:01:17,850 --> 00:01:19,540
repositories I've currently got

34
00:01:19,540 --> 00:01:22,260
registered. As much as I like fun

35
00:01:22,260 --> 00:01:24,410
activities like watching paint dry, I'm

36
00:01:24,410 --> 00:01:26,610
going to press Ctrl+C to stop that so we

37
00:01:26,610 --> 00:01:29,670
can try out a few other things. We can run

38
00:01:29,670 --> 00:01:32,270
Find‑Module and use the Name parameter to

39
00:01:32,270 --> 00:01:34,920
start filtering our search. Now, I'm

40
00:01:34,920 --> 00:01:37,270
assuming you probably know about Slack,

41
00:01:37,270 --> 00:01:39,890
the popular communication tool. If you

42
00:01:39,890 --> 00:01:41,590
don't, that's all good, as we're not going

43
00:01:41,590 --> 00:01:43,920
to use Slack itself, but someone the other

44
00:01:43,920 --> 00:01:45,750
day was telling me about a PowerShell

45
00:01:45,750 --> 00:01:48,230
module that exists for Slack but I can't

46
00:01:48,230 --> 00:01:50,270
remember the name of it. So let me put

47
00:01:50,270 --> 00:01:52,510
Slack in for the name, but with asterisk

48
00:01:52,510 --> 00:01:56,210
to perform a wildcard search. Okay, cool,

49
00:01:56,210 --> 00:01:58,940
we've got a number of results there, and

50
00:01:58,940 --> 00:02:00,650
it happens to be the first result,

51
00:02:00,650 --> 00:02:03,390
PSSlack, that I was thinking about. You

52
00:02:03,390 --> 00:02:06,390
can also search based on tags. So you can

53
00:02:06,390 --> 00:02:10,760
run Find‑Module ‑Tag Slack. As authors

54
00:02:10,760 --> 00:02:13,360
update their modules to fix bugs or add

55
00:02:13,360 --> 00:02:15,400
new capabilities, they publish new

56
00:02:15,400 --> 00:02:18,140
versions of a module. Find‑Module, by

57
00:02:18,140 --> 00:02:20,670
default, unless told otherwise, will

58
00:02:20,670 --> 00:02:22,900
return the latest version of a module at

59
00:02:22,900 --> 00:02:25,220
that point in time from the repository.

60
00:02:25,220 --> 00:02:27,980
There's a parameter named AllVersions that

61
00:02:27,980 --> 00:02:30,190
can be used to display all historical

62
00:02:30,190 --> 00:02:32,970
versions of a particular module. So we

63
00:02:32,970 --> 00:02:36,240
could run Find‑Module ‑Name PSSlack

64
00:02:36,240 --> 00:02:38,860
‑AllVersions, and we'll see this module

65
00:02:38,860 --> 00:02:41,210
has had a number of releases over time,

66
00:02:41,210 --> 00:02:45,620
with 1.0.5 being the newest. We could also

67
00:02:45,620 --> 00:02:48,200
use the MaximumVersion parameter, which

68
00:02:48,200 --> 00:02:49,720
will return the newest version of the

69
00:02:49,720 --> 00:02:52,300
module that does not exceed the version

70
00:02:52,300 --> 00:02:55,860
specified. So if we enter that as 1.0,

71
00:02:55,860 --> 00:02:58,090
even though a newer version than 1.0 does

72
00:02:58,090 --> 00:03:00,600
exist, it won't show us that, as we've

73
00:03:00,600 --> 00:03:03,080
manually capped the maximum version that

74
00:03:03,080 --> 00:03:05,740
Find‑Module should go and get for us.

75
00:03:05,740 --> 00:03:07,280
There's another parameter named

76
00:03:07,280 --> 00:03:09,790
RequiredVersion. If you are looking for a

77
00:03:09,790 --> 00:03:12,180
very specific version of a module, you can

78
00:03:12,180 --> 00:03:14,740
use RequiredVersion to limit your search.

79
00:03:14,740 --> 00:03:17,470
So let's say we were after version 1.0.2.

80
00:03:17,470 --> 00:03:21,210
We can be specific about that and only get

81
00:03:21,210 --> 00:03:24,030
that version returned. The last parameter

82
00:03:24,030 --> 00:03:25,870
of Find‑Module that I want you to be aware

83
00:03:25,870 --> 00:03:28,950
of is named Repository. So by default

84
00:03:28,950 --> 00:03:30,810
Find‑Module will search all of the

85
00:03:30,810 --> 00:03:33,160
repositories you have registered. If you

86
00:03:33,160 --> 00:03:35,260
want to limit the repositories Find‑Module

87
00:03:35,260 --> 00:03:36,960
will use when you have more than one

88
00:03:36,960 --> 00:03:39,310
repository, you can use this Repository

89
00:03:39,310 --> 00:03:41,720
parameter to tell it specifically which

90
00:03:41,720 --> 00:03:44,640
repository to look in. Lastly, before we

91
00:03:44,640 --> 00:03:47,600
get onto installing this PSSlack module,

92
00:03:47,600 --> 00:03:49,170
there's another handy command for

93
00:03:49,170 --> 00:03:51,420
discovery that you might like to use

94
00:03:51,420 --> 00:03:54,510
called Find‑Command. So instead of just

95
00:03:54,510 --> 00:03:56,190
finding the module, you can use

96
00:03:56,190 --> 00:03:58,060
Find‑Command to be a bit more granular

97
00:03:58,060 --> 00:04:01,240
with your searching to discover commands.

98
00:04:01,240 --> 00:04:04,850
If I run Find‑Command ‑ModuleName PSSlack,

99
00:04:04,850 --> 00:04:07,240
we'll see all of the commands that are

100
00:04:07,240 --> 00:04:10,210
available inside of that module, so before

101
00:04:10,210 --> 00:04:12,250
even installing it, I can take a look at

102
00:04:12,250 --> 00:04:14,160
what sort of functionality is included in

103
00:04:14,160 --> 00:04:16,360
this module to see if it might be the kind

104
00:04:16,360 --> 00:04:18,840
of thing that I'm actually looking for.

105
00:04:18,840 --> 00:04:21,380
And finally, if you know the name of a

106
00:04:21,380 --> 00:04:24,080
specific command, maybe you saw it online

107
00:04:24,080 --> 00:04:25,970
or someone told you about it, or you've

108
00:04:25,970 --> 00:04:27,700
used it before but you can't quite

109
00:04:27,700 --> 00:04:29,980
remember which module it's a part of, you

110
00:04:29,980 --> 00:04:31,820
can use Find‑Command to search for a

111
00:04:31,820 --> 00:04:34,110
specific command. Let me look for the

112
00:04:34,110 --> 00:04:37,230
command named Get‑VM, and we'll see that

113
00:04:37,230 --> 00:04:39,890
Get‑VM is a command in two modules on the

114
00:04:39,890 --> 00:04:42,820
PowerShell Gallery. Come on, Matt, I hear

115
00:04:42,820 --> 00:04:44,690
you say, we've inspected the module

116
00:04:44,690 --> 00:04:47,510
enough, let's get it installed. Alright,

117
00:04:47,510 --> 00:04:49,930
alright. To do that, we need to use the

118
00:04:49,930 --> 00:04:52,620
command named Install‑Module. Let's check

119
00:04:52,620 --> 00:04:54,970
out the help with get‑help Install‑Module.

120
00:04:54,970 --> 00:04:58,180
For this one, the only required parameter

121
00:04:58,180 --> 00:05:00,550
is the name of the module, and we do have

122
00:05:00,550 --> 00:05:02,780
options there to specify the particular

123
00:05:02,780 --> 00:05:04,950
version by using similar parameters that

124
00:05:04,950 --> 00:05:06,970
we just looked at on the Find‑Module

125
00:05:06,970 --> 00:05:09,840
command. There's a parameter here named

126
00:05:09,840 --> 00:05:12,430
AllowClobber, and while we won't be using

127
00:05:12,430 --> 00:05:15,090
this, it's good to know about. Similar to

128
00:05:15,090 --> 00:05:17,280
AllowClobber on Import‑Module that we

129
00:05:17,280 --> 00:05:18,760
looked at in the last module of this

130
00:05:18,760 --> 00:05:21,360
course, using AllowClobber on

131
00:05:21,360 --> 00:05:23,670
Install‑Module lets you confirm that you

132
00:05:23,670 --> 00:05:25,450
want to install a module that has

133
00:05:25,450 --> 00:05:27,720
conflicting commands with a module that is

134
00:05:27,720 --> 00:05:30,370
already installed on your machine. There's

135
00:05:30,370 --> 00:05:32,710
also a particular parameter I do want to

136
00:05:32,710 --> 00:05:35,920
point out named Scope. And listen up, this

137
00:05:35,920 --> 00:05:38,430
is really important. I'm going to bring up

138
00:05:38,430 --> 00:05:41,160
our PSModulePaths in the console here to

139
00:05:41,160 --> 00:05:43,770
help explain this as well. The Scope

140
00:05:43,770 --> 00:05:47,430
parameter accepts two values, AllUsers and

141
00:05:47,430 --> 00:05:50,970
CurrentUser. If you specify AllUsers, the

142
00:05:50,970 --> 00:05:53,450
module will get installed in a location

143
00:05:53,450 --> 00:05:55,630
that is accessible by all users on this

144
00:05:55,630 --> 00:05:58,380
computer, such as this location here in

145
00:05:58,380 --> 00:06:01,570
the Program Files folder. If you specify

146
00:06:01,570 --> 00:06:04,020
CurrentUser for the Scope, the module gets

147
00:06:04,020 --> 00:06:06,190
installed in a location that is only

148
00:06:06,190 --> 00:06:07,970
accessible to the current user of the

149
00:06:07,970 --> 00:06:10,820
computer, such as this folder here, which

150
00:06:10,820 --> 00:06:13,670
is inside of my user profile, so if

151
00:06:13,670 --> 00:06:15,700
someone else logs onto this machine, they

152
00:06:15,700 --> 00:06:17,320
wouldn't have access to that module that

153
00:06:17,320 --> 00:06:20,420
I've installed. Now Scope is optional, so

154
00:06:20,420 --> 00:06:22,340
there's some default behavior, and the

155
00:06:22,340 --> 00:06:24,620
default behavior differs based on which

156
00:06:24,620 --> 00:06:27,630
version of PowerShellGet you have. With

157
00:06:27,630 --> 00:06:30,370
PowerShellGet version 1, the default scope

158
00:06:30,370 --> 00:06:33,120
is AllUsers, which requires elevation of

159
00:06:33,120 --> 00:06:35,380
the PowerShell session for installation of

160
00:06:35,380 --> 00:06:38,640
a module. With PowerShellGet version 2 and

161
00:06:38,640 --> 00:06:41,580
above, the default scope is CurrentUser,

162
00:06:41,580 --> 00:06:43,800
which does not require elevation for

163
00:06:43,800 --> 00:06:46,730
install. The version of PowerShellGet can

164
00:06:46,730 --> 00:06:48,500
be checked with a Get‑Module

165
00:06:48,500 --> 00:06:51,740
PowerShellGet, and interestingly enough, I

166
00:06:51,740 --> 00:06:54,840
actually have version 1 and version 2.

167
00:06:54,840 --> 00:06:56,940
Version 1 was installed by default with

168
00:06:56,940 --> 00:07:00,150
Windows 10, but version 2 of PowerShellGet

169
00:07:00,150 --> 00:07:02,180
was installed when I installed PowerShell

170
00:07:02,180 --> 00:07:04,770
7. By default, when this happens,

171
00:07:04,770 --> 00:07:06,810
PowerShell will load the newest version.

172
00:07:06,810 --> 00:07:09,060
So we're currently running version 2 of

173
00:07:09,060 --> 00:07:11,940
PowerShellGet, so by default this module

174
00:07:11,940 --> 00:07:13,520
is going to be installed in the

175
00:07:13,520 --> 00:07:16,660
CurrentUser scope. Let's give installing a

176
00:07:16,660 --> 00:07:19,340
module a go. I'll run Install‑Module

177
00:07:19,340 --> 00:07:22,830
PSSlack. The ‑Name parameter was optional,

178
00:07:22,830 --> 00:07:24,900
as this is a positional parameter, and

179
00:07:24,900 --> 00:07:26,760
this will go and look for a module named

180
00:07:26,760 --> 00:07:29,740
PSSlack in our registered repositories,

181
00:07:29,740 --> 00:07:31,370
and it found the one in the PowerShell

182
00:07:31,370 --> 00:07:34,300
Gallery. And, as expected, it's telling me

183
00:07:34,300 --> 00:07:36,210
that I'm about to install a module from an

184
00:07:36,210 --> 00:07:38,780
untrusted repository, and am I sure I

185
00:07:38,780 --> 00:07:41,760
actually want to do this. I'm pretty sure,

186
00:07:41,760 --> 00:07:44,810
so I'll say y to that. And that's it, the

187
00:07:44,810 --> 00:07:46,990
PSSlack module is now installed on my

188
00:07:46,990 --> 00:07:49,920
machine. Pretty simple, right? I'll run

189
00:07:49,920 --> 00:07:52,020
Get‑Module PSSlack using the

190
00:07:52,020 --> 00:07:53,920
‑ListAvailable parameter because it's not

191
00:07:53,920 --> 00:07:56,440
yet imported into this session, and I'm

192
00:07:56,440 --> 00:07:59,090
going to pipe that to format list. What I

193
00:07:59,090 --> 00:08:01,020
want to highlight here is that the module

194
00:08:01,020 --> 00:08:03,570
got installed into the PSModulePath under

195
00:08:03,570 --> 00:08:06,100
my user profile because that's the default

196
00:08:06,100 --> 00:08:08,770
with PowerShellGet version 2. You'll

197
00:08:08,770 --> 00:08:10,580
definitely want to be aware of this Scope

198
00:08:10,580 --> 00:08:12,420
behavior as you start working with

199
00:08:12,420 --> 00:08:15,310
modules. Finishing up here, now that the

200
00:08:15,310 --> 00:08:17,890
PSSlack module is installed, we can run

201
00:08:17,890 --> 00:08:20,690
Get‑Command, specifying the PSSlack module

202
00:08:20,690 --> 00:08:22,580
to see which commands we can now start

203
00:08:22,580 --> 00:08:25,440
using, having now installed this module.

204
00:08:25,440 --> 00:08:27,500
And one last thing I want you to be aware

205
00:08:27,500 --> 00:08:29,940
of is even though I won't actually show it

206
00:08:29,940 --> 00:08:32,040
in any of these demos, a lot of these

207
00:08:32,040 --> 00:08:34,210
commands in the PowerShellGet module can

208
00:08:34,210 --> 00:08:37,310
be piped to one another. So, for example,

209
00:08:37,310 --> 00:08:39,320
you could do a Find‑Module to figure out

210
00:08:39,320 --> 00:08:41,050
what you're looking for, and then just

211
00:08:41,050 --> 00:08:43,380
pipe that directly to Install‑Module

212
00:08:43,380 --> 00:08:45,010
rather than explicitly running

213
00:08:45,010 --> 00:08:47,370
Install‑Module and specifying the module

214
00:08:47,370 --> 00:08:50,350
name. I'm being very particular to run

215
00:08:50,350 --> 00:08:52,500
each command separately to ensure you're

216
00:08:52,500 --> 00:08:54,710
clear on what's happening in each step,

217
00:08:54,710 --> 00:08:56,380
but I did want to mention that if you're

218
00:08:56,380 --> 00:09:00,000
comfortable with piping, please feel free to do so.

