Way back in version 1 of PowerShell, it
was possible for individuals or companies
to use an object known as a PowerShell
snap‑in to extend PowerShell by importing
additional commands, above and beyond
those that are included by default. I
mention snap‑ins briefly, only because you
still may come across them, especially in
articles or blogs online. Snap‑ins were
pretty clunky as they had to be installed
and registered on each individual machine,
usually by running an executable file, and
they added information into the Windows
Registry. They also lacked the ability to
define things like dependencies. In short,
PowerShell snap‑ins are the very old way
of doing things. And look, you really
shouldn't come across them anymore, but if
you do, it might be worth a polite mention
to the author to look at releasing their
commands in a PowerShell module. The
preferred packaging method nowadays for
PowerShell commands is, and has been for
quite some time, by using a PowerShell
module. A module is almost always just a
set of files. They are typically script
files, but sometimes you'll come across
modules that are binary DLLs, and often
these come from vendors such as Microsoft.
You still treat both of these types the
same way from an installation and usage
perspective. And unless you're building
modules, which is not in the scope of this
course, you should just be aware of this,
but not too concerned with it. The main
purpose of a module is to allow the reuse
and abstraction of PowerShell code. Simply
put, a module is a package of related
PowerShell functions or commands grouped
together as a single unit, usually saved
in a single directory. There are a number
of PowerShell modules that are
pre‑installed on a Windows machine, and
these are sometimes referred to as the
core modules. Typically on a Windows
computer, if features included with the
operating system have commands to manage
them, then those PowerShell modules are
also pre‑installed. Commands within a
module are most often all related to a
specific service or system, and each
command should perform one specific
function, and it should do that one thing
really well. For example, there's a
component of Windows known as the
Background Intelligent Transfer Service,
or BITS for short, and there's a
PowerShell module provided by Microsoft
named BitsTransfer. This module includes
commands such as Get‑BitsTransfer,
Remove‑BitsTransfer, Set‑BitsTransfer,
Start‑BitsTransfer, you get the idea. This
module doesn't include any commands to do
with any other system or platform. All of
the commands are related to managing the
same thing. The author for this module
would have started by creating each
particular command to perform a specific
function. And then they got to a point
where they had separate commands to do
separate tasks, all related to BITS. From
there, it makes sense to package these
commands in a single unit, which is where
a PowerShell module is formed. From the
perspective of an author of PowerShell
code, packaging commands in a module makes
it really easy to include information
about the module and add in properties
like dependencies, versioning, and the
requirements while also being able to
publish the module to a repository like
the PowerShell Gallery, making it
instantly available to millions of
PowerShell users. All you need to do to
install or deploy a module is place the
package of files in one of several
particular folders that PowerShell knows
to search in. These folders are stored in
an environment variable named
PSModulePath, and I'll show this to you in
the upcoming demo. You'll want to become
very familiar and aware of PSModulePath as
PowerShell uses this variable to locate
modules when you don't specify the full
path to a module. Now, strictly speaking,
you don't need to place a module in one of
the PSModulePaths to use it. You could put
it anywhere in the file system and then
import the module into your PowerShell
console by using the command named
Import‑Module. But for the most part,
you're better off by using one of these
paths, and you'll see the power of that in
the demo. While you can just copy and
paste a folder containing a PowerShell
module onto your computer and start using
it, there are built‑in commands we can use
to help with finding, installing, and
managing modules, and I'll take you
through those in detail in the next module
in this course. There's one last thing I'd
like to cover before we jump into a few
demos here. Starting from version 3,
PowerShell has the ability to import
modules into your console automatically
from any of those PSModulePaths, if you
run any command from a module that's
installed on your machine. This is known
as module auto‑loading. While auto‑loading
is a fantastic feature, using the
Import‑Module command to explicitly import
a module does have some benefits and use
cases, and you should be familiar with
this command. Some scenarios where you may
want to use Import‑Module, rather than
relying on the auto‑load, are if the
module is not in one of those default
PSModule folders. You'll need to run
Import‑Module and point it to the specific
path of the module. Occasionally you will
come across circumstances where you have
multiple modules that contain conflicting
command names. An example of this is
Get‑VM, which is a common command in the
VMware PowerCLI module, as well as the
Microsoft Hyper‑V module. By using
Import‑Module, you can use a parameter
named NoClobber, which will not import
commands that have the same names as
existing commands in the current session.
Another way of tackling this problem is to
use the prefix parameter of Import‑Module.
So using the example from before, when we
had a conflicting command of Get‑VM, you
might import the VMware module with a
prefix of VMW, meaning that all commands
from that module will have a VMW prefix.
So Get‑VM can be used for the Hyper‑V
command, while Get‑VMW VM can be used for the VMware command.