).
Some time ago I published an example of how to create a PowerShell cmdlet on my blog, "Windows PowerShell - Make your application manageable - Write your first cmdlet". As a reader pointed out, the creation of a custom shell is no longer required. At the time of writing the .NET Magazine article (Dutch), the PowerShell software hadn't reached the RC stage and I hadn't much time to mess around with the SnapIn-methodology, so it wasn't incorporated in the original article (we were happy we could get the MSH to PowerShell rename in the published article in time, as well as doing the required incompatibilies spotting to have the original code compile on the RC bits).
Today, I'm going to point out how to modify the code from the "Windows PowerShell - Make your application manageable - Write your first cmdlet" post (with the FindString cmdlet) to a SnapIn that can be registered in PSH shells on your machine, without the need for creating a new custom shell using make-shell. For the original post, see the link above. Below you'll find the stripped-down and updated version of this post using a snap-in approach.
Your first cmdlet (snap-in)
Step 1 - Create a Visual Studio project
To kick off, create a new class library project (e.g. in C#) and give it a meaningful name, for example FindString. Next, add a reference to the System.Management.Automation.dll assembly which you can find in %programfiles%\Windows PowerShell\v1.0. Include a reference to System.Configuration.Install as well.
Step 2 - Declare the cmdlet class
Next, it's time to declare our cmdlet-acting class as follows (updated using VerbsCommon, thx to Lee for his comment):
using
The class has to inherit from PSCmdlet and has to be annotated with the CmdletAttribute attribute as you can see.
Step 3 - Parameterize the cmdlet
The first parameter is called Pattern and will contain the regular expression pattern we'll look for. The second one is called FullName and can contain more than one filename, which can be fed in through the pipeline by the property name. That means that cmdlets that return objects with a public property called FullName can be linked to this cmdlet by means of piping (|), e.g. from the get-childitem cmdlet.
The core of the cmdlet's implementation goes in the ProcessRecord method. The following is a pretty short implementation of our matching logic relying on System.Text.RegularExpressions and System.IO to read files, and System.Collections.Generic for the List class:
The call to WriteObject returns the result to the pipeline for further processing; other cmdlets could use our output as their input, or the user can just feed this in to cmdlets like format-list (or work with variables, etc). To aid our implementation, we've created a simple Match class:
public
Step 5 - Create a snap-in and deploy it
Basically, a snap-in is a wrapper around one or more cmdlets that can be "imported" in a PowerShell instance. Instead of creating a separate shell (using make-shell) one can rely on snap-ins to bring custom cmdlets to Windows PowerShell.
The core of the snap-in methodology lies in the CustomPSSnapIn class from the System.Management.Automation namespace. This class inherits from System.ComponentModel.Component and thus it can be used in combination with instalers in .NET (using installutil.exe). That's how snap-ins work. In order to bring this technology to our own cmdlet-implementation, we have to do the following (with using directives for the whole codefile):
This might look quite some code at first glance, but it's really straightforward. All that you have to do over here is override from CustomPSSnapIn and provide code that returns a vendor, a name, a description and a few collections through properties. Those collections hold references to cmdlets, providers, types and format that are included in the snapin. In this case, we only include one single cmdlet which is done by preparing a Collection (from System.Collections.ObjectModel) of CmdletConfigurationEntry (from System.Management.Automation.Runspaces) instances. In our case on single entry is enough, holding the name (get-matches) and type info (typeof(FindString)). The last constructor parameter isn't used as we don't have a help file associated with the cmdlet.
Compile the whole stuff and open a Visual Studio 2005 Command Prompt (or a PS prompt if you're ambitious) and run installutil.exe against the compiled .dll file (note: on Vista, you'll have to evelate the Visual Studoo 2005 Command Prompt to run with administrative credentials in order to allow installutil.exe to write to the HKLM registry hive):
C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug>installutil.exe FindString.dllMicrosoft (R) .NET Framework Installation utility Version 2.0.50727.88Copyright (c) Microsoft Corporation. All rights reserved.
Running a transacted installation.
Beginning the Install phase of the installation.Installing Install phase completed successfully, and the Commit phase is beginning.Committing Commit phase completed successfully.
The transacted install has completed.
C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug>
Step 6 - Testing time
Launch the Windows PowerShell and display a list with registered snap-ins as follows:
PS C:\Users\Bart\Documents> get-pssnapin -registered
Name : FindStringPSSnapInPSVersion : 1.0Description : This snap-in contains the FindString cmdlet.
As you can see, the snap-in was registered successfully. However, get-matches still doesn't work:
PS C:\Users\Bart\Documents> get-matches'get-matches' is not recognized as a cmdlet, function, operable program, or script file.At line:1 char:11+ get-matches <<<<
To make it available, you have to call add-pssnapin, as displayed below:
PS C:\Users\Bart\Documents> add-pssnapin FindStringPSSnapIn
Now get-matches should work:
PS C:\Program Files\Windows PowerShell\v1.0> get-matches Wmi about_Alias.help.txt
Matches File------- ----{Wmi, Wmi, Wmi} C:\Program Files\Windows PowerShell\...
Step 7 - Taking it one step further
Performing add-pssnapin every time again doesn't boost your productivity. In order to provide easier access to your shell configuration you can export the settings using export-console:
PS C:\Users\Bart> export-console MyShell
This creates a file called MyShell.psc1 that contains the following piece of XML:
<?xml version="1.0" encoding="utf-8"?><PSConsoleFile ConsoleSchemaVersion="1.0"> <PSVersion>1.0</PSVersion> <PSSnapIns> <PSSnapIn Name="FindStringPSSnapIn" /> </PSSnapIns></PSConsoleFile>
You can now open your customized shell using powershell.exe by specifying the psc1-file as a parameter (or create a shortcut of course):
powershell -PSConsoleFile c:\users\bart\myshell.psc1
Have fun!
So here's a new tool for my personal toolbox: a simple MD5 checksum calculator for files, written in .NET 2.0.
The little "open Visual Studio 2005 trigger" story: A friend of mine reported a problem with his Vista Beta 2 installation which reported corruption, so the obvious first check was to calculate the MD5 checksum. However, a 5-seconds internet search didn't provide me with a simple tool, so I took the do-it-yourself-in-5-minutes approach and wrote such a tool myself.
In the end, the code comes down to:
string
but of course I made it a little more fancy, with the new System.Console capabilities to put a "spinner" and the elapsed time on the screen (using System.Diagnostics.Stopwatch) while calculating the checksum (you know, a little thingie that does | / - \ continiously) using a background thread. I also found out the following thanks to IntelliSense:
Console
The result is a little .exe that can be downloaded over here. I'll create a PowerShell cmdlet for the same task as well, which I'll publish over here too.
Here's the Windows Vista Ultimate Beta 2 x86 DVD ISO MD5 output (elapsed time for an Intel Centrino Duo 2.16 GHz + 2GB RAM running Windows Vista Beta 2):
MD5 File Checksum Calculcator 1.0.0.0Copyright (C) BdsSoft 2006. All rights reserved.
Calculating checksum...
Results-------File: d:\Downloads\en_windows_vista_beta2_x86_dvd.isoMD5 checksum: 0e733ab1a8e8ff9a8684fd3639332773Elapsed time: 00:01:06.2558607
Another example of BCL power and richness...
Update: A SHA1 checker is available too over here (using the HashAlgorithm.Create factory method this was a matter of seconds). Output for Windows Vista Ultimate Beta 2 x86 DVD ISO (matches the MSDN Subscribers SHA1 checksum):
SHA1 File Checksum Calculcator 1.0.0.0Copyright (C) BdsSoft 2006. All rights reserved.
Results-------File: d:\Downloads\en_windows_vista_beta2_x86_dvd.isoSHA1 checksum: 2404153a60d81103861b876878893222a5529d3aElapsed time: 00:01:39.4758180
Rather calm on my blog lately due to a high workload. So, let's give a little overview of some recent hot releases that are worth to check out in case of some spare free time. This summer, I'll try to put some more serious posts on the web over here.
Here we go:
I'm sure I've forgotten a bunch of great releases in this list but I'm sure you'll find those exciting materials when you need them :-).
A few days ago, Microsoft released the first CTP of SQL Server 2005 Everywhere Edition, the successor to SQL Server CE. You can download it over here, as well as the mandatory Books Online that accompany every SQL Server release :-). Check out the SQL Mobile blog as well, on.
So, what's in a name. Basically, SQL Server Everywhere is targeted at smart devices (Pocket PC 2003, Windows CE 5.0 and WM 5.0 based devices) as well as Tablet PC s, and provides a compact but feature-rich database engine. By means of subscriptions, it's possible to synchronize this (off-line) database with a "big brother" in SQL Server 2005. Furthermore, the product is free to redistribute with your applications (which can be automated using VS2005 features such as ClickOnce).
For a complete feature list, check out the BOL.
Formerly called WinFX, the official name of the piece of software art is now called .NET Framework 3.0. The technology is based on .NET Framework 2.0 and bundles the following next-generation internet-enabling technologies that are considered key pillars of the Vista wave (but will be available for XP and W2K3 as well):
Quite a bunch of .NET heroes are blogging about this, including 'Soma' and Jason Zander. Notice LINQ stuff goes in the Orcas timeframe, which is coming after Vista.
More information on the brand new site. And now I'm in the mood of giving away links to interesting sites, take a look at as well for information on the next-generation webserver technology: IIS 7.
So, here we are, live on Vista Beta 2 and running the 2007 Microsoft Office System Beta 2 for day-to-dat activities. Last weekend I moved from the previous Vista CTP build - which was running on a rather small partition just for sake of demos - to the beta 2 stage running on my main partition. And it's just running soooo smoothly, I absolutely love it. The same holds for the 2007 Office tools which I'm working with every day right now. One thing I love about Word 2007 is the new equation editor, as I'm writing a lot of math the last couple of weeks.
Oh, and I also enabled BitLocker Drive Encryption (I never trusted that before the beta stage, shame on me), so my personal stuff is absolutely secure against theft (the key is kept on a USB stick, as I don't have a TPM in my machine).
Usually I don't show my desktop to everyone, but here's a little screenshot (click to enlarge).