Public/xcrypt/Rename-Hashtable.ps1
function Rename-Hashtable { [cmdletbinding(SupportsShouldProcess, DefaultParameterSetName = "Pipeline")] [alias("rht")] Param( [parameter( Position = 0, Mandatory, HelpMessage = "Enter the name of your hash table variable without the `$", ParameterSetName = "Name" )] [ValidateNotNullorEmpty()] [string]$Name, [parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = "Pipeline" )] [ValidateNotNullorEmpty()] [object]$InputObject, [parameter( Position = 1, Mandatory, HelpMessage = "Enter the existing key name you want to rename")] [ValidateNotNullorEmpty()] [string]$Key, [parameter(position = 2, Mandatory, HelpMessage = "Enter the NEW key name" )] [ValidateNotNullorEmpty()] [string]$NewKey, [switch]$Passthru, [ValidateSet("Global", "Local", "Script", "Private", 0, 1, 2, 3)] [ValidateNotNullOrEmpty()] [string]$Scope = "Global" ) Begin { Write-Verbose -Message "Starting $($MyInvocation.Mycommand)" Write-Verbose "using parameter set $($PSCmdlet.ParameterSetName)" } Process { Write-Verbose "PSBoundparameters" Write-Verbose $($PSBoundParameters | Out-String) #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" #bail out Return } Try { #validate variable is a hash table if ($InputObject) { #create a completely random name to avoid any possible naming collisions $name = [system.io.path]::GetRandomFileName() Write-Verbose "Creating temporary hashtable ($name) from pipeline input" Set-Variable -Name $name -Scope $scope -Value $InputObject -WhatIf:$False $passthru = $True } else { Write-Verbose "Using hashtable variable $name" } Write-Verbose (Get-Variable -Name $name -Scope $scope | Out-String) Write-Verbose "Validating $name as a hashtable in $Scope scope." #get the variable $var = Get-Variable -Name $name -Scope $Scope -ErrorAction Stop Write-Verbose "Detected a $($var.value.GetType().fullname)" Write-Verbose "Testing for key $key" if (!$var.value.Contains($key)) { Write-Warning "Failed to find the key $key in the hashtable." #bail out Return } if ( $var.Value -is [hashtable]) { #create a temporary copy Write-Verbose "Cloning a temporary hashtable" <# Use the clone method to create a separate copy. If you just assign the value to $temphash, the two hash tables are linked in memory so changes to $tempHash are also applied to the original object. #> $tempHash = $var.Value.Clone() if ($pscmdlet.ShouldProcess($NewKey, "Replace key $key")) { Write-Verbose "Writing the new hashtable to variable named $hashname" #create a key with the new name using the value from the old key Write-Verbose "Adding new key $newKey to the temporary hashtable" $tempHash.Add($NewKey, $tempHash.$Key) #remove the old key Write-Verbose "Removing $key" $tempHash.Remove($Key) #write the new value to the variable Write-Verbose "Writing the new hashtable to variable named $Name" Write-Verbose ($tempHash | Out-String) Set-Variable -Name $Name -Value $tempHash -Scope $Scope -Force -PassThru:$Passthru | Select-Object -ExpandProperty Value } } elseif ($var.value -is [System.Collections.Specialized.OrderedDictionary]) { Write-Verbose "Processing as an ordered dictionary" $varHash = $var.value #find the index number of the existing key $i = -1 Do { $i++ } Until (($varHash.GetEnumerator().name)[$i] -eq $Key) #save the current value $val = $varhash.item($i) if ($pscmdlet.ShouldProcess($NewKey, "Replace key $key at $i")) { #remove at the index number $varhash.RemoveAt($i) #insert the new value at the index number $varhash.Insert($i, $NewKey, $val) Write-Verbose "Writing the new hashtable to variable named $name" Write-Verbose ($varHash | Out-String) Set-Variable -Name $name -Value $varhash -Scope $Scope -Force -PassThru:$Passthru | Select-Object -ExpandProperty Value } } else { Write-Warning "The variable $name does not appear to be a hash table or ordered dictionaryBet" } } Catch { Write-Warning "Failed to find a variable with a name of $Name. $($_.exception.message)." } Write-Verbose "Rename complete." } End { #clean up any temporary variables if ($InputObject) { Write-Verbose "Removing temporary variable $name" Remove-Variable -Name $Name -Scope $scope -WhatIf:$False } Write-Verbose -Message "Ending $($MyInvocation.Mycommand)" } } |