22

11/10

Making PowerShell Play Nice With .NET

09:32 by rleahy. Filed under: Technology

Before we get started, let me just say that I love PowerShell.  Any hope that Linux had of wooing me with Python/Perl/BaSH evaporated when Microsoft released PowerShell, because it can do everything you’d want a shell to do and more.

Now that that’s out of the way, let me say that sometimes—even though it’s built right on top of .NET—getting PowerShell to play nice with the Framework, and/or the things you wrote in C#, is kind of a pain in the ass.

Not a complicated, convoluted pain in the ass, like anything that has anything remotely to do with Linux, but more the “what the hell?” irritation you get when something has bad HCI.

The first pain in the ass is calling methods from the Framework.  PowerShell has this very nice and feature-complete set of cmdlets and language features that manage to wrap a lot of the things you might otherwise need the Framework for, but sometimes you just need to join two file paths together, and you’re too lazy to use string concatenation (especially when the format of the two paths you’re joining isn’t predictable, getting regex involved and…).

The solution: Your gut instinct was probably to try something like System.IO.Path.Combine(), but then PowerShell yelled at you.  Turns out that PowerShell’s designers opted for some weird bastardization of C#’s Namespace Alias Qualifier syntax.  What you have to do is type the leading part of the class/method (i.e. the namespace and class, and perhaps sub-class(es)) in square brackets, append that with two colons, and then put the name of the method.  So the example from above becomes [System.IO.Path]::Combine(), which works.

With some classes—Regex, for example—you mysteriously don’t need to include the namespace, so it’s [Regex]::Match().

Also keep in mind that while C# may be case sensitive, PowerShell is not, so you don’t need to be a capitalization Nazi even when calling the .NET Framework classes/methods directly from PowerShell.

The second pain in the ass is classes with custom indexers.  In C# this is wonderful—array-like indexing into classes wherein such indexing makes sense—but it doesn’t work quite so fluidly for PowerShell (for whatever reason), and trying to use this syntax will cause red text to appear.

A little poking around in the documentation for a few classes that have these indexers reveals that the custom indexers are actually syntactic sugar for calls to a property called Item, which takes arguments.

You can perform this type of call in PowerShell:

$myindexeditem.Item($itemindex)

for objects with more than one argument to their indexer, just send more than one argument to Item.

That’s all for now, get out there and write even sweeter PowerShell scripts, armed with this new knowledge.