One of the problems that comes along with writing my own blog on software development is that I often expose my own ignorance. I don’t pretend to know everything, by any stretch of the imagination, but writing stuff that anyone can read comes with a modicum of “assumed authority,” which I clearly don’t have. However, I sometimes stumble across things that are so cool that I just have to write about them, no matter how behind-the-times they may make me look. So, I’ll just come out and say it now: Powershell rocks my world.
Yesterday I was dinking around with a web-forms app that required some mildly tricky string manipulation. When coding in Visual Studio, I’ve often found myself wishing that there were some way to use the Immediate Window to evaluate runtime behavior at design time. For example, I can never remember string formats. The .ToString(“format”) method is extremely common, but I’ve already got too much crap crammed in my skull to remember all of the possible values for “format.” What I’ve always done in the past is fire up my project in Debug mode, put a breakpoint somewhere, and then use the Immediate Window to figure out which argument I need to pass to ToString(). There’s probably a better way to do this in general, but somehow my string of searches yesterday led to Powershell, and goodness am I happy about it. It’s not that I didn’t know that Powershell existed. Brad’s been singing its praises forever. I just never took the time to understand how powerful it is.
A known bug with the Immediate Window that I don’t believe has been solved yet is the “'RegularExpressions' is not a member of 'Text'” exception. If you’ve ever tried to execute RegularExpressions in the Immediate Window, you’ve probably seen this. After downloading and installing Powershell, I started out working on how to test the evaluation of a Regex.Replace() statement. First, I had to figure out how to get the System.Text.RegularExpressions namespace loaded. I found a nice blog post that taught me how to do that, and I’m pretty sure that you can have a Powershell script execute on launch as part of your profile. This little guy will definitely be a part of it when I have time to figure it out.
1: PS > $GacRootDir = Join-Path -Path $Env:SystemRoot -ChildPath "Assembly/Gac"
2: PS > Get-Childitem -path $GacRootDir -recurse -include *.dll| Foreach-Object {$_.FullName} | Foreach-Object {([Reflection.Assembly]::LoadFrom($_))}
After that, most of what you can do is a matter of learning the syntax, and for a guy who spent the first six-odd years of his programming career using VIM in command prompts, I must admit that it’s strangely comforting to get back to a little command-line scripting. Once my GAC assemblies were loaded, I set about solving my string manipulation problem. Specifically, I needed to set a NavigateUrl property to a UNC path, which then got sent to a JavaScript method. The code-behind is VB, but JavaScript, of course, likes it’s back-slashes to be escaped like C#. For some reason my brain thought that I should use Regex.Replace() for this (maybe scripting reminded me enough of Perl that I wanted to do a little $foo =~ s/\\/\\\\/g; or something). Testing this in Powershell was simple:
Lovely. Really, it was. I didn’t have to fire up a debugging session to find out that Regex.Replace() is going to be funny about back-slashes too, which, if I’d actually taken two seconds to think, I would have already known. Then, I remembered String.Replace():
I know, I know, this is elementary stuff. But the beautiful thing to me here is that Powershell let me do this in a matter of seconds at design-time rather than having to write a separate application or fire up the debugger.
Even more fun, I learned how to load unsigned .Net assemblies (and COM!) into Powershell so I can run methods for testing and support issues without having to write a test app. Simply using System.Reflection.Assembly, same as I would to load an unreferenced assembly in code, I can initialize a new object and then view its members and execute its methods.
So, maybe I just made myself look ignorant, but I needed to say something because I’m so excited to be finally learning to work with this powerful tool. If you’re a .Net developer and you’re not already using Powershell, I highly recommend that you go and check it out.