Change PowerShell object property names, retaining values

Viewed 990

I have an object that looks like this.

$test = {
"displayName": "Testname"
"userAge": 22
}

I have an array that looks like this.

$friendlyNames = ["Display name", "User age"]

The way this is set up the $friendlyNames array index will always match with the object property order. Is it possible to automatically replace this and end up with a object that looks like this?

$test = {
"Display name" = "Testname"
"User age" = 22
}
1 Answers
# The sample input object.
$test = [pscustomobject] @{
  displayName = "Testname"
  userAge = 22
}

# The array of new property names.
$friendlyNames = 'Display name', 'User age'

# Use an ordered hashtable as a helper data structure
# to store the new property names and their associated values as
# name-value pairs.
$oht = [ordered] @{}; $i = 0
$test.psobject.Properties.ForEach({
  $oht[$friendlyNames[$i++]] = $_.Value
})

# Convert the ordered hashtable to an object ([pscustomobject])
$testTransformed = [pscustomobject] $oht

Outputting $testTransformed yields (tabular formatting is applied by default, because the object has 4 or fewer properties; pipe to Format-List to see each property on its own line):

Display name User age
------------ --------
Testname           22

Note:

  • PowerShell exposes .psobject on any object as a rich source of reflection, and .psobject.Properties returns a collection of objects describing an object's public properties, each of which has .Name and .Value properties.

  • Using an (ordered) hashtable is an efficient way to iteratively create an (ordered) collection of key-value pairs, which can later be converted to a custom object simply by casting to [pscustomobject].

    • In fact, the custom-object literal syntax ([pscustomobject] @{ ... }) suggests just that (as used to construct $test above), but note that this is syntactic sugar in that it results in direct (more efficient) construction of a [pscustomobject] instance.
Related