It’s a great time to be a Poshoholic!

What a fun time to be working with PowerShell!

Just this weekend I got my hands on the beta of PowerShell Plus and I started looking at the new PowerShell Community site that soft-launches tomorrow.  Last Monday PowerGUI 1.0.11 was released with the fantastic PowerGUI Script Editor.  On Friday version 1.0.5 of the Quest AD Cmdlets was released.  The Virtual PowerShell User Group hosted their inaugural meeting earlier this month (if you missed this you can get the recorded video here).  Local user groups are starting to talk about PowerShell and spread the good word.  PowerShell Analyzer 1.0 is about a week away.  Next month Jeffrey Snover will be presenting new features in PowerShell 2.0 at TechEd IT Forum 2007 in Barcelona (I hope there will be a webcast for that session!).  VMWare is providing a technology preview of their ESX server snapin to testers soon.  The library of PowerShell books that are available keeps growing.  More and more Microsoft and third-party products are releasing with their own PowerShell snapins.  Add to that PowerGadgets, PowerShell Community Extensions, the PowerScripting Podcast, several active community sites, a busy newsgroup, lots of webcasts, many other PowerShell projects on CodePlex and likely a bunch of things I’m not able to think of right now and you can’t help but feel that it really is a great time to be a Poshoholic!  Are you on the train yet?

Kirk out.

Technorati Tags: , , , ,

PowerGUI 1.0.11 with the PowerGUI Script Editor is now available

Following up the teaser post that I published this past weekend, I’m happy to tell you that PowerGUI 1.0.11 was officially released yesterday.  This is a truly great product, it’s free, and it is a must have for any serious user of PowerShell.  If you’re still not convinced that you should be using this product, take a look at Dmitry Sotnikov’s post about “Notepad for PowerShell”.  It includes a screenshot of the fantastic PowerGUI Script Editor application that was included as part of this release plus other details.

Enjoy!

Kirk out.

Technorati Tags: , , , ,

PowerShell CTP coming before end of year with WinRM support

As Hal Rottenberg pointed out earlier, some interesting news has surfaced about the next version of PowerShell (2.0?).  According to an article about WinRM, there is a CTP of PowerShell coming before the end of the year and this CTP will support running cmdlets against remote computers using WinRM as the remote transport protocol.  My bet is that this will be released at the TechEd IT Forum 2007 conference in November.  Here’s the snippet from the article:

Something else to consider. Sometime before the end of the year an upgraded CTP (Community Technology Preview) version of Windows PowerShell will be released, an upgrade that will enable you to run most Windows PowerShell cmdlets against remote computers. The catch? This new version of Windows PowerShell also relies on WinRM as its remote transport protocol. If you’re interested in using Windows PowerShell to manage remote computers you’ll need to download and install WinRM on your Windows XP and Windows Server 2003 machines.

If you haven’t gotten up to speed on WinRM already, now’s the time to start!

Kirk out.

Technorati Tags: , , ,

PowerGUI 1.0.11 release is just around the corner!

According to Dmitry Sotnikov‘s most recent blog post, the next release of PowerGUI (version 1.0.11) is slated for next week.  It may even be available by the time you read this post!  I have had the great pleasure of beta testing PowerGUI 1.0.11 for the past week or so, and this is another fantastic release of this truly great product.

As with previous upgrades to PowerGUI it only takes a few minutes with the new version to see that the PowerGUI team has been very busy enhancing this product.  I hadn’t even finished the installation of the new version when I became totally distracted after noticing one of the enhancements in this version, the PowerGUI Script Editor.  This feature is great news for the PowerShell Community!  Finally a PowerShell script editor with great features that facilitate writing scripts even when you don’t know the syntax by heart, and a free one to boot!  Working with PowerShell just got much, much easier.

Add to that the performance improvements to the startup time for PowerGUI and all of the bug fixes, and you’ve got yourself another great release from the PowerGUI product team!  For a full list of enhancements and bug fixes, check the PowerGUI Feature Map page.

For those of you who haven’t tried PowerGUI yet, this would be a great release to start with!  It’s free and it adds a ton of value to working with PowerShell so there’s really no reason not to try it if you’re even remotely interested in PowerShell and wondering what all the fuss is about.  Plus there is a very active PowerGUI community where you can post questions, notify the developers about possible defects, watch webcasts to see how it works, and raise enhancement requests.  The PowerGUI team actively monitors and participates in the community, so if you need help with anything or want to start a discussion about using PowerShell with PowerGUI, about PowerGUI itself or about the Quest AD cmdlets, this is the right place to go!  I’m a regular on the community forums and will likely try to respond to your questions if someone from the PowerGUI or Quest AD cmdlets teams doesn’t get back to you first.

Kudos to the PowerGUI team for the fantastic products they’re producing!  I can’t wait to see what they’ll do next!

Kirk out.

Technorati Tags: , , , , , ,

PowerShell Challenge: Processing arguments in a function or script

Recently I was experimenting with passing arguments into a function or a script.  I wanted to see how variable length argument functions or scripts could be created.  Here’s what I had set up in my test script:

param([string[]]$args)
$args

I then saved this script as test.ps1 and called it in PowerShell like this:

.\test.ps1 “1” “2” “3” 

Naturally I expected to see the string values “1”, “2”, and “3” output to the console, each on their own line.

Instead, here is the output I received:

2
3

That’s odd.  Some arguments were output, but not all of them.  What happened to the first argument that I passed in?

In this example, when I execute the test.ps1 script, the PowerShell interpreter looks at the arguments I am passing in and attempts to assign them to the arguments that this script accepts as declared in the param statement.  I only have one argument in my param statement, so PowerShell takes the first argument that was passed in and converts it into the type of the argument declared in the param statement.  That means my “1” string gets converted into an array of strings.  Then PowerShell looks at any remaining arguments and it stores them in an array in the $args variable.  This is a system variable that is used to store all remaining arguments that aren’t matched up to arguments declared in the param statement.

Looking at my example, you can see that I am using the $args variable in my param statement.  This means that when the script is run the first value is converted into an array of strings that is stored in the args variable.  Then the args variable is cleared and the remaining arguments are added to the $args variable array.  Once they are all added, the script is run and the last two arguments are output to the console.  As a result, the first argument gets discarded.

It is interesting to note that when you do this, the $args variable retains its array of strings type within the script.  By default, $args is an array of objects.  If you comment out the param statement in the script, the script will output all objects to the console, and the $args variable will store those objects in an array of type object as expected.

Lesson learned?  Don’t use the $args variable as an argument to a function or a script.

Kirk out.

Technorati Tags: , , ,

The PowerShell Matrix

You know that scene in “The Matrix” where they download programs into Neo’s mind so that he can learn more quickly?  I need to get myself one of those for PowerShell.

The more I learn about PowerShell the more I realize there is to learn and the more I want to know.  I am such a Poshoholic!

Kirk out.

Technorati Tags: , ,

Get-PSSnapin one-liners

With the number of PowerShell snap-ins that are available continuing to grow steadily, I’ve noticed more and more that people are looking for ways to determine if a snap-in was properly registered, whether snap-in changes are properly showing up in the PowerShell console, and answers to other general snap-in troubleshooting questions (note, a PowerShell snap-in is also referred to as a PSSnapin within the PowerShell console).  Fortunately, as is the nature with many things in PowerShell, there are a number of one-liners that we can use to gather information about snap-ins or to diagnose and troubleshoot snap-in problems.  I’ll list each one with the question that it was designed to answer below.

What snap-ins come with PowerShell?

Get-PSSnapin `
    | Where-Object { $_.IsDefault -eq $true }

What third-party snap-ins do I have on this system?

Get-PSSnapin -Registered

Which of the third-party snap-ins are already added to my current PowerShell session?

Get-PSSnapin `
    | Where-Object { $_.IsDefault -eq $false }

Which of the third-party snap-ins are not added to my current PowerShell session?

Get-PSSnapin -Registered `
    | Where-Object { (Get-PSSnapin $_.Name -ErrorAction SilentlyContinue) -eq $null }

How can I see all snap-ins and identify which ones come with PowerShell, which ones are third-party, which ones are added to my current PowerShell session and which ones are not (i.e. how do I put all of this information together)?

(Get-PSSnapin | Where-Object {$_.IsDefault -eq $true}) + (Get-PSSnapin -Registered) `
    | Add-Member -Force -Name IsAdded -MemberType ScriptProperty -Value {(Get-PSSnapin $this.Name -ErrorAction SilentlyContinue) -ne $null} {} -PassThru `
    | Format-List -Property Name,IsDefault,IsAdded,PSVersion,Description

I’m having general issues when using a third-party snap-in (cmdlets I’m trying to use aren’t found, changes made in a new version aren’t showing up in PowerShell, etc).  The snapin is called ProblematicSnapin.  How can I find out detailed information about the snap-in itself so that I can verify the information about the snap-in in PowerShell and troubleshoot the issues?  Note that for this one-liner you must replace “ProblematicSnapin” with the name of the third-party snap-in you are using.

Get-PSSnapin -Registered -Name ProblematicSnapin `
    | Add-Member -Force -Name IsAdded -MemberType ScriptProperty -Value {(Get-PSSnapin $this.Name -ErrorAction SilentlyContinue) -ne $null} {} -PassThru `
    | Format-List -Property *

What cmdlets are provided by a snap-in?  Note that for this one-liner you must replace “SnapinName” with the name of the snap-in you are inquiring about.  Also note that this only works for default snap-ins and snap-ins that have been added to the current PowerShell session.

Get-PSSnapin -Name SnapinName `
    | ForEach-Object { Get-Command -PSSnapin $_ } 

Hopefully these one-liners will help you get answers to your PSSnapin related questions.

Enjoy!

Kirk out.

Technorati Tags: , , , , ,

Invoking a PowerShell script from cmd.exe (or Start | Run)

Earlier today Ying Li over at myITforum.com posted an article about some of the difficulty involved in launching a Windows PowerShell script from cmd.exe (or Start | Run) when there is a space in the path to the ps1 file containing the script.  In this article, Ying was pointing out how running a script with a command similar to the following will result in an error:

powershell -noexit & “C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1”

The reason this generates an error is simply because of how the command line arguments are broken into tokens outside of Powershell and then rebuilt as arguments inside of PowerShell.  In the example above, PowerShell is being executed with 3 arguments: -noexit, &, and the path to the PowerShell script.  Even though the PowerShell script has quotation marks around it when it is entered in cmd.exe or in the Start | Run dialog, those quotation marks are only used to hold the string together as one argument outside of PowerShell.  They are not passed in with the string.  When PowerShell actually gets to see the arguments inside, it sees this:

  1. -noexit
  2. &
  3. C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1

The -noexit argument is a named switch property that is supported by PowerShell, so PowerShell knows to keep the console open when the script is done.  The remaining arguments aren’t associated with a named property, so PowerShell treats them as the command by concatenating them together with a space between the tokens.  This makes the PowerShell command look like this:

& C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1

If you try to run this command in PowerShell, you will get an error because the parser doesn’t know what to do with the C:\Documents token.  Fortunately, the fix to this is simple.  As Ying pointed out, you can use single quotes instead of double quotes.  This means you could enter the command like this:

powershell -noexit & ‘C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1’

In this case, the single quotes are not used to identify one argument to PowerShell.exe, so the argument list looks like this:

  1. -noexit
  2. &
  3. ‘C:\Documents
  4. and
  5. Settings\poshoholic\My
  6. Documents\PowerShellRocks.ps1′

Since the single quotes weren’t removed when the command was broken into tokens, the string remains intact when it is rebuilt as the command to execute within PowerShell.

But what if you really needed to use double quotes?  Well, double quotes work too, but you have to treat them as a special case because they are used to identify an argument that contains spaces.  More specifically, you have to escape them within a surrounding pair of quotes by entering two double quotes side by side.  In the case of our example, that means entering the command like this: 

powershell -noexit “& “”C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1″””

Running this command results in two arguments being passed into PowerShell:

  1. -noexit
  2. & “C:\Documents and Settings\poshoholic\My Documents\PowerShellRocks.ps1”

Bingo, that’s the script that we originally intended to run!

While it might not be that common that someone wants to pass quotation marks into PowerShell via cmd.exe or Start | Run, I thought it would be useful to clarify this for whenever the need arises.  In general, I recommend always putting external quotation marks around the entire command that you want to pass into PowerShell this way and using paired double-quotes or non-paired single quotes within that quoted command as required.  This prevents unnecessary tokenizing and then rebuilding of the command which, as Ying’s article illustrated, doesn’t always rebuild as you would expect it to.

For related information, specifically pertaining to the order you need to use in your PowerShell.exe arguments, read this post.

Kirk out.

Technorati Tags: , ,

PowerShelling with PowerTab

I’ve recently started experimenting with PowerTab version 0.98 on one of my systems where I use PowerShell.  I hadn’t done this before for quite a few reasons:

  1. I wanted to work with PowerShell 1.0 without modifications for at least the first little while to see how well it works by itself (suffice it to say that this is the best 1.0 release of a product I have used in a long time).
  2. Beyond the initial experience with PowerShell 1.0, the built-in tab expansion was meeting my immediate needs when writing one-liners.
  3. Whenever I would write anything more complex that a one-liner I would do so in an editor that had built-in syntax highlighting and/or intellisense (I say and/or because I’ve been trying out quite a few different script editors), and PowerTab wasn’t available within those editors.

But after listening to Scott Hanselman talk about PowerShell (and PowerTab) on a recent episode of .NET Rocks TV, I figured it was time I install this component that I’ve had sitting in my downloads folder since version 0.91 or so and kick the tires a bit.

While I haven’t used PowerTab for very long yet, so far I can say that PowerTab provides some really nice enhancements over the built-in tab expansion functionality, and if you’re working within the console that ships with PowerShell 1.0 it definitely helps, especially when working with WMI objects and .NET objects directly.  The visual browsing functionality it provides will be of greatest benefit to newcomers who don’t know their way around PowerShell, WMI and .NET yet.

That said, there are a few issues I have encountered in the current release, as well as some opportunities for enhancement requests that are worth mentioning.  First, the issues:

  1. If you are viewing the tab expansion window for the current word and you press backspace or Esc, you can’t use tab expansion for that word from that point on.  For example, if you type in get-c, press tab, and then once you see your options you press backspace or Esc, tab completion will no longer work for get-c until you use tab expansion for something else.
  2. If you are viewing the tab expansion window for the current word and you press backspace or Esc, you should be returned to the exact command you started with because you are cancelling out of the option to use tab expansion on that word.  This does not work properly for files or directories.  When you press backspace or Esc the word has changed.  For example, if I am in a folder with nothing but tab.txt and tabexpansion.txt, and I type in “t” and then press the Tab key, I see the two files.  If I then press backspace or Esc, the word I entered changes from “t” to the current working directory path with “\t” appended to it (prepended by “& ‘” and appended by “‘” if there is a space in the current working directory).

Now on to the enhancement requests: 

  1. If you are viewing tab expansion options for a file or folder and you press backslash or space, that option should be selected and you should see your backslash or space in the command line.  This is necessary to prevent from additional keystrokes being required in the implementation of tab expansion (i.e. this is how it works in DOS and in PowerShell 1.0 when using the tab expansion routine that comes with PowerShell).  When you get to know what the minimum path is that you have to type, this can speed things up for you.  Having to press enter and then type the backslash is disruptive to how things worked before.  For example, using the tab expansion that comes with PowerShell, if I have two folders called “Tab” and “TabExpansion” and I know I want to navigate to the first folder I can type set-location C:\T, press the Tab key, and then press space or backslash depending on what I am doing and it will just continue.  If I do the same when using PowerTab it will beep at me when I press space, or it will do nothing when I press backslash.  I’d love to see this changed so that space and backslash will properly allow me to continue typing.  The same goes for files (although for files backslash doesn’t make sense, but space does).
  2. Similar to the last one, if you are viewing tab expansion options for a .NET class and you press the right square bracket “]”, the current option should be selected and you should see your .NET class with the “]” character at the end in the command line.  Basically I think that if you press any character that is a valid terminator for the item that is showing in the tab expansion option list that the item should be terminated and you should see it with your terminator in the current line of script you are writing.
  3. When you have a line of script on the screen and you activate tab expansion in the middle of that script, the remainder of that line of script is deleted.  This is an issue with tab expansion in the standard command prompt and the tab expansion that comes with PowerShell 1.0.  The impact of this issue is much more apparent in PowerShell when working with long one-liners (although you have command history so you can usually go back unless you just typed in a long one-liner from scratch).  I’d love to see this fixed with PowerTab, but I think this is beyond the control of what can be done in the TabExpansion function.

That’s about it for now.  I’ll continue experimenting with PowerTab and see what else I come across.  Kudos to Marc van Orsouw (MOW) for all of his hard work on PowerTab!  I look forward to seeing this functionality in PowerShell Plus!

Kirk out.

Technorati Tags: , , , , ,

The trouble with the tribbles

After looking at the new cmdlets shown in the presentation that accompanied VMWare’s recent announcement and discussing the announcement with my friend Dmitry, he mentioned how confusing things might become as more and more companies release cmdlets that don’t use product prefixes in their nouns.  I agree with this to a certain extent, but there are pros and cons either way.

Captain Kirk with tribbles  On one side, if someone develops a cmdlet that no one else has produced that will get tribbles as part of a Star Trek product, and if the type of tribbles they are retrieving are what 90% or more of the users would expect them to be, then why shouldn’t they name their cmdlet Get-Tribble?

On the flip-side though, lets say they also have cmdlets to retrieve replicators, phasers, communicators, and tricorders and they also include a generic “get all” cmdlet that retrieves everything.  As with the tribbles, if the replicators, phasers, communicators and tricorders are what 90% or more of the users would expect them to be, then they could name those cmdlets Get-Replicator, Get-Phaser, Get-Communicator and Get-Tricorder.  But what about the generic “get all” cmdlet?  Should they call it Get-Object?  That certainly wouldn’t be intuitive for an end user.  Maybe instead they should name the cmdlet Get-STObject, but then you could circle back and argue that for consistency the other cmdlets should be named similarly.  This would result in them using Get-STTribble, Get-STReplicator, Get-STPhaser, Get-STCommunicator and Get-STTricorder as well.  Those names then become clearly defined but not very pretty to look at (especially if your product name is actually Star Trek: The Next Generation and you have to distinguish your cmdlets from the Star Trek: Deep Space Nine product cmdlets, in which case you might have to name them Get-STTNGTribble, Get-STTNGPhaser, …ugh!).

What is really the right approach to take then?  Adding support for namespaces and for a using keyword in PowerShell?  If PowerShell supported namespaces, you could do this:

StarTrek::Get-Tribble | StarTrek::Activate-Transporter -Destination $klingonVessel

Alternatively, if Powershell supported a using keyword that would take a script block as a parameter, you could do this instead:

using -NameSpace StarTrek -Process {
    Get-Tribble | Activate-Transporter -Destination $klingonVessel
    Fire-Torpedo -ship $klingonVessel -targetSystem WarpDrive
    Activate-WarpDrive -warpFactor 10
}

I think this approach would give the best end-user experience for both snapin developers and script authors.  Snapin developers could continue to publish cmdlets, functions and aliases using intuitive, meaningful names without having to worry about prefixes.  Script authors could write scripts using intuitive, self-documenting cmdlet and function names.  This seems to be the best of both worlds.

Does anyone have other suggestions?  Microsoft, what do you say, can we get namespace and using keyword support in 2.0?

Kirk out.

P.S. A little known fact about me: In my early University days (pre-graphical MMORPGs – seems like eons ago now) I spent the vast majority of my free time (and often a good portion of my class time) playing a text-based MUD called Worlds of Carnage using the moniker “Nystul”.  I played it so much in fact that I finished it and went on to design areas for the MUD.  Aside from the areas I developed for people to explore on their own, I went so far as to create a virtual Enterprise ship that was completely disconnected from the rest of the MUD, complete with 10-Forward, a transporter room, a captain’s quarters and a functioning holodeck that I could tell to load programs.  It was one of the first text-based MUDs to offer a sophisticated scripting system that allowed for this sort of thing.  And no matter where I was in the game, I could just communicate with Chief O’Brien and say “Beam me up”, and he would teleport me into the transporter room.  Life used to be so simple…

P.P.S.  Hey, maybe someone should make a PowerShell-based MUD!  You could script everything you do (not that you can’t in existing MUDs, at least to some extent, but it would be cool to see it in PowerShell, at least to me)!

Go-East -count 2
Go-South -count 1
Get-Phaser | Set-Phaser -Stun
Go-South -count 1
Fire-Phaser -target $romulanGuard

🙂

Technorati Tags: , ,