Assigning the Output of a SWITCH Statement

Assigning the Output of a SWITCH Statement

  • Comments 5

I was just reading the whitepaper Automating Citrix XenApp on XenServer deployments on HP ProLiant servers.  The reason why this works well for them is that the HP Insight Rapid Deployment (RDP) software has the ability to launch scripts at various points.  Citrix has a wide range of cmdlets so they are able to put together a pretty nice bundle and offer it in a way that allows you to change it if you don't like it.  In fact my favorite part of the paper was this:

Create your own cmdlets for a XenServer environment
If the cmdlets developed by Citrix do not meet the needs of your environment, you can create your own. Cmdlets can be written in any programming language4 and then compiled as a PSSnap-in. The key objective when creating your own cmdlets should be to codify simple, modular tasks that are likely to be performed in multiple jobs associated with the management of VMs or their XenServer hosts. You can then create a PowerShell script to call the cmdlets.

The original PowerShell cmdlet set developed by Citrix for this automated deployment solution5 has since been superseded by a larger set6 released by the XenServer development team. Since it is likely to have a larger following within the Citrix community, Citrix recommends using the most recent XenServer cmdlet set when you create an automated deployment solution for your environment. Figure 1 outlines support for these cmdlet sets in the automated deployment solution.

In other words:  We released a set of scripts, check our community site for the most recent versions and if you don't like what we gave you, you can create your own.  They have got it EXACTLY RIGHT!   The more vendors we get thinking that way, the better all of our lives will be.  Tip of the hat to you Citrix.

While reading the doc, I came across the picture below and thought I would use it to teach a technique.  Take a look at the switch statement, each case does the same thing - assigns a value to $global:template.  Or at least it looks that way.  You could imagine that as this list gets longer and longer, it would become increasing difficult to detect whether you had spelling error (e.g. $global:tempate = ...).  I transpose letters all the type so I would certainly screw this up at some point.

image

Did you realize that you can assign the output of a switch statement?  Yup!  I would write this as follows:

$global:template = switch ($global:template)            
{            
    "VistaSp1x86-Base" {"/Xen4.1/Vista/VisatSp1x86.xva"}            
    "VistaSPx64-Base"  {"/Xen4.1/Vista/VisatSp1x64.xva"}            
    "LHx86"            {"/Xen4.1/LHX86.xva"}            
    "LHx64"            {"/Xen4.1/LHX64.xva"}            
}            
<NOTE - This works in PS V2.  In V1, you have to wrap the switch statement in $() to make it work.  Thanks Oisin!>

Actually since all the matches are literal strings, I would have done it as a hashtable like this:           
$map = @{           
    'VistaSp1x86-Base' = "/Xen4.1/Vista/VisatSp1x86.xva"           
    'VistaSPx64-Base'  = "/Xen4.1/Vista/VisatSp1x64.xva"           
    'LHx86'            = "/Xen4.1/LHX86.xva"           
    'LHx64'            = "/Xen4.1/LHX64.xva"           
}           
$global:template = $map.$($global:template)

But chances are that you already know that technique but maybe not the one about the output of a switch statement being assignable.

Enjoy!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 2 and 5 and type the answer here:
  • Post
  • I, for one, didn't know the trick with the hashtable and the map function. Nice! Definitely simplifies the switch statement (actually eliminates it)!

    What happens, though, if there isn't a match?

  • Excellent question Philip!

    I thought about addressing this in the blog but then thought it would screw up the signal-to-noise ratio so I punted on it.  The problem is that the original code didn't have a "default" case on the switch so I don't know what they wanted to have happen.  In the case of the hash table, you use the ContainsKey() method on the hash table:

    if (!($map.ContainsKey($global:template))) {...}

    Thanks for asking!

    jps

  • Hey Jeffrey - you might want to mention that your example only works with later v2 powershell versions (post ctp3) that allow statements on the RHS. For v1.0, you need:

    $foo = $( switch(...) { ... } )

    e.g. a subexpression wrapping the switch.

    -Oisin

  • Hi Jeffrey, I have a question.

    When I set powershell.exe as a default program for .ps1 file types in Windows 7,

    are there ways that do it easy and correctly?

    (like 'powershell.exe -File "%1"', not 'powershell.exe "%1"')

  • I forgot to say...

    I don't want to execute ps1 script with double-click,

    but I do want to execute ps1 script with only its name in a batch file or cmd.exe

    So I hoped easy way to do it as a standard feature of win7 or posh v2.

Page 1 of 1 (5 items)