Americas

  • United States

Asia

jonathan_hassell
Contributing Writer

All about PowerShell providers and modules

how-to
Jan 04, 201714 mins
Data CenterEnterprise ApplicationsSmall and Medium Business

Here's what these commands are, how they work and how to use them in your daily activities.

I think it’s time to talk in depth about some of the most important features of PowerShell: Providers and modules. (Snap-ins have also been important, but they are being gradually phased out.) These are really the core of the universe when it comes to all of the commands available for use within PowerShell, so I want to teach you what they are, how they work and how to use them in your daily activities. Let’s dive in!

Introducing providers

When you hear the term “providers,” I bet the non-developers among us (and I include myself in this group) start to tune out. That sounds like something you do along with creating a class and instantiating a for-loop with strings that pass through a model view controller.

But that’s not the case here. Let me unpack this for you a little bit, at least in the context of PowerShell.

PowerShell providers are essentially like drivers for the operating system, where you install some code to help your copy of Windows talk to the graphics hardware, the storage and disk subsystems, and the chipset on your motherboard. The drivers contain the “translation layer,” which is not an official term, so that Windows knows how to drive the hardware and make it work for your use.

PowerShell providers are drivers for PowerShell to navigate things besides the file system. Providers allow PowerShell to traverse the Registry, the File System, Windows Management Instrumentation (WMI) functionality, and more. Third parties can create providers: For example, there is a SQL Server provider that Microsoft installs that lets you do PowerShell operations on databases.

How providers work

Providers take some collection of something — whatever resource they are trying to enable for PowerShell management — and make it look like a file system or disk drive to PowerShell. Providers are used by all sorts of software packages that support PowerShell for administration, like Internet Information Services (Microsoft’s web server) and Active Directory.

This is one of PowerShell’s key extensibility features, because any resource or data to be managed always shows up like a drive. In addition, new commands can be added that interact with the same data storage, whether that’s a database or a list of administrative settings for a website or a mailbox store or anything else, really. It’s kind of cool.

How do you know what providers you already have? PowerShell does indeed ship with some. You can use the Get-PSProvider command to find out which ones.

Provider capabilities and drives

The names of the providers are fairly obvious. PowerShell can make all these items look like disk drives: Aliases, the environment (which includes environmental variables like PATH and more), the FileSystem, functions, the Registry, and any defined variables. So I can reach in and touch data or records in any one of these “places” just by cd:ing around and adding path-like statements to get to where I want to be. When you use a provider, you are technically creating a PSDrive, and that PSDrive is the representation of the storage or resource you are connecting to as the file system on a disk.

The other columns in the list are capabilities and drives.

Capabilities are a list of ways to use, and things you can (and can’t) do with each provider. For the purposes of this article, we won’t worry about them.

Drives, on the other hand, are the logical access point for providers. They’re like drive mappings in Windows that you would use to make, say, Drive M: represent a share and its contents on another computer. For instance, if we were working with the Registry provider, the “drive letter” used to spelunk around and do things would be HKLM and HKCU. So we might want to change “directory” to HKLM and do a directory listing to see what was available to manage, in which case we would use the Set-Location cmdlet to change the shell’s current container to the container you want.

Here’s what that looks like when I issue Set-Location hklm: at the prompt; take a look at the screenshot below.

You can see that dir listed out the main areas of the Registry, including HKEY_LOCAL_MACHINEHardware, HKEY_LOCAL_MACHINESoftware and so on. You work the tree by using it like a file system.

I’m hoping this is starting to make sense to you.

Items

You generally use the item set of cmdlets to interact with PSDrive providers. If you continue to consider working with providers like working with a file system, then instead of files and folders, think items. They’re called items whether you’re calling registry items or SQL Server databases. Items is a nice generic term that can be used interchangeably.

How do you figure out what the item cmdlets are? Why, you’d use Get-Command, of course!

The ones we care about are the cmdlets. Looks like we can clear the value of items, copy them, get information about them, start them, move them, create new items, remove and rename items, set them, and more.

Most of the item set of cmdlets have a -path parameter that accepts wildcards like *, but this brings up an important point. Precisely because providers support so many different types of storage and resources, there may be cases in which the wildcard is actually a valid, legal, specific input for a given provider. But if you use the wildcard with PowerShell, the system will get confused.

So, for providers that allow the standard wildcard characters as legal characters in names, you can use the -literalpath instead of just -path to tell PowerShell to treat the asterisk as an asterisk and not as a wildcard.

Let’s dig in a little further to items. Items have properties, which are basically characteristics about the item. If I have a file, then I have the date that file was created (a property), the date it was modified (a property), whether or not it is read-only or writeable (a property), and so on. If I have a Registry key, I have its location (a property), its type (a property) and so on. Items can also have child items, or items within that item. Again using the file system example, folders can have folders within them and within a folder can be files.

When you want to create a new item, in many cases you have to tell PowerShell what kind of item to create. As I show in the following figure, the Show-Command entry for New-Item demonstrates that -ItemType is a parameter I can specify.

PowerShell sometimes tries to guess what kind of item you should create based on the provider you are currently working with, but it doesn’t always guess correctly. So if I’m in C:WindowsSystem32 and I want to create a new directory called jhtest with PowerShell, I would use New-Item -Path jhtest -ItemType directory so PowerShell knew that I want a directory and not a file. If you don’t specify, then PowerShell will give you a little prompt that looks like:

```

Type:

```

And you will need to specify the type of new item that you want to create.

Differences in providers matter

It is important to remember that in PowerShell, not every provider has the same capabilities. Some work when others don’t, depending on the scenario. Some providers let you access different things than others; some do it in different ways; and some don’t work at all.

That’s why you always have to think about what capabilities each provider has when building commands using a PSDrive provider, and you must always remember that when you are working with a provider with which you are unfamiliar, be sure to run Get-PSProvider to understand its capabilities. Even if a command seems like it would work, the context of the provider in which you are running that command matters a great deal.

A provider example: The Registry

The best way to learn is with a hands-on example, and I can think of no better than changing the registry exclusively through the use of PowerShell. Our task is to turn off Wi-Fi Sense in Windows 10. Although the Anniversary Update of Windows 10 killed this feature, for the most part, for anyone who hasn’t upgraded to the Anniversary Update, you can still follow along.

(What is Windows 10 Wi-Fi Sense? It is Windows 10 automatically sharing wireless network passwords with your friends. In the Anniversary Update, Wi-Fi Sense is used only to connect you to open Wi-Fi hotspots that it knows through crowdsourcing — in other words, if you’re near a publicly open Wi-Fi hotspot, you’ll be automatically logged in.)

Surely, since Wi-Fi Sense is a configuration setting within the Windows operating system, the actual place for that setting and its status is stored is in the Registry. I Googled around for a couple of minutes and was able to find that, at least in the RTM build of Windows 10 (build number 10240 to be exact), the Registry setting for this feature was at:

“`

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWcmSvcwifinetworkmanagerconfig

“`

The actual setting is actually controlled by a DWORD value called, affectionately, AutoConnectAllowedOEM — and to turn it off, we need to set its value to 0.

Now that the task has been laid out before us, it’s time to get to work. From a PowerShell console, let’s get into the PSDrive for the Registry.

```

Set-Location -path HKLM:

```

You can do a quick dir to make sure you’re in the right spot. You can also notice that the PowerShell prompt changes to HKLM to reflect your current location. It’s all good right now. Let’s actually just go ahead and get further into the registry, all the way down to the location I identified above that I got from my Google research:

```

Set-location –path hklm: SOFTWAREMicrosoftWcmSvcwifinetworkmanagerconfig

```

Let’s do another quick dir to see what there is to see. From the report, do you see the value AutoConnectAllowedOEM that we need to create?

I don’t, so that means we actually need to create the value. For this, we would use…

…yes, the New-Item cmdlet. Here are a few ways we could go about this:

  • New-Item alone at the command prompt with nothing else would prompt PowerShell to prompt us (that’s a lot of prompting, folks!) for all of the required parameters.
  • We could use Get-Help New-Item to read about what we could do with this command.
  • We could also use Show-Command new-item in order to guide us graphically.
  • .

Use whichever of those combinations feels right to you. Either way, you should end up alongside me with the following command put together:

```

New-Item -path AutoConnectAllowedOEM -type DWORD -value 0

```

In the case of this specific New-Item command, -Path is the name of the key that we want to create, since the path refers to the way to get to the object. We’re creating a new DWORD object in the registry, so -type would be DWORD, and of course we know from our research that the -value of this new key would need to be 0.

Voila! You have successfully managed the Registry using nothing but PowerShell. But just think for a minute: Literally every configuration setting within the Windows operating system is managed through the Registry, so that means you just gained the skill to interact with and change Registry settings exclusively through scripting. More power to you!

Introducing modules and snap-ins

The modules feature is where PowerShell gets its ability to address a ton of different products and services from within one shell environment. Adding modules lets PowerShell work with different features, functions and configurations from all sorts of different software, from both Microsoft and from third parties, just by importing modules full of cmdlets and their reference information, or by adding a snap-in. What are modules? What are snap-ins? Let’s do some rudimentary definition work up front so we can get it out of the way.

  • Modules are nice, neat containers of PowerShell functionality that extend the namespace and targeting power of PowerShell to other pieces of hardware and software. Modules are the de facto way of enabling PowerShell extensibility these days, and most server products that run on Windows come with modules for extending PowerShell, including all Microsoft server products from 2010 onward (and in some cases even before then).
  • Snap-ins — or in proper PowerShell terminology PSSnapins — is basically a set of DLL files that have accompanying XML files that contain configuration information and the text that displays when you ask for help via Get-Help. Snap-ins were part of the first release of PowerShell back in the mid 2000s, and you will see fewer of these types of extensions as time goes in as Microsoft and third parties replace them with modules. So for that reason, in this article I’ll talk just about modules.

Modules

Modules are, at this point, far and away the most common type of PowerShell extensibility feature you will see. Modules are basically containers filled with all of the information PowerShell needs to work with a given piece of hardware or software, including the commands, the libraries necessary to get those commands to work, the help text, and any configuration information that might be required. Modules exist to remedy a lot of the things that make snap-ins sort of unwieldy and difficult to consume and distribute.

PowerShell looks for modules in certain directories on your system. You place the modules in that directory, and that’s it; PowerShell handles the rest. You don’t have to register them or perform any other steps. There is a PowerShell variable called PSModulePath that contains the directories where PowerShell is going to look for modules on your system, and since there are usually multiple directories to search for modules in, each directory is separated by a semicolon with no spaces. No quotes are required here. How can you, ahem, *get* the *content* of this variable?

```

Get-Content env:PSModulePath

```

You either put paths in this directory, or you add the directory where other modules reside on your system to this path entry, which you can find in the Windows Control Panel. If I were you, I would just move modules into one of the two default directories and worry about other things.

What is particularly nice about modules is that, since they are stored in defined locations that PowerShell knows about in advance, they can be discovered automatically by the shell. So you get the advantage of being able to look for commands and have the help for a bunch of commands in a namespace that may or may not have been explicitly loaded yet, because PowerShell knows to look in *all* of the modules, not just the ones it has actively loaded.

This is how you get the benefit of tab completion and (at least in the Windows PowerShell Integrated Scripting Environment) IntelliSense without having to manually add a zillion modules to your session each and every time you want to run a command.

If you have a module stored somewhere else, which is something that happens rather frequently with third-party PowerShell modules, then you can import the module manually into your session by specifying the full path to the module with the Import-Module command.

```

Import-Module c:powershellmodulesthirdpartycoffeemaker

```

Modules can also add providers, which will then allow you, as you know, to walk up and down the configuration structure for a piece of software (or hardware, I suppose). To see whether any new providers were added when you added a module to your session, you can use the standard Get-PSProvider command we talked about in the previous half of the article. You’ll see a list of names, capabilities and drives you can use with this new module.

The last word

As I mentioned, my goal for this piece was to show you more of the most important features of PowerShell. You even got to dive in deep into the Registry with your beginner PowerShell skills and turn off an important feature in Windows 10. Well done, ladies and gentlemen! Onward!