Huh, isn't that strange? When you open a PowerShell console bundled with SQL Server or Exchange 2007, it supports a lot more cmdlets (to manage SQL Server or Exchange, for example) than regular powershell.exe does. Where do those extra Cmdlets come from, and more importantly, can you use them in plain powershell.exe or PowerShellPlus as well?
Snapins: Brain Extensions for PowerShell
Fortunately, yes, because every single Cmdlet is part of a Snapin. Even the basic set of 129 or so Cmdlets comes wrapped up as Snapins, and Get-PSSnapin lists all the snapins you have currently loaded:
PS> Get-PSSnapin
Name : Microsoft.PowerShell.Core
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains Windows PowerShell management cmdlets used to manage components of Windows PowerShell.
Name : Microsoft.PowerShell.Host
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains cmdlets used by the Windows PowerShell host.
Name : Microsoft.PowerShell.Management
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains management cmdlets used to manage Windows components.
Name : Microsoft.PowerShell.Security
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains cmdlets to manage Windows PowerShell security.
Name : Microsoft.PowerShell.Utility
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains utility Cmdlets used to manipulate data.
Snapins are storage containers for two completely different things:
- additional Cmdlets
- additional Providers
Let's take a closer look at Cmdlets and Providers.
Snapins: Home to all your Cmdlets
Of course you know what a Cmdlet is: a basic PowerShell command just like get-childitem or get-service. Every single Cmdlet was brought to you by a Snapin. To see all the Cmdlets from a specific Snapin, use Get-Command with the parameter -pSSnapIn. So you could check out which Cmdlets come with any one of the Microsoft Snap-Ins. Or even more useful, once you add a new Snapin, you can easily create a list of all the new Cmdlets to play with them and find out what they can do for you (more about adding new Snapins in a second).
PS> Get-Command -pSSnapIn Microsoft.PowerShell.Core
CommandType Name Definition
----------- ---- ----------
Cmdlet Add-History Add-History [[-InputObj...
Cmdlet Add-PSSnapin Add-PSSnapin [-Name] <S...
Cmdlet Export-Console Export-Console [[-Path]...
Cmdlet ForEach-Object ForEach-Object [-Proces...
Cmdlet Get-Command Get-Command [[-Argument...
Cmdlet Get-Help Get-Help [[-Name] <Stri...
Cmdlet Get-History Get-History [[-Id] <Int...
Cmdlet Get-PSSnapin Get-PSSnapin [[-Name] <...
Cmdlet Invoke-History Invoke-History [[-Id] <...
Cmdlet Remove-PSSnapin Remove-PSSnapin [-Name]...
Cmdlet Set-PSDebug Set-PSDebug [-Trace <In...
Cmdlet Where-Object Where-Object [-FilterSc..
If you would like to find out where a specific Cmdlet came from, you can use get-command to access the Cmdlet in question and then query its PSSnapin property like this:
PS> (Get-Command Get-ChildItem -commandType Cmdlet).PSSnapIn
Name : Microsoft.PowerShell.Management
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains management cmdl
ets used to manage Windows components.
PS> (Get-Command Set-ExecutionPolicy -commandType Cmdlet).PSSnapIn
Name : Microsoft.PowerShell.Security
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains cmdlets to mana
ge Windows PowerShell security.
You can also create a list of Cmdlets and group them by Snapin like this (thanks to Alex for pointing me at this):
PS> Get-Command -commandType Cmdlet | sort pssnapin, name | ft name
-groupBy pssnapin | more
PSSnapIn: Microsoft.Exchange.Management.Powershell.Support
Name
----
Get-DatabaseEvent
Get-DatabaseEventWatermark
PSSnapIn: Microsoft.PowerShell.Core
Name
----
Add-History
Add-PSSnapin
Export-Console
ForEach-Object
Get-Command
Get-Help
Get-History
Get-PSSnapin
Invoke-History
Remove-PSSnapin
Set-PSDebug
Where-Object
PSSnapIn: Microsoft.PowerShell.Host
Name
----
Start-Transcript
Stop-Transcript
PSSnapIn: Microsoft.PowerShell.Management
Name
----
Add-Content
<SPACE> next page; <CR> next line; Q quit
Providers: Navigate your World!
Sophisticated snapins often also contain Providers. Providers are responsible for navigating hierarchical data structures. In short, providers turn any information store into a drive. Check out your existing Providers with Get-PSProvider:
PS> Get-PSProvider
Name Capabilities Drives
---- ------------ ------
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess {C, S, D, E}
Function ShouldProcess {Function}
Registry ShouldProcess {HKLM, HKCU}
Variable ShouldProcess {Variable}
Certificate ShouldProcess {cert}
PS> Get-PSProvider | Format-Table Name, Drives, PSSnapin -autosize
Name Drives PSSnapIn
---- ------ --------
Alias {Alias} Microsoft.PowerShell.Core
Environment {Env} Microsoft.PowerShell.Core
FileSystem {C, S, D, E} Microsoft.PowerShell.Core
Function {Function} Microsoft.PowerShell.Core
Registry {HKLM, HKCU} Microsoft.PowerShell.Core
Variable {Variable} Microsoft.PowerShell.Core
Certificate {cert} Microsoft.PowerShell.Security
Note that the default output focusses on the actual drives that make use of your Providers, and as you can see, the Registry Provider is used by the "drives" HKLM: and HKCU:. This is why you can navigate the Windows Registry just as easily as a plain old hard drive when using PowerShell: Dir HKCU\Software.
However, the default output does not tell you where the Providers came from. To find out, use Format-Table to choose yourself which object properties you would like to see, and include the property PSSnapin. There you go: the Registry Provider was brought to you by the Microsoft.PowerShell.Core Snapin.
Adding More Cmdlets to your PowerShell Host
Now, how do you add additional Snapins to PowerShell to get access to more Cmdlets and Providers? Well, it is a two-step process.
First take a peek into the Snapin repository to find out which Snapins are available on your system. You get this list with Get-PSSnapin and the parameter -registered. Note: If you omit the parameter -registered, you will see the Snapins that you already loaded into PowerShell. With the parameter -registered, you see all Snapins that are registered on your machine but not necessarily loaded yet.
PS> Get-PSSnapin -registered
Name : Microsoft.Exchange.Management.PowerShell.Admin
PSVersion : 1.0
Description : Admin Tasks for the Exchange Server
Name : Microsoft.Exchange.Management.Powershell.Support
PSVersion : 1.0
Description : Support Tasks for the Exchange Server
Name : Microsoft.Office.OneNote
PSVersion : 1.0
Description : Provides cmdlets for managing OneNote notebooks.
Name : Microsoft.SystemCenter.VirtualMachineManager
PSVersion : 1.0
Description :
Name : Netcmdlets
PSVersion : 1.0
Description : /n software NetCmdlets
Name : Pscx
PSVersion : 1.0
Description : PowerShell Community Extensions (PSCX) base snapin wh
ich implements a general purpose set of cmdlets.
Name : Quest.ActiveRoles.ADManagement
PSVersion : 1.0
Description : Registers the CmdLets and Providers in this assembly
Depending on the software installed on your system, you see a whole bunch of Snapins (or none at all). There are four crucial things to note here:
- All Standard Snapins like Microsoft.PowerShell.Core are not listed here. Standard PowerShell Snapins cannot be loaded or unloaded. Standard Snapins are "always on".
- Snapins are specific to your platform type so when you install 64bit Snapins on a 32bit System, they do not work and will not be shown in the above list. Vice versa, a 32bit Snapin will not show on a 64bit machine in a 64bit process.
- As you can see, all the "specific" Cmdlets and Providers that come with software like Exchange are really just Snapins that you can easily load and use in any PowerShell host as you will see in a second.
- Snapins need to be registered on your machine before you can load them. Registration requires Admin privileges and is one of the design flaws in PowerShell V1. Commercial snapins will register themselves when you install them. Snapins that come without installer, just as a plain DLL, need to be registered manually using INSTALUTIL.EXE. Registration basically consists of a number of registry entries in HKLM where PowerShell looks for available Snapins. You can as well add those Registry entries manually.
To actually use one of the listed Snapins, use Add-PSSnapin. I'd like to load the fabulous and free Pscx Snapin (http://www.codeplex.com/PowerShellCX) and then create a list of all the new Cmdlets I got:
PS> Add-PSSnapin pscx
PS> Get-Command -pSSnapIn Pscx | sort Name
CommandType Name Definition
----------- ---- ----------
Cmdlet ConvertFrom-Base64 ConvertFrom-Base64 [-B...
Cmdlet ConvertTo-Base64 ConvertTo-Base64 [-Pat...
Cmdlet ConvertTo-MacOs9LineEn... ConvertTo-MacOs9LineEn...
Cmdlet ConvertTo-UnixLineEnding ConvertTo-UnixLineEndi...
Cmdlet ConvertTo-WindowsLineE... ConvertTo-WindowsLineE...
Cmdlet Convert-Xml Convert-Xml [-Path] <S...
Cmdlet Disconnect-TerminalSes... Disconnect-TerminalSes...
Cmdlet Export-Bitmap Export-Bitmap [-Bitmap...
Cmdlet Format-Byte Format-Byte [-Value] <...
Cmdlet Format-Hex Format-Hex [-Path] <St...
Cmdlet Format-Xml Format-Xml [-Path] <St...
Cmdlet Get-ADObject Get-ADObject [-Domain ...
Cmdlet Get-Clipboard Get-Clipboard [-Text] ...
Cmdlet Get-DhcpServer Get-DhcpServer [-Serve...
Cmdlet Get-DomainController Get-DomainController [...
Cmdlet Get-ExportedType Get-ExportedType [-Ass...
Cmdlet Get-FileVersionInfo Get-FileVersionInfo [-...
Cmdlet Get-ForegroundWindow Get-ForegroundWindow [...
Cmdlet Get-Hash Get-Hash [-Path] <Stri...
Cmdlet Get-MountPoint Get-MountPoint [[-Volu...
Cmdlet Get-PEHeader Get-PEHeader [-Path] <...
Cmdlet Get-Privilege Get-Privilege [[-Ident...
Cmdlet Get-PSSnapinHelp Get-PSSnapinHelp [-Pat...
Cmdlet Get-Random Get-Random [-Verbose] ...
Cmdlet Get-ReparsePoint Get-ReparsePoint [-Pat...
Cmdlet Get-ShortPath Get-ShortPath [-Path] ...
Cmdlet Get-TabExpansion Get-TabExpansion [-Lin...
Cmdlet Get-TerminalSession Get-TerminalSession [[...
Cmdlet Import-Bitmap Import-Bitmap [-Path] ...
Cmdlet Join-String Join-String [-Strings]...
Cmdlet New-Hardlink New-Hardlink [-Path] <...
Cmdlet New-Junction New-Junction [-Path] <...
Cmdlet New-Shortcut New-Shortcut [-Path] <...
Cmdlet New-Symlink New-Symlink [-Path] <S...
Cmdlet Out-Clipboard Out-Clipboard [-InputO...
Cmdlet Ping-Host Ping-Host [-HostName] ...
Cmdlet Remove-MountPoint Remove-MountPoint [[-N...
Cmdlet Remove-ReparsePoint Remove-ReparsePoint [-...
Cmdlet Resize-Bitmap Resize-Bitmap [-Bitmap...
Cmdlet Resolve-Assembly Resolve-Assembly [-Nam...
Cmdlet Resolve-Host Resolve-Host [-HostNam...
Cmdlet Select-Xml Select-Xml [-Path] <St...
Cmdlet Send-SmtpMail Send-SmtpMail [-InputO...
Cmdlet Set-Clipboard Set-Clipboard [-Text <...
Cmdlet Set-FileTime Set-FileTime [-Path] <...
Cmdlet Set-ForegroundWindow Set-ForegroundWindow [...
Cmdlet Set-Privilege Set-Privilege [-Privil...
Cmdlet Set-VolumeLabel Set-VolumeLabel [[-Pat...
Cmdlet Split-String Split-String [[-Separa...
Cmdlet Start-Process Start-Process [[-Path]...
Cmdlet Start-TabExpansion Start-TabExpansion [-V...
Cmdlet Stop-TerminalSession Stop-TerminalSession [...
Cmdlet Test-Assembly Test-Assembly [-Path] ...
Cmdlet Test-Xml Test-Xml [-Path] <Stri...
Cmdlet Write-BZip2 Write-BZip2 [-Path] <S...
Cmdlet Write-Clipboard Write-Clipboard [-Obje...
Cmdlet Write-GZip Write-GZip [-Path] <St...
Cmdlet Write-Tar Write-Tar [-Path] <Str...
Cmdlet Write-Zip Write-Zip [-Path] <Str...
Test-Driving a Microsoft Office OneNote PowerShell Provider
Ok, so Snapins bring additional fun with new Cmdlets, enabling you to ZIP-compress files or send out emails. They often also contain additional Providers, turning even more data stores into the paradigm of PowerShell drives.
For example, the Pscx Snapin comes with an Active Directory provider that enables you to navigate your AD structure just like your hard drive. All you need to make sure is that you are actually logged on to a domain.
The virtual AD drives' name is your AD name. If in doubt, use Get-PSDrive to list all your virtual PowerShell drives, and soon you will discover the new AD drive. Use New-Item to create new organizational units or users just as you would create new folders and files in a traditional drive.
However, be careful because automation works both ways and can easily be a career limiting move. When you Remove-Item the root of your AD, you will see (a) if permissions are set correctly in your AD and (b) if they had been set incorrectly, how fast PowerShell can wipe out your entire AD.
The concept of Providers can be extended to a ton of scenarios, and if you happen to use Microsoft OneNote, you may be thrilled to learn that a PowerShell Provider for OneNote exists. Here is where you can get it: http://bdewey.com/2007/07/18/onenote-powershell-provider/ It is free and comes with full sources, so it may in fact also be a great starting point for anyone wanting to learn how to write Providers. Note: To install the Provider, OneNote needs to be present on your system. And no, OneNote does not come with most Office packages, it often is an extra download.
Remember that once you installed the new Snapin, you need to load it using Add-PSSnapin before you can start to automate OneNote from PowerShell. The OneNote Provider creates a new virtual PowerShell drive called OneNote:. You can now browse through your existing Notebooks or create a new one and populate it with data. The next couple of lines of code add a new OneNote notebook called "SystemInfo" with two pages called "Processes" and "Services". Then, PowerShell actually populates these pages with the current list of processes and services:
PS> # create a new notebook in the temp folder:
PS> New-Item onenote:\SystemInfo -type Notebook -value $env:temp
PS> # create a section with two pages:
PS> New-Item onenote:\SystemInfo\Section -type Section
PS> New-Item onenote:\SystemInfo\Section\Processes -type Page
PS> New-Item onenote:\SystemInfo\Section\Services -type Page
PS> # populate pages with actual system info content
PS> Get-Process | Out-String | Add-Content onenote:\SystemInfo\Section\Processes
PS> Get-Service | Out-String | Add-Content onenote:\SystemInfo\Section\Services
The result is displayed in OneNote, and from here you could export it to PDF or process the information in any other way you want (please apologize but the OneNote you see below comes from a German system):

If you'd like to know what Cmdlets the OneNote provider brings to you, you could filter the output from Get-Command if you're too lazy to specify the complete provider name:
PS> Get-Command | ? { $_.PSSnapIn.Name -like '*OneNote*' }
CommandType Name Definition
----------- ---- ----------
Cmdlet Close-OneNote Close-OneNote [[-Path]...
Cmdlet Export-OneNote Export-OneNote [[-Path...
Cmdlet Get-OneNoteHierarchy Get-OneNoteHierarchy [...
Cmdlet Get-OneNoteHyperlink Get-OneNoteHyperlink [...
Cmdlet Get-OneNotePageContent Get-OneNotePageContent...
Cmdlet Get-OneNoteTOC Get-OneNoteTOC [[-Path...
Cmdlet Open-OneNote Open-OneNote [[-FullNa...
Cmdlet Set-OneNotePageContent Set-OneNotePageContent...
PS> Get-Command -pSSnapIn Microsoft.Office.OneNote
CommandType Name Definition
----------- ---- ----------
Cmdlet Close-OneNote Close-OneNote [[-Path]...
Cmdlet Export-OneNote Export-OneNote [[-Path...
Cmdlet Get-OneNoteHierarchy Get-OneNoteHierarchy [...
Cmdlet Get-OneNoteHyperlink Get-OneNoteHyperlink [...
Cmdlet Get-OneNotePageContent Get-OneNotePageContent...
Cmdlet Get-OneNoteTOC Get-OneNoteTOC [[-Path...
Cmdlet Open-OneNote Open-OneNote [[-FullNa...
Cmdlet Set-OneNotePageContent Set-OneNotePageContent...
Managing PowerShell with PowerShellPlus
In PowerShellPlus, you can easily manage Snapins with Settings\Manage Snapins... This will open a dialog with all registered Snapins. To load and use a snapin, all you need to do is tick the checkbox.

PowerShellPlus also comes with a comprehensive learning center which will dynamically load and support any Snapin you registered. Just make sure you relaunch PowerShellPlus after you installed a new Snapin. PowerShellPlus will then discover and make available all help information from any new Snapin.
So once you installed the OneNote Snapin and relaunched PowerShellPlus, you can conveniently look up any new OneNote Cmdlet and try out the examples that come with it. Simply click on example code to have it inserted into the console for you.

You don't know PowerShellPlus yet? Try it! You can download it here.
I hope you liked this quick excurse into the world of Snapins, Cmdlets and Providers. One thing I learned today is that PowerShell adds so many useful capabilities to software like OneNote that PowerShell support will widen the target group for OneNote considerably. So if you develop software, take a look at Providers and make sure you add PowerShell support. We'll love it!
Tobias
Posted
Oct 10 2008, 02:04 PM
by
Tobias Weltner
Filed under: Add-PSSnapin, Get-PSSnapin, New-Item, InstalUtil, Cmdlet, Navigate, Provider, Snapin, Pscx, Register, OneNote