StudioShell 1.2 Released

imageA bit late to the blog, but I’m happy to say that StudioShell 1.2 has been released!  This release has been a long time coming, due largely to my lack of focus and a rather ambitious feature set.

This post is a breakdown of the key elements in the 1.2 release.  I’ll elaborate more on some of these items in future posts.

NuGet Support

While I prefer the StudioShell console experience over NuGet, NuGet has a user base that is 170 times larger than StudioShell.  It’s silly not to do everything I can to support that environment – both in terms of enabling StudioShell features in the NuGet host and in leveraging the NuGet distribution mechanism. 

In the previous releases, the majority of StudioShell features were available from the NuGet console; however, some of the more “luxurious” features wouldn’t work – for instance, you could add menu commands from the NuGet console:

1 PM> new-item dte:/commandbars/menubar/help ` 2 -name clickthis -value {"hello world!" | out-host}

The “clickthis” menu item would appear, but it wouldn’t do anything when you clicked on it.  The 1.2 release addresses these shortcomings – you can now expect full support for StudioShell functionality from the NuGet package manager console.

In addition, you can now install StudioShell via NuGet.  Just search the public repository for the “StudioShell” package:

1 PM> install-package StudioShell

PowerShell Support

One of the most frequent requests I receive is to use StudioShell from the standard PowerShell console.  This would be a great enabler for automated build scenarios and software factories.

This is now possible with the 1.2 release.  You can pull StudioShell into your standard PowerShell console just like any other module:

1 > import-module StudioShell

This results in a DTE: drive that is attached to a new instance of Visual Studio that you can use to load solutions, edit projects, create code, etc. 

Experimental SSMS Support

A friend of mine is interested in using StudioShell in other Visual Studio shell applications – specifically in BIDS.  We haven’t gotten that far, but the StudioShell 1.2 MSI installer does allow you to integrate with SQL Server Management Studio 2012 (Denali). 

Not all of the DTE: drive is available – in particular the project and code models don’t seem to be supported in SSMS.  At the same time, there is still a lot of useful functionality available.  E.g., the debugger hive is fully functional, allowing you to spelunk stacks, locals, etc. during a SQL debugging session.

This feature should be considered highly volatile until we can get some people using it regularly and reporting the issues.  Use at your own risk.

DTE: Drive Topology

In the past year I’ve learned quite a bit about designing useful PowerShell providers.  I’ve applied some of this knowledge to the StudioShell PSDTE provider by changing the layout of some of the drive nodes.

In previous releases the code model and project model occupied a shared space on the DTE: drive.  This made sense from an object-model perspective – projects contain files, files contain code.  Unfortunately it made for some slow pipelines; for instance, applying global code changes:

1 ls dte:/solution -rec | ` 2 where {$_ -match 'codeclass' } | ` 3 set-itemproperty -name Comment -value (get-date)

would force iteration of all project items, properties, and code.  Very slow operation during which the shell and Visual Studio remain unavailable.  The new drive topology moves the code model to a peer of the project model:

1 ls dte:/solution/codemodel -rec | ` 2 where {$_ -match 'codeclass' } | ` 3 set-itemproperty -name Comment -value (get-date)

effectively isolating code from projects and enabling faster “bulk” operations.

These changes are breaking for existing scripts that rely on the old path topology, but 1.2 includes a simple way to revert the drive topology to the previous version when you need to:

1 > use-pathTopologyVersion 1.0

In a nutshell, this command tells the PSDTE provider to use the drive topology that existed in the specified version of StudioShell.  If you have a script that relies on these old paths, just add a call to use-pathTopologyVersion to the top of the script and StudioShell will re-enable the old paths.  When you’re done, you can bounce back to the current topology just as easily:

1 > use-pathTopologyVersion -current

Cleaner Codebase

StudioShell started as a very … organic project.  It grew as I needed it to grow, and it still does.  As a friend once understated, “it’s a bit monolithic.”  The code needed some serious refactoring before any of the previous features could be realized.

A quick shout-out to two vendors who proved key in this process: NDepend was essential in teasing apart concerns, and PostSharp greatly simplified several feature implementations.

Bug Fixes

Of course this release contains plenty of fixes as well.  A special thank-you to everyone who supports this project by submitting issues and discussing features.  Keep ‘em coming.

Looking Ahead – looking for help

So what’s next for StudioShell?  First and foremost is a more aggressive release pipeline.  With 1.2 comes a PSake build, the next step is to incorporate automated deployments to NuGet and CodePlex.  I don’t want to wait another 6 months to package a release.

I’m also looking at expanding the DTE drive topology to include some other Visual Studio services.  More on this later.

I’d also like some help getting StudioShell usable in other shells, especially the SQL family of Visual Studio shells.  If you have the inkling to help, please get in touch.

kick it on DotNetKicks.com
E-mail • Permalink • Comments (0)

MAssaging Pipeline Input with ScriptBlocks

imageI’m hard at work here in Code Owls labs building a super-secret PowerShell project that will absolutely blow you away.  Or totally muss your hair.  Well, provide a slightly refreshing breeze at least.  More on that later…

Today I was floored to discover an incredibly useful feature of PowerShell that I never knew existed: you can alter input from the pipeline by supplying a scriptblock as the input parameter value.  Yeah, I don’t understand that sentence either, so let’s look at an example.

Here’s a simple PowerShell function that accepts input from the pipe:

1 function Test 2 { 3 param( 4 [Parameter( ValueFromPipeline=$true )] 5 [object] 6 $i 7 ) 8 9 process 10 { 11 $i; 12 } 13 }

It quite literally just drops its input back to the pipe.  Here it is in action:

> 1,2,3 | Test 1 2 3

or you can use it like so:

> Test -i 1,2,3 1 2 3

Riveting, no? 

But watch what happens when we a) supply pipeline input and b) specify a scriptblock as the “i” parameter:

> 1,2,3 | Test -i { $_ + 1 } 2 3 4

O.M.G.S.T.F.U!!  The pipeline input is passed through the scriptblock before being passed to the Test function as input!  I’m sure plenty of you knew about this, and I scold each of you for not telling me and letting me continue to write junk pipelines using foreach-object to achieve the same thing:

> 1,2,3 | foreach{ $_ + 1 } | Test 2 3 4

Well, never again thank you.

All lightness aside, this is a fundamental aspect of pipelining that I hadn’t encountered until this afternoon.  I have to admit I’m a bit ashamed at living without this trick in my bag for so long, so let me share what I’ve learned in the hopes of regaining some shell cred:

  1. This works for parameters marked as accepting either ValueFromPipeline or ValueFromPipelineByPropertyName input.  Parameters that do not accept pipeline input are except from this little gem.
  2. The parameter MUST have a type spec (e.g., the [object] attribute on the $i parameter in my Test function).  If you leave off the type spec, you’ll get a nasty parameter binding exception.

And it works wherever pipeline input is applied, in both your own PowerShell and in the standard cmdlet battery:

> get-history | out-file ./history.ps1 -input { $_.commandline} > cat ./history.ps1 # ... ls get-counter '\processor(*)\*' | select -prop countersamp* #... get-history -?

Oh, the pipelines we’ll save with this!  Enjoy!

Edit 01.05.2012

Fixed incorrect statement that scriptblocks do not work for parameters marked as ValueFromPipelineByPropertyName.

kick it on DotNetKicks.com
E-mail • Permalink • Comments (0)

Charlotte PowerShell Users Group

CharlottePoshUgI’m very excited to announce that exactly one month from today will be the first meeting of the Charlotte PowerShell Users Group.  Moreover, I’m giddy with anticipation as this first meetup will play host to Ed Wilson of the Microsoft Scripting Guys blog and “the Scripting Wife” Teresa!

We’ll be meeting at the Charlotte Microsoft campus at 6pm on January 5, 2012.  The schedule for this meeting is roughly as follows:

  • 6:00 – 6:30 pm: arrive and socialize.
  • 6:30 – 7:00 pm: sponsors, group roundtable.
  • 7:00 – 9:00 pm: Ed Wilson discusses PowerShell Best Practices

If you are near Charlotte, North Carolina and use PowerShell in any capacity, I encourage you to join the group and attend this meetup.  Not only will you reap the benefits of Ed’s talk, but you’ll help shape the group to best serve the local PowerShell community!

kick it on DotNetKicks.com
E-mail • Permalink • Comments (0)

An Apology to Kevin Mitnick

imageI’ve been reading the book Ghost in the Wires by social-engineer-extraordinaire Kevin Mitnick.  The book is completely engrossing, and I’ve been enjoying the story so much I had to tweet about it:

Reading Ghost in the Wires by Kevin Mitnick. Absolutely mesmerizing account of simple and effective social engineering exploits.

… and as it happens on twitter, Mr. Mitnick happened to be wading in the conversation flow and replied:

glad you liked it. Please put your comments on Amazon for me.

… and as it also happens on twitter I wrote a knee-jerk reply:

surely I will. Also will purchase some of your other books. Also, please don't steal any of my digital identity stuff, k?

…and as it usually comes to pass I then imagined the whole of my twitter following offering up a rowdy “har-dee-har-har” and I got back to work.

… and then I started to get deeper into the book. 

… and I started to get a feel for the raw deal that Mr. Mitnick has received. 

… and I thought back to my attempt at humor (see the underlined portion of my last tweet, above) and realized with some statistical certainty just how many times Mr. Mitnick has had to endure crap like that from rubes like myself.

Hey, I’m under no illusion that my comment had any effect on the man.  However, an apology is in order, if only to serve as a self-reminder not to tweet without thinking.

So, Mr. Mitnick, if you happen to find this:

I sincerely apologize for my off-hand and thoughtless attempt to be cute.  The only rectification I can offer is a promise to apply more mental processing to my tweets from this point forward. 

If it’s any consolation, the overly-intimate relationship between corporate IT policy and law is something I think about quite often. 

… and worry about.

… and occasionally blog about

… and try to avoid altogether really.

I mean, seriously – corporations aren’t culpable for willingly exposing data on a public network but the individual is at fault for looking at it???!!1  For the love of Pete… 

kick it on DotNetKicks.com
E-mail • Permalink • Comments (0)