Passion * Technology * Ruthless Competence

Thursday, January 21, 2010

Fixing Powershell’s Busted Resolve-Path Cmdlet

Usually, my PowerShell posts are effusive in their praise. However, who thought up this “feature” gets no praise from me:

PS» Resolve-Path ~\missing.file
Resolve-Path : Cannot find path 'C:\Users\hpierson\missing.file' because it does not exist.

In my opinion, this is a bad design. Resolve-Path assumes that if the filename being resolved doesn’t exist, then it must be an error. But in the script I’m building, I’m resolving the path of a file that I’m going to create. In other words, I know a priori that the file doesn’t exist. Yet Resolve-Path insists on throwing an error. I would have expected there to be some switch you could pass to Resolve-Path telling it to skip path validation, but there’s not.

And the worst thing is, I can see that Resolve-Path came up with the “right” answer – it’s right there in the error message!

Searching around, I found a thread where someone else was having the same problem. Jeffrey Snover – aka Distinguished Engineer, inventor of Powershell and target of Erik Meijer’s Lang.NET coin throwing stunt – suggested using –ErrorAction and –ErrorVariable to ignore the error and retrieve the resolved path from the TargetObject property error variable. Like Maximilian from the thread, using this approach feels fragile and frankly kinda messy, but I needed a solution. So I wrote the following function that wraps up access to the error variable so at least I don’t have fragile messy code sprinkled through out my script. 

function force-resolve-path($filename)
{
  $filename = Resolve-Path $filename -ErrorAction SilentlyContinue
                                     -ErrorVariable _frperror
  if (!$filename)
  {
    return $_frperror[0].TargetObject
  }
  return $filename
}

The script is pretty straightforward. –ErrorAction SilentlyContinue is PowerShell’s version of On Error Resume Next in Visual Basic. If the cmdlet encounters an error, it gets stashed away in the variable specified by ErrorVariable (it’s also added to $Error so you can still retrieve the error object if ErrorVariable isn’t specified) and continues processing. Then I manually check to see if resolve-path succeeded – i.e. did it return a value – and return the TargetObject of the Error object if it didn’t.

As I said, fragile and kinda messy. But it works.

Posted By Harry Pierson at 11:38 PM Pacific Standard Time

Tuesday, July 28, 2009

Functions that Create Functions in Powershell

Since I started using Powershell, I’m very picky about what I let on my path. I feel it’s much cleaner to create aliases or functions rather than letting all kinds of crud creep into my path.

Recently, I installed the latest IronRuby release and discovered there’s a whole bunch of little batch file wrappers around common Ruby commands like gem and rake. While being able to simply type “igem” or “irake” is much easier than typing “ir "C:\Program Files\ironruby-0.6.0\bin\igem"”, I didn’t want to pollute my path - even with a product from my team. Instead, I wanted to create a Powershell function for each of those IronRuby-fied commands. Furthermore, I wanted to avoid manually creating a function for each Ruby command – these batchfiles are literally identical except for their name, so I figured it would be possible automate the function creation in Powershell. Here’s what I came up with:

$iralias = get-alias ir -EA SilentlyContinue
if ($iralias -eq $null) {return}

$irbindir = split-path $iralias.Definition

function make-rubyfunction($cmd)
{
  $cmdpath = join-path $irbindir $cmd
  set-item function:global:$cmd -Value {ir $cmdpath $args}.GetNewClosure()
  write-host "Added IronRuby $_ command"
}

("igem","iirb","irackup","irails","irake","irdoc","iri") | 
  %{make-rubyfunction $_} 

I start by getting the ir alias, which I’m setting in my traditional fashion. The Ruby command files are in the same directory as ir.exe, which is what ir is aliased to. If the ir alias isn’t set, I quit out of the script without setting anything.

The make-rubyfunction function is the primary workhorse of this script. You pass in a command name as a string, and it uses set-item on the function provider to create a new function. Note, I had to explicitly create this function in the global scope since I’m running the set-item cmdlet inside a script.

Getting the value for the function took a bit of head banging to figure out. I’m used to Python, which automatically closes over variables, so my first attempt was to set the function value to something like { ir $cmdpath $args }. But Powershell doesn’t close automatically, so that fails since $cmd isn’t defined inside the function. I asked around on the internal Powershell alias, and someone pointed me to the new GetNewClosure function in Powershell v2. In other words, Powershell only supports manual closures, which is kind of wonky, but works OK for this scenario. I create a new script block that references in-scope variable $cmdpath and GetNewClosure automatically creates a new script block where that value is captured and embedded. More info on GetNewClosure in the docs.

Now, I’m using Win7 exclusively at this point, so depending on a v2 feature didn’t bother me. However, if you’re using Powershell v1, you could still accomplish something similar using text substitution. Here’s my original (i.e. pre-GetNewClosure) version of make-rubyfunction

function make-rubyfunction($cmd)
{
  $cmdpath = join-path $irbindir $cmd
  $p = "ir `"$cmdpath`" `$args"
  set-item function:global:$cmd -Value $p
  write-host "Added IronRuby $_ command"
}

I’m using Powershell’s standard text substitution mechanism to create the function value as a string. Note that I’m escaping the dollar sign in $args, so that does not get substituted the way $cmdpath does. GetNewClosure feels cleaner, so that’s how I ended up doing it, but both ways seem to work fine.

Finally, I pass an array of IronRuby commands down the pipe to make-rubyfunction. I love the pipe command, though it feels strange to use parentheses instead of square brackets for list comprehensions like Python and F#!

Anyway, the script – as usual – is up on my SkyDrive. At some point, I want to do something similar for common IronPython scripts like pyc and ipydbg. Until then, hopefully someone out there will find it useful (like maybe the IronRuby team?).

Posted By Harry Pierson at 4:59 PM Pacific Daylight Time

Thursday, June 18, 2009

Add-Bcd-Vhd.ps1

I *LOVE* the new boot from VHD feature in Win7. I am primarily using it for doing some VS 2010 dogfooding without messing up my primary drive partition. But man, the process for setting up a VHD for booting is brutal. Scott Hanselman did a great job laying out the steps, but I wanted something a bit more productive.

First, I created a clean Win7 RC VHD and zipped it up for easy storage. The basic Win7 RC VHD is just under 5GB, but compresses down to about 1.5GB with 7-zip. I used the ImageX process Aviraj described though in the future I’ll use the Install-WindowsImage script. Install-WindowsImage is more convenient to use because it will list the indexes within a given .wim file instead of making you grovel thru an XML file like ImageX does. Also Install-WindowsImage is 27k download while ImageX is part of the 1.4 gigabyte Windows Automated Installation Kit. Look, I’m not hurting for bandwidth, but I don’t see the point of downloading 54442 times more data for a utility that isn’t as useful.

Once you’ve created the VHD, you need to update your Boot Configuration Data, or BCD for short, using the appropriately named BCDEdit utility. The process is fairly straight forward, if tedious. You have to run BCDEdit four times, copy the configuration GUID to the clipboard and type out the path to the VHD in a slightly funky syntax. Blech. So I built a PowerShell script to automate updating the BCD, called add-bcd-vhd. You can get it from my skydrive. Pass in the name of the BCD entry and the path to the VHD and add-bcd-vhd will do the rest.

I was whining on Twitter yesterday that there’s no PowerShell specific tools for managing the BCD data. Add-bcd-vhd just runs bcdedit behind the scenes and processes the text output with regular expressions. Ugly, but effective. I decided to spend some time trying accessing the BCD data from its WMI provider, but that turned out to be way too much of a hassle to be effective. If someone else out there knows how to use the BCD WMI provider from PowerShell, I’d appreciate some sample code.

Posted By Harry Pierson at 1:39 PM Pacific Daylight Time

Wednesday, April 29, 2009

Updated Powershell Scripts

For those who are interested, I just uploaded a bunch of changes to the PowerShell Scripts folder on my SkyDrive. Feel free to download them and use them as you need.

  • find-to-set-alias – Brad Wilson enhanced this function significantly and broke it out into it’s own script. I had a small issue with his version where the folder search may only return a single value, so you can’t treat it like collection. My version wraps that command in @(…) so that you can always treat it like a collection.
  • find-in-path – searches all the folders in your path for a given file name (wildcards supported. Very useful for “where is this app actually installed” kind of debugging.
  • get-git-branch – returns the current git branch of a given folder. Got the idea for this originally from Ivan Porto Carrero.
  • prompt – my powershell prompt. Pretty basic, but it now shows current git branch.
  • elevate-process – create a new PowerShell window or run an app as an administrator. I alias this to su on my machine. I recently reworked the “run an app” part of this script, so it will search the current folder and then the path to run the app you specify.
  • _profile – this is my main profile script, which I share across multiple machines via Mesh. I reworked all my alias setting to use the new find-to-set-alias and moved setting the color of the command window to the top of the script.

Update – I just updated elevate-process again, adding a special clause to handle .bat and .cmd files. cmd.exe seems to ignore the working directory setting, so if your batch file relies on being run from the folder it’s in, it’ll break with elevate-process. That’s annoying. So if you elevate a batch file, the script runs cmd.exe directly and executes the specified batch file after first changing to the current directory. Ugly, but it seems to work.

Posted By Harry Pierson at 12:25 PM Pacific Daylight Time

Wednesday, December 17, 2008

PowerShell find-to-set-alias

I use Live Mesh to keep my PowerShell scripts folder synced between multiple machine. Some of those machines have different things installed on them or have things installed in different locations. For example, my laptop is x86 while my desktop is x64 so many things on the desktop get installed into c:\Program Files(x86) instead of the plain-old c:\Program Files folder. I wanted my shared profile script to be able to search a set of folders for a given executable to alias, and I came up with the following function.

function find-to-set-alias($foldersearch, $file, $alias)
{
  dir $foldersearch
    %{dir $_ -Recurse -Filter $file} | 
    %{set-alias $alias $_.FullName -scope Global; break}
}

It’s pretty simple to use. You pass in a folder search criteria – it must have a wildcard, or the function won’t work – the file you’re looking for and the alias you want to set. The function finds all the folders matching the $foldersearch criteria, then searches them recursively looking for the $file you specified. Set-alias is called for the first matching $file found – pipeline processing is halted via the break statement.

Here are the find-to-set-aliases I have in my profile:

find-to-set-alias 'c:\program files*\IronPython*' ipy.exe ipy
find-to-set-alias 'c:\program files*\IronPython*' chiron.exe chiron

find-to-set-alias 'c:\Python*' python.exe cpy

find-to-set-alias 
    'c:\program files*\Microsoft Visual Studio 9.0\Common7' devenv.exe vs
find-to-set-alias 
    'c:\program files*\Microsoft Visual Studio 9.0\Common7' tf.exe tf

find-to-set-alias 'c:\program files*\FSharp*' fsi.exe fsi
find-to-set-alias 
    'c:\program files*\Microsoft Repository SDK*' ipad.exe ipad
find-to-set-alias 
    'c:\program files*\Microsoft Virtual PC*' 'Virtual pc.exe' vpc

Python, IronPython and F# aliases, no surprise there. Chiron is the REPL server for dynamic language Silverlight development. Typically, I use Chris Tavares’ vsvars script to configure the command shell for development purposes, but I find it’s nice to have aliases for TF and DevEnv handy at all times.

Posted By Harry Pierson at 3:17 PM Pacific Standard Time

Friday, November 07, 2008

My Elevate-Process Script

I used to use the Script Elevation PowerToys to provide a simple way to launch an elevated command window from a Powershell prompt. However, that required installing said PowerToys in order to work, which I invariably forgot to install when paving my machine. That got annoying, so I went in search of a pure Powershell solution, which Peter Provost conveniently provided on his blog.

However, one of the benefits of the Script Elevation PowerToys was the ability to launch an admin command prompt in a specific directory – including the current one. I wanted the ability to default to launching Powershell when the user doesn’t specify a command to run. I thought I could just set $psi.WorkingDirectory, but as I’ve described previously, I update $home in my profile script to D:\HPierson.Files (I keep my important files on my D: drive so I can pave C: with impunity) then set my current location to $home. So I can’t set the current location by using $psi.WorkingDirectory – it just gets overridden by my profile script.

However, it turns out you can pass arbitrary script code to Powershell via the –Command arguments. You also have to pass –NoExit to keep the command window around. The script passed in via -Command is executed after the profile script, so I can pass in a little script code to set the current location to the right location.

I modified Peter’s elevate-process script to launch a new Powershell command window when zero arguments or one folder argument are passed in. In those cases, elevate-process sets the location to the specified directory (current directory as the default when no arguments are provided) via the –NoExit and –Command arguments.

I’ve posted the script to my SkyDrive as well as providing it below. Feel free to steal use it as you need.

function elevate-process 

  $psi = new-object System.Diagnostics.ProcessStartInfo
  $psi.Verb = "runas";

  #if we pass no parameters, then launch PowerShell in the current location
  if ($args.length -eq 0)
  {
    $psi.FileName = 'powershell'
    $psi.Arguments = 
      "-NoExit -Command &{set-location '" + (get-location).Path + "'}"
  }

  #if we pass in a folder location, then launch powershell in that location
  elseif (($args.Length -eq 1) -and 
          (test-path $args[0] -pathType Container))
  {
    $psi.FileName = 'powershell'
    $psi.Arguments = 
        "-NoExit -Command &{set-location '" + (resolve-path $args[0]) + "'}"
  }

  #otherwise, launch the application specified in the arguments
  else
  {
    $file, [string]$arguments = $args;
    $psi.FileName = $file  
    $psi.Arguments = $arguments
  }
    
  [System.Diagnostics.Process]::Start($psi) | out-null
}

Update: I tried to run my elevate-process script from c:\Program Files and discovered a bug. The set-location scripts need the path parameter to be encapsulated in single quotes in order to handle paths with spaces. I’ve updated both the code above as well as the copy on my SkyDrive.

Posted By Harry Pierson at 4:16 PM Pacific Standard Time

Friday, September 12, 2008

Webdev Script and KillWebDevServer

I was updating my webdev powershell script today. I wanted to add support for a -browser switch that would automatically launch a browser window the way chiron from the Silverlight Dynamic Languages SDK. does. I also set the script to serve up the current directory by default. I posted the new version up on my SkyDrive.

While I was working on the script, I thought about how one might shutdown the WebDev server from the command line. That turned out to be much harder. Basically, you have to look thru all the top level windows for one that has "ASP.NET Development Server" in the window text, then you send that window two messages - WM_QUERYENDSESSION and WM_QUIT. Not sure why the WebDev server uses WM_QUERYENDSESSION to shut down it's tray icon, but if you look at WebDev.WebServer.exe in Reflector, you'll see the tray icon form overrides WinProc in order to look for message 0x11, i.e. WM_QUERYENDSESSION.

I threw together a quick little C# console app to shutdown the WebDev server and stuck it up on my SkyDrive as well. Source code is up there too. I had to use a bunch of P/Invokes to make it work, or I would have written it in Powershell or IronPython.

Enjoy.

Posted By Harry Pierson at 5:53 PM Pacific Daylight Time

Monday, July 28, 2008

Some Powershell Scripts

By popular demand, I uploaded a bunch of my scripts to my SkyDrive. Included are:

  • Set Powershell Home - this is actually a zip file that contains the profile redirect script. Unzip this in your Documents folder and change the path in Microsoft.PowerShell_profile to where ever you want your profile and home directories to live.
  • _profile - my "real" profile script. Note, the su function requires the Script Elevation PowerToys in order to work. Also, all the various aliases are hard coded to their location on my machine. You'll probably want to change them.
  • prompt - my prompt script
  • prepend-path - a script to add a directory to start of my path
  • append-path - like above, but adds the directory to the end of the path
  • append-path-perm - like append-path, but permanently updates the path in the registry

Enjoy.

Posted By Harry Pierson at 4:26 PM Pacific Daylight Time

DevHawk's Slightly Useful Powershell Configuration

Since folks were interested in my favorite tools, I thought I'd blog how I have PowerShell configured. I'm not an ultra-power user, but I hold my own and hopefully you can use some of this configuration for yourself. Please tell me you're not still using CMD.

First, I use a trick I picked up from Tomas Restrepo to change your home directory and profile script. Here's my Microsoft.PowerShell_profile.ps1 file (in the WindowsPowerShell subdirectory of My Documents)

# reset $HOME and $PROFILE variables
set-variable -name HOME -value "D:\HPierson.Files" -force 
(get-psprovider FileSystem).Home = $HOME 
set-variable -name Profile -Value "$Home\Scripts\_profile.ps1"

# Run the $PROFILE script
. $profile

By default, PS uses the user's personal directory (c:\users\hpierson in my case) as the home directory and the aforementioned filename for the profile script. Personally, I like to keep all "real" data off my boot partition so that I don't have to back it all up when I repave. So my "real" home location is d:\HPierson.Files. The above script sets both the $HOME variable and file system home property to this directory. It also resets the $PROFILE variable to a script in my $home\Scripts folder and runs it.

My $PROFILE script does several things of note:

  • It adds the aforementioned $home\Scripts folder to the path. My utilities folder is a permanent part of the path, put I only add the scripts folder when I'm actually running PS.
  • If I'm running as administrator, I set the background color of the console window to red. I think I picked up this script from Brad Wilson at some point.
  • Set location to home, otherwise when I start PS as admin, it starts in c:\win\sys32.
  • I have a simple prompt script file that displays current folder, the current command number and a list of yellow plus signs indicating how deep I am in the directory stack. To get it to work, I have to remove the standard prompt function, which I do in $PROFILE.
  • I can't ever remember the space between "cd" and "..", so I wrote a simple function called "cd.." that executes "cd ..".
  • I have a su function that leverages the Script Elevation PowerToys. If you pass in a command, it executes it with elevated credentials. If you just execute su, it runs an elevated PowerShell.
  • I use 7-zip for my compression needs, including the 7za command line app. However, PS has issues w/ executing an exe that starts with a number. So I aliased 7za as "zip". UPDATE: Tomas points out that you can prepend an ampersand to force execution, so I could have typed "&7za". I forgot that when I created the alias and am now used to using zip, so I'm not going to change it. But I thought you should know.
  • I have an ever-changing set of aliases, depending on my needs. Currently, I alias "ipy", "cpy", "fsi", "fsc", "devenv" and "chiron" to their fully path-qualified equivalents, so I can run them from anywhere without having to add their respective folders to the path.

I don't set vsvars in the $profile script, but I do have a copy of the one Chris Tavares wrote in my scripts folder, so I can set up a VS environment in a moments' notice.

Also, I put PowerShell on the Vista quick launch bar, so I can bring it up by typing Win-2.

Posted By Harry Pierson at 9:52 AM Pacific Daylight Time

Monday, July 14, 2008

Morning Coffee 167

  • If you're a gamer, you're probably already well aware that E3 is this week. The Too Human demo has already been released. I have a friend who's been working on "something" that will be announced today (I think).
  • Live Mesh folks pushed out an update Friday. Among the new features is the ability to sync folders among peers but NOT up to the cloud. This is cool because it means I can sync my many many GB of pictures and music on my home machine backed up with Carbonite. This means I can sync them without blowing thru my 5GB Mesh storage limit.
  • It looks like there's a new F# drop - 1.9.4.19 - but as usual there is no announcement or details as to what's new. Release notes guys, look into it.  UPDATE - Don Syme blogged the release, and it's pretty minor. a .NET FX 3.5 SP1 bug fix, a fix for Mono, and they removed WebRequest.GetResponseAsync to make F# work on Silverlight. And the release notes are in the readme. My bad.
  • Speaking of F#, it was "partially inspired" by OCaml, so when I see papers related to OCaml, I immediately wonder if I an apply the described techniques to F#. "Catch me if you can, Towards type-safe, hierarchical, lightweight, polymorphic and efficient error management in OCaml" is one such paper. (via LtU)
  • Speaking of functional programming, Matthew Podwysocki posted a bunch of FP links as well as a Code Gallery Sample on FP in C#. Good stuff.
  • As per Scott Guthrie, it looks like there's a new ASP.NET MVC drop coming this week.
  • Based on posts by Ted Neward, Dare Obasanjo and Steve Vinoski, Google Protocol Buffers sounds like it's going to be a dud. Note, I haven't looked at it depth personally, I'm just passing on opinions of some folks I read and trust.
  • Speaking of Dare, both he and James Hamilton take a look at Cassandra and come away impressed. I wonder how easy it is to code against from Python and/or .NET?
  • Bart de Smet has a cool sample of calling out to PowerShell from IronRuby via the backtick command. Pretty cool, but it would even cooler to show how to call out to PS and return .NET objects to Ruby (though that would probably not be spec compliant for the backtick command).
  • Here's a MS code name I had never heard before - Zermatt. It's "a framework for implementing claims-based identity in your applications." (via Steve Gilham)
Posted By Harry Pierson at 9:30 AM Pacific Daylight Time

Monday, July 07, 2008

Morning Coffee 166

Yes, I realize it’s been a while. I tried in vain to catch up with my blog reading after my Hawaii vacation and finally just gave up and hit “mark all as read”.

Dynamic Languages

  • There's a new version of the DLR hosting spec available (doc, pdf). The DLR implementation is still in motion, so there are some inconsistencies between the spec and the code, but the spec should give you the high level overview you need if you want to host DLR languages inside your app.
  • Oleg Tkachenko recently joined the dynamic languages team. He's the creator of the Interactive IronRuby Web Shell, an IronRuby version of Try Ruby. Of course, it’s not as cool as using SL2to execute the code directly in the browser. Michael Foord has his Python in the Browser and my teammates John and Jimmy demoed a Silverlight version of Try Ruby @ TechEd.
  • Jim Deville, also of the dynamic languages team, recently started blogging.
  • I have a new boss, Dave Remy. He doesn't have a blog - yet - but you can follow him on Twitter as daveremy. When Twitter is actually working that is.
  • There's a new homepage/wiki for IronRuby though I’m not sure why there's a picture of Matz wearing a Python shirt on the home page.
  • My teammate Jimmy Schementi provides some "continued hope" for a better (heck, I'll take current) ASP.NET and ASP.NET MVC story for DLR languages.
  • Via Michael Foord, sounds like IronClad is making good progress. V0.4 can run the bz2 module "in its entirity" (maybe run a spellcheck on your site, guys?) and now apparently, it's now able to load numpy.core. Very exciting!

Other Stuff

  • Pat Helland, who has blogged even less than me for the past few months, has a post up about controller and doers in the IT department. After 18 months in MSIT, put me in the doer camp, please.
  • The F# team has pushed out a spec for v1.9.4 of the language. Don Syme says it's not official, but it's a huge improvement over the old informal spec
  • Speaking of F#, my friend Matthew Podwysocki recently published FsTest, a testing DSL for F#. I wrote about F# unit testing as part of my PEG parsing series, and I really like the direction Matthew has taken this project. You can pull it down from CodePlex.
  • When I did my PEG talk @ Lang.NET, Gilad Bracha mentioned I should check out oMeta. It looks really cool, though with the job change I haven’t had the time to play with it. Now I discover that Jeff Moser is working on a version for CLR called oMeta# that I’ve got to spend some time with. And in the comments to that post, I discovered pyMeta from Allen Short, though it apparently doesn’t work on IronPython (must investigate why).
  • James Kovacs introduces psake, a PowerShell based build automation tool which uses a rake-inspired internal DSL syntax similar to one I blogged last year. I'd love to see this take off, but given MSBuild's tool integration, I wonder if that's feasible.
  • I upgraded my home wireless network almost exactly a year ago. I've been happy with the range and coverage, but not so happy with the Buffalo Tech firmware. The built-in DHCP server is pretty flaky. So I upgraded to the open-source Tomato firmware. Upgrade was smooth, though I did need to reset my cable modem. But even that was smooth - Comcast has an automated service for that now,
Posted By Harry Pierson at 9:30 AM Pacific Daylight Time

Wednesday, April 09, 2008

Morning Coffee 162

  • Another nice thing about the new job: I'm working in the vicinity of some good friends. I was over in building 42 yesterday and made it a point to stop by Pat Helland's office yesterday and spend an hour or so chatting about the new gig. Pat is down the hall from David Hill, whom I worked with on Architecture Strategy. Back in my building, we're down the hall from the VSX folks including my friends Ken Levy and Gareth Jones. I'm sure there are more folks I know around, but hey it's only my second week!
  • I'm a big fan of Carbonite, which I use to back up all the digital media on my home computer. With two little kids, we have lots of digital photos as you might imagine . However, one thing that bugs me about Carbonite is that it doesn't back up video files by default, you have to go in on a folder by folder basis and select "'Back up Video files in this folder" from the context menu. Given how much trouble this "feature" has given me, I imagine less techie folks don't even realize their video files aren't getting backed up. However, I will say the latest version of the Carbonite Software at least makes it easy to find files that aren't backed up. A quick sweep revealed around a dozen folders that had un-backed-up video files in them, which I promptly fixed.
  • The big news yesterday was the new Google App Engine, which looks to give you access to virtualized infrastructure that sounds similar to what GOOG is rumored to use internally. I like Dave Winer's comment that this enables "shrinkwrap net apps that scale that can be deployed by civillians." Given Google's history w/ Python - Python's BDFL Guido van Rossum works there - it's no surprise that Google App Engine (GAE?) runs on Python, though apparently they "look forward to supporting more languages in the future". I'm guessing "more languages" == Ruby, maybe Erlang too.
  • I wonder if/how Google App Engine will affect Ruby on Rails momentum? If there's a significant lag before App Engine supports Ruby, will that drive developers to Python web stacks like Django? (Django is included in "the box" with App Engine)?@ PyCon, I was surprised at the intra-language animosity I observed. I wonder how many Python developers are secretly hoping Google never ships Ruby support. I highly doubt Google would do that - they want to tap the exploding RoR market like everyone else - but I'd bet it would really take the wind out of Rails' sails if they did.
  • Today's Michael Foord Link: Embedding IronPython 2, Examples of the DLR Hosting API. You can read the DLR Hosting spec, but it's pretty out of date so Michael's article helps fill in some of the gaps.
  • Looks like PowerShell has gotten the open source community treatment in a project called Pash. While I'm sure others are excited about PS on Linux or Mac, I'm excited to see PS running on Compact Framework. I wonder if it would work with XNA?
  • Speaking of XNA, XNA Console is a new CodePlex project that provides an IPy console to manipulate your XNA based game on the fly. Python is no stranger to game development - Civ IV for example provided mod capabilities via python. Alas, the compact framework can't run IPy today, so neither can XNA on Xbox. But wouldn't it be cool to hack your game in IPy running on a 360 using the messenger kit? (via IPy URLs)
  • Bart De Smet gets functional, writing type switch and pattern matching in C# 3.0. I guess it works, but it sure is ugly. Why not just use F# and be done with it?
  • Soma announces that the VC++ Feature Pack has shipped. Somewhere, I assume, there is much (some?) rejoicing.
Posted By Harry Pierson at 10:20 AM Pacific Daylight Time

Thursday, March 20, 2008

WebDev.WebServer PowerShell Function

In experimenting with NWSGI yesterday, I found I wanted the ability to launch the development web server that ships with Visual Studio (WebDev.WebServer.exe) from the command line. I hacked up the following PowerShell function and dropped it into my $profile so I can easily launch the web server in any directory any time I need. Thought I'd share:

function webdev($path,$port=8080,$vpath='/')  
{  
    $spath = 'C:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE' 

    $rpath = resolve-path $path 
    $params = "/path:`"$rpath`" /port:$port /vpath:$vpath" 

    $ignore = [System.Diagnostics.Process]::Start($spath, $params
    "Started WebDev Server for '$path' directory on port $port" 
}

There's probably an easier way to launch an exe with parameters than Sys.Diags.Process.Start, but it works. Using resolve-path is the key, that lets me pass in a relative path on the command line, but the script converts it to an absolute path in order to pass it to the webdev server. Also, I'm not sure I should have hard coded the path to the exe, but again it works and it's not like it's tough to change.

Enjoy.

Update: Tomas Restrepo pointed out an easier way to start the process:

&'C:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE' "/path:$rpath" "/port:$port" "/vpath:$vpath"

I couldn't figure out how to correctly launch the exe when the physical path to serve has a space in it. Thanks Tomas.

Posted By Harry Pierson at 2:39 PM Pacific Standard Time

Tuesday, March 18, 2008

Lunchtime Coffee 158

  • My friend (and hopefully my next representative) Darcy Burner is leading a group of congressional challengers in publishing A Responsible Plan To End The War In Iraq. I haven't read the plan itself in detail, but I sure like what I'm hearing about it.
  • Speaking of politics, Obama's speech today "A More Perfect Union" was fantastic.
  • Bioshock is getting a sequel. 'nuff said.
  • There's a new version of FolderShare out and I've got mixed feelings about it. On the one hand, I've been a regular user of FolderShare for a while so it's nice to see it get a face lift. On the other hand, it's been over two years since Microsoft bought FolderShare and we're only just now getting a new version, which is literally nothing more that a face lift - this version introduces no new functionality at all.
  • I was hoping to geek out vicariously via someone else's hacking around with Singularity. Luckily, Matthew Podwysocki provides just such an opportunity.
  • Looks like "Prism" is the new CAB. Glenn Block has two extensive posts covering a project overview and their first drop. I think it's interesting that the Prism team is focused on building a reference implementation, and letting the framework eventually fall out. Reading thru the description, it sounds awesome. However, based on the massive increase of inbox throughput I'm experiencing since I accepted the new job, I can't imagine I'll have time to play with it. Maybe Matthew will start playing with Prism too! (via Sam Gentile - btw, thanks for the kind words on the new job Sam!)
  • Speaking of Sam, he points to a series by Bob Beauchemin entitled LINQ to SQL and Entity Framework: Panacea or evil incarnate? With a title like that, who can resist reading the whole series? Err, I can because LINQ 2 SQL & EF performance just fell off my radar entirely. However I gotta agree with Sam's point that he "can't think of anyone more qualified than Bob" to tackle these questions.
  • Tomas Restrepo blogs his dev environment PS script as well as a PS fortune script. Personally, I use Chris Tavares' vsvars wrapper for PS, though I'll gladly take an "official" PS based dev environment.
  • I wonder if Ted Neward will get jumped for admiring Mort the way Nick Malik did. Given that Ted called himself Mort while Nick compared Mort to agile developers, I'm guess Ted will have to go back to his Vietnam analogy if he wants to create controversy.
  • Speaking of Ted, I agree with his point that conferences are about people. As a python pre-newbie (I figure I'll reach full newbie status by the time I actually start my new job), I spent most of my PyCon time connecting with people rather than trying to learn technical stuff. Also, I love Ted's WHISCEY acronym.
  • Speaking of PyCon, my soon-to-be new teammate Srivatsn Narayanan blogs his thoughts on PyCon. I'll try and get to my PyCon thoughts soon.
Posted By Harry Pierson at 11:49 AM Pacific Standard Time

Wednesday, February 13, 2008

Morning Coffee 146

  • The writers strike is officially over. Everyone goes back to work today. Thomas Cleaver has what I thought was the best post summarizing how the writers won. TV Guide has a rundown of how and when various shows will resume. I can't wait to see Daily Show and Colbert Report tonight. Lost - aka the best show on TV - looks like it will be getting five more episodes (in addition to the eight shot before the strike).
  • Speaking of TV, Battlestar Galactica Fans: circle April 4th on your calendar.
  • Obama won all three "Potomac Primaries" yesterday, and is now the Democratic front-runner, though there's a long way to go before the convention. Scott Adams of Dilbert fame has a great take on presidential experience - I'm guessing he's an Obama fan.
  • In minor acquisition news, Microsoft is acquiring Caligari, makers of 3D modeling tool trueSpace. The Caligari folks are joining the Virtual Earth team, though I wonder what the XNA folks think of the acquisition. This isn't the first 3D modeling product Microsoft ever acquired - we owned Softimage for four years in the '90s.
  • Scott Hanselman and Tomas Resprepo both write about PowerShellPlus, which I saw week before last @ Lang.NET. Scott really likes it, for both PS novices and gurus, but Tomas thinks the UI is busy, based on the screenshots. Personally, I'm not doing much PS work lately - occasional one off stuff, but that's it - so it doesn't seem worth the effort.
  • Speaking of Scott & Tomas, Scott also has a nice gallery of VS themes. I'm partial to Tomas' Ragnarok Grey. Is there a VSThemesGallery.com site somewhere?
  • Still speaking of Scott, he points to the new ASP.NET Developer Wiki (beta). I poked around, but didn't find anything shiny. I was very surprised that searching for "MVC" returned no results.
  • Speaking of MVC, Scott Guthrie has a rundown on what's coming in the MIX preview release of ASP.NET MVC. Biggest news IMO is that it's /bin deployable - i.e. you don't need your hoster to do anything special to support MVC (assuming they already support ASP.NET 3.5). Also big news, they're releasing the source so you can build and patch (and enhance?) it yourself.
  • Chris Taveres continues is ObjectBuilder series and Tomas continues is DLR Notes series. BTW, my F# based DLR experimentation continues, albeit slowly (frakking day job). Hope to be able to post on this soon.
  • One of the things driving my interest in F# is manycore. An interesting tangent to manycore is general purpose programming on graphics processing units (aka GPGPU). MS Research just released a new version of Accelerator, just such a GPGPU system. I personally haven't played with it - I've been focused on writing parsers, not parallel code.
  • Is XQuery really "a promising technology of the future" as Don Box suggests? I see exactly zero demand or use for it in my day-to-day work. Of course, Don's paid to build future platform goo, so maybe it is promising and Don's afore-mentioned goo will leverage it, though I remain skeptical. As for XML being "Done like a well-cooked steak", I'd say XML is like a great steak cooked perfectly, except it's done exactly how you don't like it. You can appreciate its quality, but you don't really enjoy it as much as you could have.
Posted By Harry Pierson at 10:04 AM Pacific Standard Time

Thursday, January 31, 2008

Morning Coffee 141 - Lang.NET '08 Edition

header I was hoping to blog my thoughts on Lang.NET as the event went along. Obviously, that didn't happen, though I was pretty good about dumping links into my del.icio.us feed. The talks were all recorded, and should be up on the website in a week or two. Rather than provide a detailed summary of everything that happened, here are my highlights:

  • The coolest thing about conferences like this is what John Rose called "N3" aka "Nerd-to-Nerd Networking". It was great to meet in person, drink with and geek out with folks who's blogs I read like Tomas Petricek, Wesner Moise and Larry O'Brien. Plus, I got to meet a bunch of other cool folks like Gilad Bracha, Stefan Wenig and Wez Furlong. That's worth the price of admission (which was admittedly nothing) right there.
  • Coolest MSFT talk: Martin Maly "Targeting DLR". I was wholly unaware that the DLR includes an entire compiler back end. Martin summarized the idea of DLR trees on his blog, but the short version is "you parse the language, DLR generates the code". That's pretty cool, and should dramatically lower the bar for language development. Of course, I want to write my parser in F#, so I'm going to port the DLR ToyScript sample to F#.
  • Runner-up, Coolest MSFT talk: Erik Meijer "Democratizing the Cloud with Volta". Erik is a great speaker and he really set the tone of his session with the comment "Division by zero is the goal, not an error". He was referring to an idea from The Change Function that user's measure of success is a function of perceived crisis divided by perceived pain of adoption. Erik wants to drive that adoption pain to zero. It's a laudable goal, but I remain unconvinced on Volta.
  • Coolest Non-MSFT talk: Gilad Bracha "Newspeak". Newspeak is a new language from one of the co-authors of Java. It's heavily smalltalk influenced, and runs on Squeak. He showed developing PEGs in Newspeak, and they were very compact and easy to read, easier even than F#. He calls them Executable grammar, and you can read his research paper or review his slides on the topic. Unfortunately, Newspeak isn't generally available at this time.
  • Runner-up, Coolest Non-MSFT talk: Miguel de Icaza "Moonlight and Mono". The talk was kinda all-over-the-place, but It's great to see how far Mono has come. Second Life just started beta testing a Mono-based script runner for their LSL language (apparently, Mono breaks many LSL scripts because it runs them so fast). He also showed off Unity, a 3D game development tool, also running on Mono.
  • Resolver One is a product that bridges the gap between spreadsheets and applications, entirely written in IronPython (around 30,000 lines of app code and 110,000 lines of test code, all in IPy). Creating a spread-sheet based app development environment is one of those ideas that seems obvious in retrospect, at least to me. If you do any kind of complicated spreadsheet based analysis, you should check out their product.
  • If you're a PowerShell user, you should check out PowerShell+. It's a free console environment designed for PowerShell and a damn sight better than CMD.exe. If you're not a PowerShell user, what the heck is wrong with you?
  • Other projects to take a deeper look at: C# Mixins and Cobra Language.
  • I thought my talk went pretty well. It's was a 15 minute version of my Practical Parsing in F# series. Several folks were surprised I've been coding F# for less than a year.
Posted By Harry Pierson at 10:25 AM Pacific Standard Time

Monday, January 28, 2008

Morning Coffee 140

  • I only posted one Morning Coffee post last week. It wasn't a lack of content, it was a lack of drive on my part. I had 20-30 items flagged in my news reader, but for some reason I couldn't work up the interest in posting them. So some of these are a bit old.
  • I'm at the Language.NET Symposium this week, so look for lots of language blogging. I've already chatted with Tomáš Petříček and John Lam. If someone kicks Ted Neward's ass because he hates Perl, I'll try and liveblog it.
  • Speaking of Ted Neward, he discusses the question "Can Dynamic Languages Scale?" without devolving into a flame-fest. I agree 100% with his point about the difference between performance scaling and complexity scaling. Personally, I tend to err on the side of better complexity scaling, since buying hardware is easier than hiring developers.
  • Nick Malik responds to me calling his shared global integration vision flawed. He points to NGOSS/eTOM as an example of a shared iterative model that works. I know squat about that shared model, so I'll refrain from commenting until I do a little homework on the telco industry.
  • Speaking of shared interop models, Microsoft is joining DataPortability.org. Dare Obasanjo and Marc Canter are skeptical that so far this effort is all hype and no substance. Reminds me a bit of AttentionTrust.org. But if DataPortability.org can get off the ground, maybe there's hope for Nick's vision (or vis-versa).
  • Don Syme lists what's new in the latest F# release. As I said, this release is pretty light on features. Hopefully, I'll get some details
  • Tomas Restrepo shows how to change your home folder in PowerShell. I need to do this.
Posted By Harry Pierson at 9:10 AM Pacific Standard Time

Friday, November 09, 2007

Morning Coffee 122

  • Sorry for the posting lag. Had a few technical difficulties around here. In the process of moving hosts, so expect more glitches.
  • My talk at the p&p Summit on Monday went really well. At least, it felt good and the applause at the end felt genuine. I recorded the audio on my laptop, so I'll be posting a Silverlight version as soon as I figure out how to adjust the levels so their somewhat consistent. Paraesthesia and #2872 have reactions.
  • Speaking of the p&p Summit, Scott Hanselman posted his ASP.NET MVC demo from his talk. Said ASP.NET MVC bits aren't available yet, so you can't, you know, run the demo for yourself. But at least you can review what the ASP.NET MVC code will look like.
  • I stopped by the SOA/BPM conference last week and saw Jon, Sam and Jesus among others. Spent quite a bit of time talking to Sam and his Neudesic colleagues about this "physically distributed/logically centralized" approach that I think is hogwash. It sounds to me like Neudesic approach is really federated not centralized, though I'm not sure David Pallmann would agree. Federated makes much more sense to me than centralized.
  • Nick Malik continues his series on SOA Business Operations Model. I especially like his point that this isn't a series of choices, you need to "look at your company and try to understand which model the business has selected. "
  • The first CTP of PowerShell 2.0 is out! Check out what's new on the PowerShell team blog and Jeffrey Snover's TechEd Presentation. (via Sam Gentile)
  • Soma announced updates to VC++ coming next year, including TR1 support and a "major" MFC upgrade to support creating native apps that look like Office, IE or VS. I get supporting TR1, but the idea that people are clamoring for MFC updates is kinda surprising. Many years ago when I first came to MSFT, a friend asked "But don't you hate Microsoft?" to which I responded "No, I just hate MFC". Obviously, not everyone agrees with that sentiment.
  • Steve Vinoski thinks there's no hope for IT. Funny, I keep agreeing with Steve's overall point but disagreeing with his reasoning. I still don't buy the serendipity argument. I like compiled languages. And I think he's overstating the amount of "real, useful guidance" for REST floating around. Basically, there's "the book".
  • In widely reported news, Windows Live launched their next generation services. Don't bother with the press release, just go to the new WL home page.
  • Speaking of WL, Dare Obasanjo points to the Live Data Interactive SDK page where you can experiment with the WL Contacts REST API. It gives you a good sense of how the Web3S protocol works. Pretty well, IMO. However, how come WL Contacts Schema doesn't include some type of update timestamp for sync purposes? If you wanted to build say a Outlook <--> WL Contacts sync engine, you'd have to download the entire address book and grovel thru it for changes every sync.
  • Speaking of Web3S, I'd love to see some info on how one might implement a service using Web3S. Yaron Goland positions Web3S as an alternative to APP that WL developed because they "couldn't make APP work in any sane way for our scenarios". I'm sure other folks have similar scenarios.
Posted By Harry Pierson at 10:26 AM Pacific Standard Time

Friday, August 17, 2007

Morning Coffee 112

  • The Lee Holmes over at the Powershell Team Blog writes about alternatives to the "decades-old" Windows console host. Powershell Plus looks awesome. PoshConsole also looks pretty cool (though far from finished yet) and is free.
  • WL ID Web Authentication SDK has been released. Details on the WL ID team blog. It looks like what Passport SDK provided for quite some time, but now it's free. There's also a client auth SDK in development. (via Dare Obasanjo)
  • Libor Soucek leaps to the wrong conclusion about not differentiating enterprise & support systems. Of course, different systems will have different availability requirements. But what happens when we connect them together? We can't let the support system effect the availability of the enterprise system, right? To me, that implies either a) the support system now needs to conform to enterprise system availability requirements or b) we need some other mechanism (like async durable messaging) to act as a buffer between them. Personally, I like "b".
  • Nick Carr points to an article The Trouble with Enterprise Software by Cynthia Rettig. Cynthia writes that while the massive complexity of enterprise software, especially large-scale ERP systems like SAP, significantly hinder it's value. It's a must read. Choice quotes:
    • "It is estimated that for every 25% increase in complexity in the tasks to be automated, the complexity of the software solution itself rises by 100%."
    • "The notion of reusable software works on a small scale. Programmers have successfully built and reused subroutines of standard functions. But as software grows more complex, reusability becomes a difficult or impossible task."
    • "Hope, unfortunately, has never been a very effective strategy."
    • "Is enterprise software just too complex to deliver on its promises? After all, enterprise systems were supposed to streamline and simplify business processes. Instead, they have brought high risks, uncertainty and a deeply worrying level of complexity. Rather than agility they have produced rigidity and unexpected barriers to change, a veritable glut of information containing myriad hidden errors, and a cloud of questions regarding their overall benefits."
Posted By Harry Pierson at 11:33 AM Pacific Daylight Time

Thursday, July 12, 2007

Thoughts on C# Fluent Interfaces

Martin Fowler points to a couple of articles by Anders Norås on building internal / embedded domain specific languages in C#. Anders has built a DSL for creating calendar events and tasks, like you might expect to do in Outlook. Here's an example:

ToDoComponent planningTask =
   Plan.ToDo("Plan project X").
      StartingNow.
      MustBeCompletedBy("2007.08.17").
      ClassifyAs("Public");
planningTask.Save();

EventComponent planningMeeting =
   Plan.Event("Project planning meeting").
      RelatedTo(planningTask).
      WithPriority(1).
      At("Head office").
      OrganizedBy("jane@megacorp.com", "Jane Doe").
      StartingAt("12:00").Lasting(45).Minutes.
      Attendants(
         "peter@megacorp.com",
         "paul@megacorp.com",
         "mary@contractor.com").AreRequired.
      Attendant("john@megacorp.com").IsOptional.
      Resource("Projector").IsRequired.
      ClassifyAs("Public").
      CategorizeAs("Businees", "Development").
      Recurring.Until(2008).EverySingle.Week.On(Day.Thursday).
      Except.Each.Year.In(Month.July | Month.August);
planningMeeting.SendInvitations();

It may not be as clean as a say a Ruby version might be, but even with all the parens and periods it's still pretty readable. Fowler calls this a fluent interface, a term I like better than "internal DSL".

Two things jumped out at me reading Anders' entry on how he built this fluent interface. First, there's a lot of code to make this work. Anders didn't publish the code, but he did admit:

"Believe me, there will be a lot of code when you're done. I'm almost there with this DSL, and at the time of writing it consists of 58 classes not including the API and tests."

That's 58 classes just to implement the fluent interface, not counting the underlying EventComponent API. That's a lot of non-business logic code to write. How many projects are willing to invest that kind of time and effort to build a fluent interface? (I would guess "not many")

However, I bet there's a lot of template-izable code in Anders fluent interface. When he writes about keeping the language consistent by "creating branches within our grammar using different descriptor objects", I can help but think about parser development with YACC and the like. These tools typically use a DSL like BNF. Maybe we could build a DSL for building fluent interfaces?

Second, Anders makes a very interesting point about the structure of the fluent interface code:

Writing DSLs is a little different from the regular object oriented programming style. You might have noticed that the Plan class has a verb for its name rather than the usual noun. This allows us to have a natural starting point for writing out the "sentence" explaining our intention.

Where have you seen this verb based approach before? Powershell cmdlets.

Windows PowerShell uses a verb-noun pair format for the names of cmdlets and their derived .NET classes. For example, the Get-Command cmdlet provided by Windows PowerShell is used to retrieve all commands registered in the Windows PowerShell shell. The verb part of the name identifies the action that the cmdlet performs. The noun part of the name identifies the entity on which the action is performed.
[Cmdlet Verb Names, MSDN Library]

I've written about this aspect of PowerShell before:

In OO, most of the focus is on objects, naturally. However, administrators (i.e. the target audience of PS) tend to be much more task or action focused than object focused. Most OO languages don't have actions as a first class citizens within the language. C# and Java don't even allow stand alone functions - they always have to be at least static members of a class.

I'm fairly sure there are many reasons why strongly typed OO languages aren't popular among administrators. I'm not going to go down the static/dynamic typing rat hole here, but I would guess the object/action language tradeoff is almost as important as the typing tradeoff. What's nice about PowerShell is that while it has strong object support, it also has strong action support as well. In PS, actions are called Cmdlets. While I'm not a big fan of the name, having first class support for them in PS is one of the things I find most interesting.
[Perusing Powershell Part 1: Get-SQLServer, DevHawk]

While there is no first-class support for verbs or actions in C#, it looks like Anders has essentially rolled his own. For example, his Plan.Event() method returns a new EventDescriptor object. Subsequent calls on this object (RelatedTo, WithPriority, OrganizedBy) change the internal state of this EventDescriptor object. When you reach the end of the chain of calls, EventDescriptor has an implicit EventComponent cast operator that creates a new EventComponent with all the data that's been collected along the chain by the EventDescriptor.

Again, I can help but think a significant amount of code in this approach can be generalized and the creation automated. Also, I wonder if any of the new C# 3.0 capabilities could be used to improve the implementation. For example, would Extension Methods make it easier to build the fluent interface? Maybe / Maybe not. Regardless, Anders has given me a lot to noodle on.

Posted By Harry Pierson at 2:38 PM Pacific Daylight Time

Monday, June 25, 2007

Morning Coffee 94

  • By most accounts, the Capitals had a good draft this weekend. They started the day with ten picks across the seven rounds. The ended the day with ten prospects as well as three extra picks next year, including two second rounders. According to the GM George McPhee (aka GMGM), next year's is "supposed to be a terrific draft" which is probably true but what you always say when you trade down for future picks. On the other hand, if the guys you want are available further down, why not stock up on the future picks?
  • John Lam reports on Steve Yegge's Rails port to JavaScript that he saw at Foo Camp. Google (aka Steve's employer) wasn't interested in adopting Ruby or Rails since they already use C++, Java, JavaScript and Python. So Steve ported Rails to JavaScript. Wow. However, it does beg the question which is more valuable, Ruby or Rails? If you could have just one or the other, which would you choose?
  • Speaking of dynamic languages, Powershell Community Extensions v1.1 is out. I want to check out the new Elevate function. Currently, I'm using the Script Elevation PowerToys, but I would rather have a pure PS solution. (via Powershell Team Blog)
  • I always know it's a slow day when I decide to check TechMeme while writing my Morning Coffee post. Usually, I get plenty to write about from just my news reading. However, right now, even TechMeme seems mostly uninteresting. Only thing remotely interesting to me is Samsung's new 64GB solid state drive.
Posted By Harry Pierson at 9:57 AM Pacific Daylight Time

Wednesday, June 20, 2007

Morning Coffee 92

  • Brad Wilson blogs about SvnBridge, a tool that lets you use Subversion clients like TortoiseSVN to talk to Team Foundation Server. While I think that's cool, I wonder is anyone interested in subversion clients other than TortoiseSVN? For example, will people choose AnkhSVN instead of the Team Explorer Client?
  • Speaking of TortoiseSVN, I wonder if those guys are interested in building a TortoiseTFS project? I did find two other TFS shell extensions projects: Dubbelbock TFS and Turtle, though neither appears as full featured as Tortoise.
  • Scott Guthrie details VS08's multi-targeting support. Of course, the three versions of the .NET Framework VS08 can target all use the same underlying runtime, which probably made it easier to build.
  • Michael Platt refactors Don Box's original tenets of service orientation so he can include some information about how these services get built.
  • Scott Hanselman tackles the tricky question of assembly granularity.
  • PowerShell Analyzer is now available for purchase. Among other things your $59 gets you, besides a 50% savings, is "Feature request priority". That's pretty cool. I wonder how many other micro-ISV's take the approach of "pay me now and you get to help me pick some of the new features."
  • My Monitor SetupBrandon LeBlanc writes about dual monitor support in Vista. I'm loving the dual monitor support, though I have a somewhat strange setup. I keep my primary monitor rotated in portrait mode, which is great for reading and writing. I typically use my second monitor for blogs and mail. I even wrote a custom multi-mon wallpaper utility so I could easily generate new wallpapers for my non-standard monitor layout, including bitmap rotate support. If there's interest, I can post it. (via Sam Gentile)
  • Nick Malik continues to write about Mort, with the usual response from the usual folks. I liked his point that "You cannot fight economics with education", but otherwise I'm staying out of this discussion.
  • In the same vein, Martin Fowler writes about Technical Debt. I completely agree with his hypothesis that short changing design may save time in the short term but will cost much more in the long term. However, the problem is that the people who are making the tradeoff - i.e. the people paying for the project NOT the people building the project - either don't understand the tradeoff or are more than happy to sacrifice the long term cost for the short term gain. How are most projects measured? Being on time and on budget with the planned set of features. Very few projects - and none that I've ever seen - are goaled on long term maintainability. Until you can change that, this issue will continue to linger.
Posted By Harry Pierson at 12:03 PM Pacific Daylight Time

Monday, June 18, 2007

Morning Coffee 91

  • My wife loves me. I'm a very lucky man.
  • I'm starting to really dig Safari Books Online. Having a tablet really helps here, I can sit in bed and read and it's ALMOST like reading a real book. Is there an offline experience? Something like the NYTimes WPF Reader app would be killer.
  • I'm not a Twitter guy, but I like the idea of using it to publish CI results. Not quite as cool as using the Ambient Orb, but close. (via DotNetKicks)
  • Soma details the dogfood usage of TFS in Developer Division. Sorta interesting if you're into knowing that stuff. Brian Harry apparently has much more.
  • I realize that linking to Pat Helland every time he writes something is fairly redundant. If you want his feed, you know where to find it. But he writes great stuff! The latest is Accountants Don't Use Erasers, which talks about append-only computing. His point that the database is a cache of the transaction log is mind blowing, yet makes total sense.
  • Bruce Payette blogs a PS DSL for creating XML documents.
  • Jesus Rodriguez details WCF's new Durable Service support in .NET 3.5. I get the need for the [DurableServiceBehavior] attribute, but do I really have to adorn each of the service methods with [DurableOperationBehavior] too? That seems redundant. Also, I wonder how this looks at the channel layer?
  • Speaking of WCF's channel layer, I recently picked up a copy of Inside Windows Communication Foundation by Justin Smith. This is the first book I've found that has more coverage of the channel layer than the service layer, so I like it.
  • Dare writes about Web3S, Windows Live's general purpose REST protocol. Apparently, WL started with Atom Publishing Protocol, but found that it didn't meet their needs around hierarchy and granular updates. David Ing says it's "not that similar" to my concept of REST, but I going to read the spec before I comment.
  • Scott Hanselman writes about how he learned to program and some thoughts about teaching his son. Patrick has recently started expressing interest in programming (he want's to do what Daddy does). At four, I'm thinking I'll start him on Scratch (though ToonTalk looks interesting). As he gets older, I was thinking about Squeak, though I'm a smalltalk noob. I really like Scott's idea of creating a connection to the physical world via something like Mindstorms. Patrick loves Lego almost as much as his dad, so that would be cool.
Posted By Harry Pierson at 11:03 AM Pacific Daylight Time

Tuesday, June 12, 2007

Morning Coffee 88

I've got over 500 unread news posts and 200 emails in my inbox to process. So this is nowhere near comprehensive.

  • Clarius released the June 07 CTP of their Software Factory Toolkit. Big new feature in this drop is T4 Text Template editor that has syntax highlighting and eventually intellisense. They also released the May 07 CTP of VSSDK Assist, previously known as VSIP Factory. Haven't played with either yet, but it seems like a good time to be a tool builder.
  • PowerShell hits a million downloads in six months. No surprise there, IT'S FRAKING AWESOME. Jeff Snover details seven MSFT products using PS, promising many more that he can't talk about. See earlier comment about being fraking awesome.
  • Speaking of PS, I don't "get" Server Core because it doesn't support managed code. So no PS for Server Core. They announced @ TechEd that Server Core will support IIS 7, but since there's no CLR you can't run ASP.NET. As far as I'm concerned, no PS and no ASP.NET is below the minimum threshold of usefulness. I realize it's technical limitation related to the current factoring of the .NET Framework and I assume some team somewhere in Redmond is working on fixing it. But what's the point of releasing Server Core in the meantime?
  • QUT releases version 0.8 of their Ruby.NET compiler. Given that the IronRuby guys bootstrapped by licensing the Ruby.NET compiler, I wonder how these two projects will evolve side by side.
  • Speaking of Ruby, JRuby has gone 1.0. Congrats!
  • At TechEd, I saw my friend Steve Jones from Capgemini, and it's not this Steve Jones. Woops. But CRUD is still CRAP.
  • Pat Helland breaks Scott Hanselman's Rule #2 and details how he "lost a Megan".
  • My ex-teammate David Hill has been busy with Acropolis. If you are even the slightest bit interested in this technology, you should be reading his blog.
  • Microsoft acquired a company called Stratature last week. I don't typically track MSFT acquisition news + it was lost in the noise of TechEd. But Roger Wolter thinks it's a great move and that Stratature's Master Data Management hub product is one of the best. Given the importance of MDM in SOA, I think I need to go learn more about this product.
Posted By Harry Pierson at 8:58 AM Pacific Daylight Time

Friday, June 08, 2007

Morning Doughnuts 11

Harry will be back on Monday so I will returning to blogging on my website, while I will let the expert return to his normal posts here (not that he really took a break). I agree with Harry's post in that I really want to get something built so that we can talk about more than theoretical models. Like last time I appreciate the opportunity to sub for the master this last week. I hope that you found some of my entries interesting.

  • Sam Gentile wrote the other day why it's great to be a Microsoft developer. I enjoyed that post because I just celebrated the end of my first year here at Microsoft. At this point I am not sure what I have contributed, but I have learned a great deal and want to apply that knowledge over the next year to help the company to succeed. We really do have great people and great technologies.
  • The Seattle/Oklahoma City Sonics hired a GM who is only 30 years old. You know you must be getting old when the people running the sports teams are younger than you. :-) He comes from the Spurs organization though so at least he has a background from a successful franchise.
  • Ben Pearce listed out his top 5 questions about PowerShell this week at TechEd. He also recommends the book "PowerShell in Action" by Bruce Payette. I heartedly agree with this endorsement as the book is excellent.
  • It looks like there are going to be more family friendly games for the XBOX360. I for one am glad to hear that. The other day as I was trying to find some games my 4 year old with the broken leg could play I realized how many games I have that wouldn't be appropriate for him. This is very good news in my opinion.
Posted By Dale Churchward at 9:44 AM Pacific Daylight Time

TechEd 2007 - Heading Home

TechEd isn't technically over, but it is for me. I'm on a flight home in about four hours. Frankly, I am very excited to be going home. It's been almost a year since my last public presentation, and the only work travel I've done in the last 12 months was that Gartner EA conference last June, the Thomas Erl SOA workshop back in September and TechEd 07. I am simply out of practice being gone from home this long.

It doesn't look like I'll be going dark another 12 months before my next public presentation. People must have noticed me stick my head up to do TechEd, I've been asked about presenting at seven conferences that all happen in the next six months. I'll do a few - I hope to gravitate to the ones close to campus and don't require me to be gone very long - but my problem with presenting right now is that I'm still talking theory. I left evangelism because I wanted to build something. We're still getting started on that "build something" thing, so I don't have anything to show, just stuff we're thinking about building. Hopefully, by conference season next year, I'll actually have something to show.

My session yesterday went ok - I think it could have been better, but the audience seemed to get a lot out of it. It was a larger crowd Monday, but only one customer came up afterwards to discuss the talk with me. Yesterday, I had a half a dozen or so. I'd post slides for you dear reader, but I didn't do any. However, I think on of the sessions I will be doing in the next few months is basically a breakout version of this talk, so I'll need slides for that.

The attendee party was almost a bust due to rainstorm. When I got there around 8pm, the word was that all the rides but Spiderman were closed. So I rode Spiderman with a bunch of UK blokes I ended up hanging out with, and by the time we got out the rain had passed and almost everything was open again. Unfortunately, the one thing that didn't reopen was Hulk, which I was really looking to ride again. I got to ride it two years ago at TechEd 2005 as part of a special trip the TechEd core team took. But I did get to ride Spiderman, Dueling Dragons, Jurassic Park and Ripsaw Falls (I got drenched) which is pretty much all the big rides but Hulk.

I did take a little time out yesterday before the expo closed to go on a Swag Hunt, mostly to get little trinkets for my kids. I picked up my Sourcegear Evil Mastermind shirt on Monday (the only piece of swag I actually wanted). Mostly, it was the usual assortment of little flashlights, yo-yo's, and the like. I do want to give a shout out to the /n software folks, who were giving away a custom painted Xbox 360 with the Powershell logo. That was cool. Seemed almost every booth had some type of hi-tech gadget giveaway, but that was the coolest by far. They also gave me a copy of their new NetCmdlets product, which Dale has apparently been playing with. The question is, which will Dale be more jealous of: my copy of NetCmdlets or the cool PowerShell sticker I got for my laptop?

Posted By Harry Pierson at 5:31 AM Pacific Daylight Time

Thursday, June 07, 2007

Morning Doughnuts 10

  • I am a big fan of PowerShell, and I know Harry likes it as well. Of course I have aliased many of the commands so they appear more Unix like. I mention this because David Aiken mentions a new product for PowerShell called NetCmdlets produced by N Software. I downloaded a trial and have been impressed so far. If you use PowerShell it might be worth giving this a look.
  • The New Yorker has an interesting article about feature choices in technology. Basically it comes down to customers choose products with more features and customization options if given the choice, but when they actually have to use the products they prefer simplicity. I think that is something lost on those of us who design things. Giving users every possible option can make our products seem more difficult to use over simpler less feature rich choices. (via Coding Horror)
  • Well it took longer than some may have guessed, but Microsoft has been sued over the name Vista by a French TV company. Apparently they were going to launch a television station with the same name. I wonder what the courts will decide since apparently the TV company didn't register the name in the software category.
Posted By Dale Churchward at 9:46 AM Pacific Daylight Time

Friday, May 04, 2007

Morning Coffee 73

  • The MSDN folks have a utility for creating custom help files from the online MSDN library. I didn't realize MSDN even had a content service. This is tres useful.
  • Jeff Atwood explains how error-filled the web is and how error-tolerant modern web browsers are. I've often argued that one of the keys to the rise of Visual Basic was because it was tolerant of sloppiness. It's hard to argue with Jeff's conclusion that "forgiveness by default is what works".
  • BizTalk Labs shipped an update to the Connectivity Service. It "now supports simple publish and subscribe eventing. This allows multiple clients to subscribe to a service and receive notifications." Steve Maine has some details and a link to the MIX session he did with Don.
  • Larry O'Brein is happy about IronRuby, but was hoping to see a new Ruby/C# hybrid language. Even though it's his "#1 administrative programming language", he specifically hopes for a new language so would "have the flexibility to evolve the language." But Larry, MSFT already had an dynamic administrative language that it can evolve! It's called PowerShell...
  • The XNA folks have shipped a bunch of new content, including the Racing Game Starter Kit.
  • Machinima is growing up fast. I just discovered iClone, a real-time 3D animation filmmaking tool. You know, my birthday is coming up later this month...
Posted By Harry Pierson at 12:19 PM Pacific Daylight Time

Friday, April 20, 2007

Morning Coffee 67

  • Beta 1 of VS "Orcas" and .NET Framework 3.5 has shipped. Get it here. Besides LINQ, I'm most looking forward to experimenting with some of the new WF/WCF integration work. However, I don't think this beta includes DBPro functionality. Not surprising, given that DBPro only shipped a few months ago, but disappointing since I've moved all my database dev work over to that model.
  • Korby Parnell introduces Claimspace, part of the Microsoft.Community family. While the other family members are retreads - blogs, forums and tagging - but this seems like something fundamentally new - or at least new to me - and therefore interesting. (via Larkware)
  • Scott Hanselman updates the new version of Notepad2 to re-enable Ruby support originally built by Wesner Moise. Ruby is nice, but where's the PowerShell love?
  • After his performance in front the Judiciary Committee, Attorney General Gonzales is grossly incompetent, lying or both. What does it say about President Bush that he was "pleased with the Attorney General’s testimony"? It says Bush values loyalty over competence, is hiding something or both. Given that his approval ratings can't get much worse, I guess standing by Gonzales even in the midst of bi-partisan calls for his resignation isn't going to affect Bush much politically. On the other hand, confirming a new AG with a Democratic congress and low 30% approval rating might be devastating, depending on the bodies buried over there.
Posted By Harry Pierson at 9:35 AM Pacific Daylight Time

Tuesday, April 10, 2007

Morning Coffee 60

My car has a new battery so I am back in the office with my nose on the grindstone. I've spent most of the morning talking about SOA and my MSIT project, so I only have a few items today.

  • Nicholas Carr illustrates the coming competiton between SalesForce.com and Google. Very interesting. Of course, that doesn't damp "their mutual disdain for the Horrible Monster of Redmond" as Carr puts it.
  • I decre that Peter Schneider officially has too much time on his hands. I mean, if he's got time to implement a compiler and interpreter for Brainfuck in Powershell, what else has he got time for? On the other hand, it's short and shows how internal DSL friendly PS can be. (via Larkware)
  • Jeff Atwood wonders if MTurk is a failure. I wrote a year ago that MTurk is a successful feature, but would be a failure as a stand-alone service. As I wrote then, "I’m guessing it would be worth it to Amazon to run the service even if they were the only ones using it."
Posted By Harry Pierson at 10:15 AM Pacific Daylight Time

Friday, March 16, 2007

Morning Coffee 46

Sort of late this morning due to back to back meetings...

  • I seem to have stirred up a bit of a hornet's nest with my "kinda surprising that no other mainstream language has done this before" comment. Dennis Hamilton and Mike Parsons both asked about other dynamic languages like Javascript and Python in my comments. To be clear, the ability to add a new method to a specific object instance is fairly common in dynamic languages. Extension methods in C#3/VB9 is a different capability - it only supports adding new methods to a class, not to specific object instances. I'm not sure what dynamic languages other than Ruby supports adding new methods to both object instances and classes, but I'm sure they're out there.
  • Some anonymous commenter asked "why invent another language for PowerShell if there are so many great popular languages already in existance [sic]?" I can't speak for the PowerShell team, but I think they were better off inventing a new language specificly designed for their scenario than they would have been shoe-horning in existing lanugage. To their credit, it looks like the PS team took great care to make the PS lanugage accessable by leveraging common syntax and idioms from other shell programming environments. I'm not a shell programming expert, but isn't PS more a variant of shell languages that have come before than a brand new language?
  • I want a "Works on My Machine" T-Shirt.
Posted By Harry Pierson at 10:32 AM Pacific Standard Time

Thursday, March 15, 2007

I'm Wrong Because Ruby and Powershell Are Mainstream

Brad Wilson and Scott Hanselman took me to task for my comment the other day that no "mainstream" language had implemented extension methods:

How mainstream is Ruby on Rails for you? Ruby is a full fledged dynamic language. No hacks for "extension methods" (Brad)

Ya, I kind of blanched at that statement too...method_missing is pretty mainstream... (Scott)

They're right, Ruby does support the addition (and redefinition I think) of methods on a class at any time. There's a sample of this in the Classes and Objects chapter of Programming Ruby (aka the pick-axe book) where they add a basic documentation facility "available to any module or class" in Ruby by adding a doc instance method to the Module class.

class Module
  @@docs = Hash.new(nil)
  def doc(str)
    @@docs[self.name] = str
  end

  def Module::doc(aClass)
    # If we're passed a class or module, convert to string
    # ('<=' for classes checks for same class or subtype)
    aClass = aClass.name if aClass.type <= Module
    @@docs[aClass] || "No documentation for #{aClass}"
  end
end

Given how Ruby classes are defined, I think the newly added methods have access to the private data of the class. Extension methods in C#3/VB9 only have access the public interface of the object. But that's a fairly minor difference.

FYI, Powershell can do this as well, though not as succinctly as Ruby. Scott has an example how you can add a DatePhotoTaken property to System.IO.FileInfo using Omar Shahine's PhotoLibrary project.

Chalk this up to my continuing ignorance of dynamic languages. I'm working on it, albeit slowly.

Posted By Harry Pierson at 12:53 PM Pacific Standard Time

Tuesday, February 20, 2007

Internal DSLs in PowerShell

(Harry is on a secret mission in uncharted space this week, so instead of the daily Morning Coffee post, you get a series of autoposted essays. This post combines both some leftover learnings about Ruby from Harry's Web 2.0 days with his recent obsession with PowerShell.)

My first introduction to the idea of internal DSLs was an article on Ruby Rake by Martin Fowler. Rake is Ruby's make/build utility. Like most build tools like Ant and MSBuild, Rake is a dependency management system. Unlike Ant and MSBuild, Rake doesn't use an XML based language. It uses Ruby itself, which has huge benefits when you start doing custom tasks. In Ant or MSBuild, building a custom task requires you to use a external environment (batch file, script file or custom compiled task object). In Rake, since it's just a Ruby file, you can start writing imperative Ruby code in place.

Here's the simple Rake sample from Fowler's article:

task :codeGen do 
  # do the code generation 
end 

task :compile => :codeGen do 
  # do the compilation 
end 

task :dataLoad => :codeGen do 
  # load the test data 
end 

task :test => [:compile:dataLoad] do 
  # run the tests 
end

The task keyword takes three parameters: the task name, an array containing the task dependencies and a script block containing the code to execute to complete the task. Ruby's flexible syntax allows you to specify task without any dependencies (:codegen), with a single dependency (:compile => :codegen), and with multiple dependencies (:test => [:compile,:dataLoad])

So what would this look like if you used Powershell instead of Ruby? How about this:

task codeGen { 
  # do the code generation 
}

task compile codeGen {
  # do the compilation 
}

task dataLoad codeGen { 
  # load the test data 
}

task test compile,dataLoad {
  # run the tests 
}

Not much different. PS uses brackets for script blocks while Ruby uses do / end, but that's just syntax. Since it lacks Ruby's concept of symbols (strings that start with a colon), PS has to use strings instead. Otherwise, it's almost identical. They even both use the # symbol to represent a line comment.

There is one significant difference. For tasks with dependencies, Rake uses a hash table to package the task name and its dependencies. The => syntax in Ruby creates a hash table. Since the hash table has only a single value, you can leave of the surrounding parenthesis. The key of this single item hash table is the task name while the value is an array of task names this task depends on. Again, Ruby's syntax is flexible, so if you have only a single dependency, you don't need to surround it in square brackets.

In Powershell, the hash table syntax isn't quite so flexible, you have to surround it with @( ). So using Rake's syntax directly would result in something that looked like "task @(test = compile,dataLoad) {...}" which is fairly ugly. You don't need to specify the square brackets on the array, but you having to add the @( is a non-starter, especially since you wouldn't have them on a task with no dependencies.

So instead, I thought a better approach would be to use PS's variable parameter support. Since all tasks have a name, the task function is defined simply as "function task ([string] $name)". This basically says there's a function called task with at least one parameter called $name. (All variables in PS start with a dollar sign.) Any parameters that are passed into the function that aren't specified in the function signature are passed into the function in the $args variable.

This approach does mean having to write logic in the function to validate the $args parameters. Originally, I specified all the parameters, so that it looked like this: "function global:task([string] $name, [string[]] $depends, [scriptblock] $taskDef)". That didn't work for tasks with no dependencies, since it tried to pass the script block in as the $depends parameter.

Here's a sample task function that implements the task function shown above. It validates the $args input and builds a custom object that represents the task. (Note, the various PS* objects are in the System.Management.Automation namespace. I omitted the namespaces to make the code readable.)

function task([string$name)     
{    
  if (($args.length -gt 2-or ([string]::isnullorempty($name)))    
  {    
    throw "task syntax: task name [<dependencies>] [<scriptblock>]"    
  }    
       
  if ($args[0-is [scriptblock])    
  {    
    $taskDef = $args[0]    
  }    
  elseif ($args[1-is [scriptblock])    
  {    
    $depends = [object[]]$args[0]    
    $taskDef = $args[1]    
  }    
  else    
  {    
    $depends = [object[]]$args[0]
    #if a script block isn't passed in, use an empty one    
    $taskDef = {} 
  }    

  $task = new-object PSObject    
  $nameProp = new-object PSNoteProperty Name,$name    
  $task.psobject.members.add($nameProp)    
        
  $dependsProp = new-object PSNoteProperty Dependencies,$depends    
  $task.psobject.members.add($dependsProp)    
        
  $taskMethod = new-object PSScriptMethod ExecuteTask,$taskDef    
  $task.psobject.members.add($taskMethod)    
        
  $task    
}

Of course, you would need much more than this if you were going to build a real build system like Rake in PowerShell. For example, you'd need code to collect the tasks, order them in the correct dependency order, execute them, etc. Furthermore, Rake supports other types of operations, like file tasks and utilities that you'd need to build.

However, the point of this post isn't to rebuild Rake in PS, but to show how PS rivals Ruby as a language for building internal DSLs. On that front, I think PowerShell performs beautifully.

I'm looking forward to using PowerShell's metaprogramming capabilities often in the future.

Posted By Harry Pierson at 11:08 PM Pacific Standard Time

Friday, February 16, 2007

Morning Coffee 33

I realize yesterday I said I was on vacation starting today. In reality, I'm not going to the office today, but I have time to post this before my vacation starts in earnest.

  • I hit Zero Email Bounce in advance of my vacation. It's been quite a while since the last time I got here and I hope to hit it much more often in the future.
  • The DSL tools team shipped a Designer Integration PowerToy that allows you to integrate models from multiple DSL designers into a single authoring tool. Gareth has more here.
  • Assorted PowerShell links: PowerShell Analyzer and PowerShellIDE. Both look interesting.
  • Personally, I like Notepad2 but apparently the only way to add a new syntax highlight scheme requires modifying the source code. Ugh. Anyone out there already added PS support to Notepad2? How about a suggestion for a simple text editor that supports extensible syntax highlighting?
  • Steve, Nick and Tomas all commented on my long running services WCF post. Tomas mentions Advanced Message Queuing Protocol (AMQP) which looks to be developing an open spec queuing system like MSMQ or MQ series. Interesting, but given the lack of involvement of the major MQ and DB vendors, I'm hard pressed to imagine this gaining any kind of critical mass.
Posted By Harry Pierson at 8:59 AM Pacific Standard Time

Wednesday, February 14, 2007

Morning Coffee 31

  • Architect MVP business news keeps on coming. Today it's Corillian - the company Scott Hansleman works for - getting acquired by CheckFree.
  • Los Angeles is looking to provide city-wide low-cost (maybe free) wireless access. My father has often suggested that Internet access be treated like other utilities like water and power. Sounds like LA is heading down that path. I wonder if they're looking at WiMAX?
  • The .NET Micro Framework - which powers the SPOT watch - now has an SDK. For those keeping track, that makes three embedded solution platforms from Microsoft, the Micro FX, Windows CE (which also just shipped a new version) and Windows XP Embedded. (via Larkware)
  • BEA's Bruce Graham talks somewhat obtusely on a topic I am particularly passionate about: putting more power in business people's hands to build their own systems. (via Joe McKendrick)
  • Register for the Windows Home Server beta. Also check out the forums, team blog and SuperSite Preview. Looks pretty sweet (via Scott Hansleman)
  • The final version of Live Search for Mobile was released a few days ago. This program rocks. I'm using the Windows Mobile version, but there's also J2ME version as well. (via Dare Obasanjo)
  • Any lingering interest I had in Ruby vanished yesterday as got to chapter 8 of Windows Powershell in Action. Chapter 8 is called "ScriptBlocks and Objects" and it is specifically about meta-programming. After reading that chapter, PS seems more flexible in this space than Ruby, which is the current industry darling for metaprogramming. For example, in Ruby you can optionally pass a block of code to any method. In PS, you can define a ScriptBlock like any other parameter. That means you can tell from the method signature that the ScriptBlock is used. Or you can define a function that takes multiple ScriptBlock parameters. Much more thought on this is needed.
Posted By Harry Pierson at 9:59 AM Pacific Standard Time

Wednesday, February 07, 2007

Perusing Powershell Part 2: Error or No Output?

In yesterday's post on PS, I provided the source for my implementation of Get-SQLServer. I realized after I made the post that there was a significant bug in the ProcessRecord method. If you specify a service instance (default or named), the cmdlet makes no effort to actually validate that such a SQL server instance exists. So if you ask for a instance that doesn't exist, Get-SQLServer will happily write an invalid Server object to the pipeline. So I changed it to actually validate that the specified instance exists. I connect to the specified machine (local machine if not specified) using ManagedComputer and look in it's ServerInstances collection for the specified SQL instance.

The question is, what should you do if the specified SQL instance doesn't exist on the specified machine? One the one hand, you could write an error indicating that the SQL instance doesn't exist. Or, you could simply write nothing to the output pipeline, which may cause an error down the line.

Which is the right approach?

At first, I wrote an error when I couldn't find the instance, but decided that wasn't the right approach. It isn't really an error unless you attempt to act on that instance, right? So I thought the more PS friendly approach would be to write nothing and let the down stream cmdlets deal with it. I do write a debug message if the specified instance doesn't exist, so the scripter isn't completely in the dark.

So here's the new and improved ProcessRecord method of my Get-SQLServer cmdlet:

protected override void ProcessRecord()
{
    //Make sure both -Name and -Default aren't specified
    if (!string.IsNullOrEmpty(_Name) && _Default.IsPresent)
    {
        WriteError(new ErrorRecord(
            new ArgumentException(
                "Default and Name parameters can't both be specified"),
            "DefaultAndName",
            ErrorCategory.InvalidArgument,
            null));

        return;
    }

    //If the machine name is not specified, assume the local machine 
    //(via the "." value)
    string machine = string.IsNullOrEmpty(_MachineName) ? "." : _MachineName;

    //Connect to the specified machine via the SMO WMI ManagedComputer object
    SmoWmi.ManagedComputer mc = new SmoWmi.ManagedComputer(machine);

    if (string.IsNullOrEmpty(_Name) && !_Default.IsPresent)
    {
        //If neither Name or Default are specified, write all the 
        //server instances on specified machine
        foreach (SmoWmi.ServerInstance si in mc.ServerInstances)
            WriteServerObject(si);

        return;
    }

    string instanceName = _Default.IsPresent ? "MSSQLSERVER" : _Name;

    if (mc.ServerInstances.Contains(instanceName))
        WriteServerObject(mc.ServerInstances[instanceName]);
    else
        WriteDebug("The specified SQL instance does not exist");
}

//Helper method to create a SMO Server object from a 
//SMO WMI ServerInstance object and write it to the pipeline
private void WriteServerObject(SmoWmi.ServerInstance si)
{
    if (si.Name == "MSSQLSERVER")
        WriteObject(new Smo.Server(si.Parent.Name));
    else
        WriteObject(new Smo.Server(si.Parent.Name + "\\" + si.Name));
}
Posted By Harry Pierson at 12:00 PM Pacific Standard Time

Tuesday, February 06, 2007

Perusing Powershell Part 1: Get-SQLServer

I wrote this morning that I've shifted my new language focus from F# to PowerShell. I did this for a variety of reasons, but primarily because PowerShell is the future of Microsoft administration while F# is a research project. The thing that interests me most about F# is its support for hybrid OO/functional programing. Turns out, PS uses a different approach, but accomplishes much of the same goal.

In OO, most of the focus is on objects, naturally. However, administrators (i.e. the target audience of PS) tend to be much more task or action focused than object focused. Most OO languages don't have actions as a first class citizens within the language. C# and Java don't even allow stand alone functions - they always have to be at least static members of a class.

I'm fairly sure there are many reasons why strongly typed OO languages aren't popular among administrators. I'm not going to go down the static/dynamic typing rat hole here, but I would guess the object/action language tradeoff is almost as important as the typing tradeoff. What's nice about PowerShell is that while it has strong object support, it also has strong action support as well. In PS, actions are called Cmdlets. While I'm not a big fan of the name, having first class support for them in PS is one of the things I find most interesting.

PS is designed to be extended. And while there is support for defining functions in PS directly, for the most part PS is designed to be extended in a .NET OO language like C#. I have mixed feeling on this. Languages like F# and Ruby allow for these sorts of extensions to be built within the language itself. On the other hand, having a strong separation between scripting the shell and extending the shell simplifies the scripting experience without sacrificing capability of building extensions.

Here's a simple cmdlet I wrote called Get-SQLServer. SQL Server already comes with a robust object oriented administration library, but no support for PS (no surprise, since PS just shipped). I imagine future versions of SQL will have PS support, but to me this represents a great opportunity to get deep understanding of PS as well as focus on PS cmdlet design without having to do much of the grunt work.

using System;
using System.Management.Automation;
using Microsoft.SqlServer.Management.Smo.Wmi;
using Microsoft.SqlServer.Management.Smo;

[Cmdlet(VerbsCommon.Get, "SQLServer")]
public class GetSqlServerCommand : Cmdlet
{
    private string _Name;
    [Parameter]
    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    private string _MachineName;
    [Parameter]
    public string MachineName
    {
        get { return _MachineName; }
        set { _MachineName = value; }
    }

    private SwitchParameter _Default;
    [Parameter]
    public SwitchParameter Default
    {
        get { return _Default; }
        set { _Default = value; }
    }

    protected override void ProcessRecord()
    {
        string machine = 
            string.IsNullOrEmpty(_MachineName) ? "." : _MachineName;

        if (string.IsNullOrEmpty(_Name) && !_Default.IsPresent)
        {
            //write all server instances on specified machine
            //if _machineName is null or empty, the local machine is used
            ManagedComputer mc =  new ManagedComputer(machine);
            
            foreach (ServerInstance si in mc.ServerInstances)
            {
                if (si.Name == "MSSQLSERVER")
                    WriteObject(new Server(machine));
                else
                    WriteObject(new Server(machine + "\\" + si.Name));
            }

            return;
        }

        if (!string.IsNullOrEmpty(_Name) && _Default.IsPresent)
        {
            WriteError(new ErrorRecord(
                new ArgumentException(
                    "Default and Name parameters can't both be specified"),
                "DefaultAndName",
                ErrorCategory.InvalidArgument,
                null));

            return;
        }

        if (_Default.IsPresent)
            WriteObject(new Server(machine));
        else
            WriteObject(new Server(machine + "\\" + _Name));
    }
}

As you can see, it's fairly simple. The cmdlet takes three parameters - Name, MachineName and Default. MachineName represents the windows server machine the SQL server instance is running on. Name is a common PS parameter, and here is used to specify the SQL instance name you're interested in. However, since the default instance of SQL on a given server doesn't have a name, I had to add a Default flag. Since the cmdlet can return a collection of SMO Server objects, I needed a way to distinguish between "Give me the default instance on a machine" and "Give me all instances on a machine". I couldn't use a null or empty Name parameter to mean both. If neither Name or Default are specified, it means the user wants a collection. If both are specified, it's an error. Otherwise, the cmdlet returns a single Server object - either the default or a named instance as specified.

Using the cmdlet is fairly straight forward. If you simply specify "Get-SQLServer", it gives you a collection of all the SQL Server instances on the local machine. If you specify "Get-SQLServer -Default", it gives you just the default SQL Server instance on the local machine. And if you specify "Get-SQLServer -Name sqlexpress", it gives you just the SQL Express instance on the local machine. Using the -MachineName parameter allows you to connect to a remote SQL server box, but is otherwise the same.

Of course, this is a very simple cmdlet. It doesn't even change the current state of the system. But now that we have a reference to a SQL Server instance, we can call methods on that instance. In the next post (whenever that is), I'll build some cmdlets to let me create and drop databases on that instance.

Update: Removed syntax coloring from code because it looked bad in my news reader.

Later Update: Fixed the syntax coloring

Posted By Harry Pierson at 2:19 PM Pacific Standard Time

Friday, February 02, 2007

Morning Coffee 23

  • My Binding Across States post made it to the home page of DotNetKicks, so at last six other people liked it. I wonder if I'll be able to detect and traffic increase from that.
  • I wrote yesterday that I had ordered a PCMCIA Smart Card reader for my laptop. I ordered it around 11:30pm on Wednesday and it arrived yesterday around 2pm.That's good service! And so much more convenient than the USB smart card reader.
  • I also mentioned yesterday that I had moved my laptop over to Vista. I'm not sure why, but my battery life has gotten significantly better. Maybe it's because these days I'm primarily using my laptop to remote into my desktop so I'm not exercising the local system much.
  • I was checking out Windows PowerShell Quick Reference from O'Reilly (on Safari) and discovered this PS offers the numeric constants of gb, mb, and kb to represent gigabytes, megabytes, and kilobytes. Example: $downloadTime = (1gb + 250mb) / 120kb. That's pretty cool.
  • Speaking of PS, I stumbled across PowerSMO! from Dan Sullivan. Instead of building native PS support for SQL administration, PowerSMO! makes it easy to access SMO objects in PS. Instead of having to call "new-object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer", you call "Get-SMO_ManagedComputer". Even more interestingly, PowerSMO! uses metaprograming techniques to generate all the Get_SMO* methods. It iterates over all the SMO types - about 1000 types in total - and generates the associated Get-SMO functions into a temp script file. Once the temp file is created, it can be invoked like any other script. Must noodle on this approach further.
Posted By Harry Pierson at 9:56 AM Pacific Standard Time

Thursday, February 01, 2007

Morning Coffee 22

  • I figured out something to build with PowerShell. Not ready to spill all the beans yet, but I've started by building a provider for SQL Server. SQL already has the SQL Management Objects (SMO) library, so I can really focus on how PowerShell works rather than getting too bogged down in the logic of the provider. I'm sure someone else is working on something similar, but my primary goal with building this provider is to understand PowerShell. The codebase itself is a distant second in priority.
  • On the subject of missing LINQ's, Alex James wants LINQ to Web. A good potential use for the Windows Live Search API.
  • I posted three recent blog posts to DotNetKicks yesterday, but I've only collected one additional kick so far (for my Compiling Workflows post). Looking at what does gather kicks, I think I would need to write a more dev focused article if I wanted to make the DNK home page.
  • Don Smith left a comment on my WSSF post where he talked about the developer and the architect perspective. He seemed surprised that I took the developer perspective. To quote David White: "Architect Must Implement". The customization opportunity in guidance automation is huge, but the value is to the developer first. And while it's a good start, it doesn't go very far at automating the development experience. At heart, I guess I'm a developer even though my business card sez Architect (with a capital "A" these days no less).
  • I moved my laptop over to Vista yesterday. My workstation is still on XP, but that's because I haven't had time to completely rebuild my dev environment. No Aero support with the
  • I elbowed my way into the TS Gateway pilot at Microsoft and I'm loving it. TS Gateway is a new feature of Longhorn Server that "enables authorized remote users to connect to terminal servers and remote desktops on the corporate network from any Internet-connected device running Remote Desktop Connection 6.0." So I can quickly and easily remote into my desktop from anywhere without establishing a VPC session. The only annoyance is my USB smart card reader, which is fine in a pinch but a pain to constantly have dangling off my laptop. However, my boss approved a PCMCIA smart card reader so soon that won't be an issue.
Posted By Harry Pierson at 10:41 AM Pacific Standard Time
Change Congress
Recent Bookmarks
Tags .NET Framework (2) __clrtype__ (9) ADO.NET (5) Agile (7) AJAX (3) Architecture (288) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (94) Web Services (5) ASP.NET (25) Async Messaging (2) Azure (1) Battlestar Galactica (3) BI (2) BizTalk (4) Blogging (117) dasBlog (11) Podcasting (4) BPM (1) C# (11) C++ (4) Capitals (5) CardSpace (3) CLR (2) CodePlex (1) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Debugger (23) Dependency Injection (2) Development (122) C Plus Plus (1) Embedded (5) Lanugages (42) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (25) Domain Specific Languages (15) Durable Messaging (5) Dynamic Languages (12) Dynamic Silverlight (1) Education (3) Enterprise 2.0 (1) Entertainment (14) ETech (15) F# (51) Functional Programming (17) Game Development (2) Guidance Automation (3) Hardware (8) HawkCodeBox (1) HawkEye (3) Health (1) Hockey (31) Home Electronics (1) Home Network (5) Hosting API (1) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (112) IronRuby (16) Java (2) Job (3) Kodu (1) LangNET (2) Lightweight Debugger (5) LINQ (23) Live Framework (3) Live Mesh (2) Lost (1) Master Data Management (1) Media 2.0 (6) Microsoft (31) MIX06 (2) Mobile Phone (1) Monads (5) Morning Coffee (172) Object Oriented (4) Office (5) Open Source (8) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (33) Games (18) General Geekery (27) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (19) Parallel Programming (3) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (5) Politics (48) Polyglot (3) PowerPoint (2) PowerShell (39) Presentation (7) Projects (1) HawkWiki (1) Pygments (5) Python (6) Quote of the Day (4) Refactoring (1) Research (2) REST (18) Reuse (5) Robotics (2) Rock Band (4) Rome (5) Ruby (23) Ruby on Rails (1) Sci-Fi (2) Scripting (4) Security (3) Service Broker (14) SharePoint (2) Silverlight (20) Social Software (1) Software + Services (2) Software Design (2) Software Engineering (1) Software Factories (11) Software Industry (1) Space Elevator (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (7) Unified Client (1) Unit Testing (4) USC (1) UX (1) Virtual PC (2) Visual Basic (3) Visual Studio (20) Volta (2) Washington Capitals (37) WCF (31) Web 2.0 (67) Web Services (7) WF (21) Windows (3) Windows Live (29) Windows Live Writer (3) WPF (8) Xbox (1) Xbox 360 (54) XML (11) XNA (15) Zune (4)
Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion.