Rename Hashtable Key Revised

Last week I posted an advanced PowerShell function to rename a hashtable key. As usual, the more I worked with it the more I realized it was missing something – namely the ability the take a pipelined object. My original version assumed you had saved the hashtable to a variable. But as I was working with ConvertTo-Hashtable I realized the shortcoming. The solution was to modify Rename-Hashtable so that it could accept a hashtable as a piped value.

I won’t go through the function again. You can read the original post to learn more about how it works. Let’s look at what changed. Because I wanted to retain the option to also specify a variable name, I created two parameters sets. One for the piped object and one for the variable name.

[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="Pipeline")]

Param(
[parameter(Position=0,Mandatory=$True,
HelpMessage="Enter the name of your hash table variable without the `$",
ParameterSetName="Name")]
[ValidateNotNullorEmpty()]
[string]$Name,
[parameter(Position=0,Mandatory=$True,
ValueFromPipeline=$True,ParameterSetName="Pipeline")]
[ValidateNotNullorEmpty()]
[object]$InputObject,
[parameter(position=1,Mandatory=$True,
HelpMessage="Enter the existing key name you want to rename")]
[ValidateNotNullorEmpty()]
[string]$Key,
[parameter(position=2,Mandatory=$True,
HelpMessage="Enter the NEW key name")]
[ValidateNotNullorEmpty()]
[string]$NewKey,
[switch]$Passthru,
[ValidateSet("Global","Local","Script","Private",0,1,2,3)]
[ValidateNotNullOrEmpty()]
[string]$Scope="Global"
)

I defined parameter sets called Pipeline and Name and made the former the default in the cmdletbinding attribute. Because the remaining parameters would be in both parameter sets I didn’t specify one. When looking at the function’s help you can see the result.

rename-hashtable-paramsets

Because I’m taking input from the pipeline, I needed to add a Process scriptblock. Within the scriptblock, if an object has been piped in, I turn on the passthru variable and create a temporary copy of the piped in hashtable.

Process {
    #validate Key and NewKey are not the same
    if ($key -eq $NewKey) {
     Write-Warning "The values you specified for -Key and -NewKey appear to be the same. Names are NOT case-sensitive"
     Return
    }

    Try {
        #validate variable is a hash table
        if ($InputObject) {
            $name="tmpInputHash"
            Set-Variable -Name $name -Scope $scope -value $InputObject
            $Passthru=$True
        }
...

The rest of the code worked just fine and there was no reason to change it. All I needed to do was transform the -Inputobject value into the -Name value since I already had code that used $Name. Sometimes you need separate code blocks but in this case I didn’t. Once the transformation is complete, the rest of the function runs as originally designed. With this version I can now run commands like this:

PS C:\> $h = get-service spooler -computer Serenity | convertto-hashtable -NoEmpty -Exclude CanStop,CanPauseAndcontinue | rename-hashtable -key machinename -new computername
PS C:\> $h

Name                           Value
----                           -----
computername                   Serenity
Name                           spooler
ServiceName                    spooler
RequiredServices               {RPCSS, http}
DependentServices              {Fax}
ServiceType                    Win32OwnProcess, InteractiveProcess
Status                         Running
ServicesDependedOn             {RPCSS, http}
ServiceHandle                  SafeServiceHandle
DisplayName                    Print Spooler

Download Rename-Hashtable2 and give it a go.

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to FriendFeed Post to Google Buzz Post to Ping.fm Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

About the Author

PowerShell.org Announcer

This is the official account for PowerShell.org and sponsor announcements.