SnapInini - Lite portable SnapIns with no need of registration/installation.
June 7th, 2008 by KarlOne thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn’t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I’d start a blog series covering it. I call them Snapininis or SnapIn-Lites. A good thing is you can achieve the same end result in PowerShell V2 with modules - but that is V2 and a while away from being released, and then even further away from being fully deployed.
So how does this work?
1) you have to load an assembly into memory in powershell that contains your snapin.
2) you add the cmdlets directly into the runspace that is running and tell powershell to update its list of cmdlets.
Here is the C# code for a sample barebones SnapInini.
using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace Snapinini
{
public class DynamicCmdLet
{
public static void Load()
{
CmdletConfigurationEntry conf = new CmdletConfigurationEntry("dummy-cmdlet", typeof(ForeachDictionaryCmdLet), null);
Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Append(conf);
Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Update();
Runspace.DefaultRunspace.CreateNestedPipeline(
"new-alias dcmd dummy-cmdlet; write-host ’snapinini loaded’",
false).Invoke();
}
}
[Cmdlet("dummy", "cmdlet")]
public class ForeachDictionaryCmdLet : System.Management.Automation.PSCmdlet
{
protected override void EndProcessing()
{
WriteObject("hello from the dummy cmdlet");
}
}
}
In the above sample I have a very very simple cmdlet. You can see that i get the defaultrunspace, go into its RunspaceConfiguration and add the cmdlets and update the list. I am additionally running some powershell script that adds an alias to the cmdlet and writes a message to the screen just as an example showing you that you can do more stuff if you wish. In the above code the load is a static method so its easy to call from powershell once you’ve loaded the assembly, but in all honesty the Load() code could just as well have been written in the calling PowerShell.
So how do we load and use this in PowerShell?
[system.Reflection.Assembly]::LoadFrom("snapinini.dll")
[snapinini.DynamicCmdLet]::load()
dummy-cmdlet
dcmd
Where to from here? This example is very simple, you could easily add multiple cmdlets into the equation, specify help files, add custom type definitions etc. Another thing I had experimented with is taking a real snapin and using reflection to see the cmdlets in it and adding them directly, however unless you know exactly what a snapin does this is dangerous because in its registration it might set up a bunch of other things also that are important.
Another thing I should cover next time is a safe way to load assemblies from any location and ensure that all their references get resolved seamlessly.
-Karl
Posted in Bare Metal, Powershell |

Entire RSS