Extending PowerShell with Snapins (and Microsoft OneNote)

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:

  1. All Standard Snapins like Microsoft.PowerShell.Core are not listed here. Standard PowerShell Snapins cannot be loaded or unloaded. Standard Snapins are "always on".
  2. 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.
  3. 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.
  4. 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

Comments

powershell cmdlets « My Work Blog wrote powershell cmdlets &laquo; My Work Blog
on 05-07-2010 6:08 PM

Pingback from  powershell cmdlets « My Work Blog

Copyright 2012 PowerShell.com. All rights reserved.