A little more on PowerShell

I've been showing PowerShell on the roadshow, and Steve warning me about it becoming the "Look-how-clever-I-am-with-PowerShell show". Actually, I quite like the idea of a "Look-how-clever-PowerShell-makes-you show". Working on some of bits and pieces of PowerShell for managing hyper I've found a couple of new corners which I thought I'd share.

I wanted to show the tree of snapshots taken of a Hyper-v Virtual Machine ... and let the user choose one of them.  I ended up with a semi-generic "Choose-Tree" function, and that sent me back to the choose functions I've written about before. I wanted to have something totally generic like this

    choose-list (Get-WmiObject win32_diskdrive) @("DeviceID", "Model")

   ID DeviceID           Model  
   -- --------           -----

    0 \\.\PHYSICALDRIVE0 Hitachi HTS721010G9SA00 ATA Device

    1 \\.\PHYSICALDRIVE1 Generic USB Card Reader USB Device

    2 \\.\PHYSICALDRIVE2 Multi Flash Reader USB Device 
    Which one ?: 

The idea is simple enough, pass the function an array of data and other array of the field names I want displayed, put a counter alongside them and let the user enter the index into the array for the item they want.

This led me to using variables and parameters in places I haven't done before One was using a variable to hold a field name. Like this

    $foo="TotalPhysicalMemory"
   (Get-WmiObject win32_computersystem).$foo

Very useful if I need to pass a parameter to a function to tell it which property to use from the objects it was passed. Building a tree for example, which field is displayed, which gives a node's parent, and so on. Then I started looking at using an array of strings to hold the field names, like this

    $foo=@("TotalPhysicalMemory","Model")
   Get-WmiObject win32_computersystem | format-table -property $foo

That works very nicely too. Because Powershell lets us mix types of item in an array we can put in hash tables which store custom fields. So a design formed... Pass data and Fields as parameters, add the counter custom-field that I was already using in my choose functions to the Fields array (put it an array and join it with the array of fields passed to the function), and use that in a format-table command. Since some of Choose functions had multiple selections and some single I had a "Multiple" parameter and that changes the prompt / selection at the end. So my generic choose-from a-list function ends up as half a dozen lines.

    function choose-List
   {Param ($Data , $fieldList , [Switch]$Multiple)
    $global:Counter=-1
    $fieldlist=@(@{Label="ID"; expression={ ($global:Counter++) }}) + $fieldList
    $data | format-table -autosize -property $fieldList | out-host
    if ($Multiple) { $Data[ [int[]](Read-Host "Which one(s) ?").Split(",")] }
    else           { $Data[        (Read-Host "Which one ?")           ] }
   }

Each "choose" function - choose VM, Choose network etc then becomes one line.

Technorati Tags: Microsoft,Powershell