PowerShell V2 & Cmdlet Keyword

Link. October 18, 2008. Comments [3]. Posted in: PowerShell

In the latest entry in the official PowerShell Blog, Jeffrey Snover leaves a little tidbit about a change coming on the next CTP of PowerShell V2:

The cmdlet keyword is going away and we'll just have function. Notice that now you can specify the [Parameter()] attribute on parameters.  When you do that, we treat the function like a cmdlet.

I don’t mind getting rid of the cmdlet keyword; honestly, but is the new syntax that much of an improvement? So now instead of an explicit keyword telling you whether something is a function of a cmdlet, you have an attribute spilled around the function parameters? Not sure if that’s good or not, but sounds confusing to me, at first glance.

Maybe what rubs me the wrong way, however, is the [Parameter] attribute. I’m OK with using an attribute to specify the metadata associated with the parameters, honestly. But the whole Param + [Parameter] thing just reads redundant and ugly:

function Emit-XML {
Param ([Parameter(Mandatory=$true,ValueFromPipeline=$true)]$object)
...
}

Can anyone more familiar with this chime in? Am I the only one slightly bothered by this?

Explorer in Explorer Mode

Link. October 11, 2008. Comments [5]. Posted in: PowerShell

I tend to fire up Windows Explorer instances from my prompt very often, either on the current directory or in other spots. I was pretty used to using the “explorer /e,<path>” command from CMD.EXE but I never had figured out exactly how to use it on PowerShell and have it work reliably: Paths with spaces always caused it to open the default documents folder instead.

Finally sat down and played with it until I got it right:

# open explorer in this directory
function exp([string] $loc = '.') {
   explorer "/e,"$loc""
}

get-myprocess

Link. October 5, 2008. Comments [1]. Posted in: PowerShell

Silly little helper PowerShell function that I’ve been finding useful lately when doing some debugging:

# get our own process information
function get-myprocess {
   [diagnostics.process]::GetCurrentProcess()
}

My PowerShell Prompt

Link. August 14, 2008. Comments [5]. Posted in: PowerShell

Neil Houghton asked a couple of days ago if I could share my PowerShell prompt() function. Here's what my prompt looks like:

ps-prompt

I tried to keep my prompt relatively short while still on a single line. There are two things I care about in my prompt: The machine name I'm working on (useful when I have VMs opened) and the current path, in abbreviated form.

Thus, my prompt() function looks like this:

function prompt {
   # our theme
   $cdelim = [ConsoleColor]::DarkCyan
   $chost = [ConsoleColor]::Green
   $cloc = [ConsoleColor]::Cyan

   write-host "$([char]0x0A7) " -n -f $cloc
   write-host ([net.dns]::GetHostName()) -n -f $chost
   write-host ' {' -n -f $cdelim
   write-host (shorten-path (pwd).Path) -n -f $cloc
   write-host '}' -n -f $cdelim
   return ' '
}

The abbreviation of the current directory is partially inspired by Unix (use ~ if it's under the $HOME) and partially by how GVim shortens paths for its tab captions:

vim-tabs

Here's the function that takes care of this:

function shorten-path([string] $path) {
   $loc = $path.Replace($HOME, '~')
   # remove prefix for UNC paths
   $loc = $loc -replace '^[^:]+::', ''
   # make path shorter like tabs in Vim,
   # handle paths starting with \\ and . correctly
   return ($loc -replace '\\(\.?)([^\\])[^\\]*(?=\\)','\$1$2')
}

One thing to keep in mind regarding shorten-path: I do a very simple replace of $HOME by ~. The reason it works correctly is that I ensure in my profile script that the $HOME variable has a fully qualified path and "completed" using the resolve-path command. I also modify what the home directory is under PowerShell by using a trick I've described previously.

Things I Love About PowerShell

Link. August 11, 2008. Comments [3]. Posted in: PowerShell

I thought it would be fun to bring up a list of some small things I love about using PowerShell as my default command line / scripting tool on the Windows platform. Without further introduction, here they are:

Switching to Network Shares

One of the most annoying limitations of the old cmd.exe was that it provided almost no support for network shares that were not mapped as drives.

The PowerShell provided model, fortunately, didn't make this mistake, so you can use set-location to switch to a network share and execute commands there just like in any other local folder:

ps_network

Location Stacks

Like other shells, PowerShell supports pushing folders into a stack and then popping them back out, making it a lot easier to navigate around a few folders without having to remember the complete paths each time. You manipulate the location stack using the push-location and pop-location commands, which are aliased to pushd and popd respectively.

I find this very useful when running doing builds or when working with Vim and some scripting language.

The PowerShell implementation, however, has a couple of advantages:

  1. It works on the provider model, so you can push/pop more than just file system locations. For example, you could use the location stack to move around the registry.
  2. It supports multiple stacks: You can keep multiple, named location stacks at the same time by simply using the -stackName parameter: 

    ps_stacks

The contents of the location stacks are stored as part of your PowerShell Session State, and you can see the contents of each stack by using the get-location command:

ps_liststacks

Notice that the default stack will always have an empty string ('') as its name.

It's .NET-based

The fact that PowerShell is based on the .NET Framework can be confusing to some people due to some of the underlying complexity of the framework leaking to the shell (like value types).

However, for a developer like me, this is a great thing. It means that a lot of the things I used to create small C# apps for, like quickly trying out a framework class/method, I can now try interactively on the shell. It also means that there is a lot of functionality already built, right at my fingertips that can be used very quickly.

Here's an example: I was recently working on a new Virtual Machine I had just setup and needed to generate a new GUID. I'm very used to going to the command line and running the old uuid.exe utility to do this, but, unfortunately, I had not installed the Windows SDK on the VM yet and was not planning to. With PowerShell, though, this was not a problem:

# uuidgen.exe replacement
function uuidgen {
   [guid]::NewGuid().ToString('d')
}

Shell Introspection

Another aspect that I really enjoy about PowerShell is the built-in introspection features. It's a lot easier to learn the shell when all the information about what's available and the objects you're manipulating is easily accessible.

Here are some of the introspection features I like:

  • The get-command command. Great way to see what commands are available. Coupled with get-help, it's a really nice way to figure something out.
  • The built-in providers. One really nice feature of PowerShell is that functions, aliases and variables are all exposed as providers, meaning you can list them / examine them to your hearts content using the standard location commands like get-childitem. Just try running "ls function:" or "ls variable:" next time.
  • The $MyInvocation, $ExecutionState and $Host variables give you access to plenty of information about the execution environment, as well as lots of options for manipulating it.

No need for Calc.exe

I used to constantly start calc.exe to do a quick calculation. Since PowerShell is a full scripting language, however, I now do most of those quick calcs by directly entering expressions into the PowerShell prompt.

It's a heck of a lot easier and very convenient for me since I always keep around a PowerShell prompt opened and ready to go.

Syndicate

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Ads


Categories

Statistics

Total Posts: 1041
This Year: 111
This Month: 0
This Week: 0
Comments: 819

Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.2.8279.16125

Sign In