Home > Blogs > VMware PowerCLI Blog > Monthly Archives: September 2007

Monthly Archives: September 2007

PowerShell Namespaces (RE: The trouble with the tribbles)

Poshoholic raises the question of PowerShell namespaces.

I’ve been thinking about this, too. I think it’s important for usability to keep the naming uncluttered, which is why you’ll find Get-VM as opposed to Get-VMWVM or some such in the VMworld presentation I posted last week.

That said, the potential for naming collisions isn’t something to simply dismiss and also plays into usability. I’ve been thinking along the same namespace lines as Kirk. It turns out that we already have some amount of namespace support in PowerShell as long as we’re talking about snapins. Based on that, here’s a strawman of something that might work today:

function Set-NameSpace {
  param($ns = $null)

  $oldNamespace = @{}
  foreach ($key in $ns.Keys) {
    $oldMapping = Get-Command $key -CommandType Cmdlet -ErrorAction SilentlyContinue
    if ($oldMapping -ne $null) {
      $oldNamespace[$key] = $oldMapping.PSSnapin.Name + "\" + $oldMapping.Name
    } else {
      $oldNamespace[$key] = $null
    }

    $newMapping = $ns[$key]
    if ($newMapping -eq $null) {
      del alias:$key
    } else {
      Set-Alias $key $ns[$key] -Scope 1
    }
  }

  $oldNamespace
}

Now imagine that each snapin defines a namespace mapping variable. To make it concrete, let’s imagine a snapin named foo that wants to use the names get-host and get-process itself. So that snapin defines its namespace mapping like this:

 

$fooNamespace = @{"get-host" = "foo\get-vmhost"; "get-process" = "foo\get-process"}

With this, we can achieve the affect of a "using namespace" construct like this:

PS C:\ws\powershell> $old = set-namespace $fooNamespace
PS C:\ws\powershell> $old

Name                           Value
----                           -----
get-process                    Microsoft.PowerShell.Management\Get-Process
get-host                       Microsoft.PowerShell.Utility\Get-Host


PS C:\ws\powershell> get-process
Cannot resolve alias 'get-process' because it refers to term 'foo\get-process',
which is not recognized as a cmdlet, function, operable program, or script fil
e. Verify the term and try again.
At line:1 char:11
+ get-process <<<<
PS C:\ws\powershell> get-host
Cannot resolve alias 'get-host' because it refers to term 'foo\get-vmhost', whi
ch is not recognized as a cmdlet, function, operable program, or script file. V
erify the term and try again.
At line:1 char:8
+ get-host <<<<

So we see based on the errors that our invocations were in the correct "namespace" as we’re trying to invoke these cmdlets from the foo snapin. And now to stop using that namespace:

PS C:\ws\powershell> set-namespace $old | Out-Null
PS C:\ws\powershell> get-host


Name             : ConsoleHost
Version          : 1.0.0.0
InstanceId       : d2f07d5a-8be5-45e8-9bf4-8e32b531f410
UI               : System.Management.Automation.Internal.Host.InternalHostUserI
                   nterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy

This could be made much more like a "using namespace" construct as in Kirk’s post by passing the commands to be executed as a script block and resetting the namespace after execution.

Aside from that, this is obviously incomplete, not taking into account aliases instead of or in addition to cmdlets, etc. And it doesn’t work at all for functions which don’t have a snapin to distinguish them (any thoughts on alternatives?). But maybe it’s a reasonable strawman for dealing with the problem using existing mechanisms. What do you think? Better suggestions?

Antonio Dias

Update:
I used Get-Process and Get-Host as examples because we’re all familiar with them. This obviously isn’t an encouragement to stomp on existing names, just a thought exercise around alternatives to prefixing the nouns.

New-HtmlHelp

We noticed the Documentation One Liner topic over on the Windows PowerShell group’s blog. We don’t have a one-liner but we do have a little script that Angel, one of the team members, wrote to tackle the same problem. We chose to map the help into HTML in a javadoc-ish format. Below, you can see a little sample of applying it to one of the core cmdlets. Click on the image to see full size.

Here are the script and stylesheet: Download doc-style.css Download New-HtmlHelp.ps1

Usage: New-HtmlHelp [commands for which to generate help] [target directory] [title]

Example: New-HtmlHelp (get-command -pssnapin microsoft.powershell.management) ./cmdletHelp "Management Cmdlets"

Then open ./cmdletHelp/index.html in a browser. To complete it, create a web page that describes the package in the ./cmdletHelp/right-frame.html file.

This script is a quick-and-dirty hack and makes some assumptions that are valid for our environment. In other words: It works for us. YMMV. Note: the script as attached isn’t signed. Please read it over and validate it for yourself. If you add any improvements, we’d certainly appreciate a link to them. 🙂

Helpsnippet_5

“Hello World” | out-host

PowerShell provides a great automation platform for Windows. At VMware, we’ve been exploring PowerShell interfaces for VMware Infrastructure and VMworld gave us a good opportunity to provide a sneak peek at some of the forms those interfaces could take. You can view the slides from that session here: Download VMworld2007_IO30.pdf

In case you don’t feel like browsing through the slides, here’s a quick sample:

Get-VM qa* | Get-NetworkAdapter | where { $_.NetworkName -eq "red" } | Set-NetworkAdapter -NetworkName "blue"

This little example shows off some of the leverage and simplicity a PowerShell interface could provide. Hopefully, it’s self-explanatory but I’ll translate it anyway: For all virtual machines with names that start with "qa," change any network adapters they may have that are attached to the "red" network to instead be attached to the "blue" network. This is pretty typical PowerShell syntax, composing a few simple commands with a little bit of PowerShell language scripting to accomplish a task. And it’s indicative of the kind of simplicity we’re trying to achieve.

On the PowerShell development team, we’re very excited about this work and we’re interested in feedback from any of you who may have comments and in particular from anyone who attended the VMworld session on this topic (IO30).

To keep up with ongoing work, please subscribe to one of our blog feeds: