PowerShell completely copies the array

I am trying to create a full copy of an existing array. Every time I try to do this, it seems like it is not working. The fact is that I am changing the names of objects inside a new copied array, but they also change in the original array.

The code below is very simplified, as there is so much more to it than just renaming object names, but that proves what I think.

Code example:

Function Get-Fruits { Param ( $Fruits = @('Banana', 'Apple', 'Pear') ) foreach ($F in $Fruits) { [PSCustomObject]@{ Type = $F } } } $FruitsOriginal = Get-Fruits Function Rename-ObjectName { # Copy the array here $FruitsNew = $FruitsOriginal # Not a true copy $FruitsNew = $FruitsOriginal | % {$_} # Not a true copy $FruitsNew = $FruitsOriginal.Clone() # Not a true copy $FruitsNew | Get-Member | ? MemberType -EQ NoteProperty | % { $Name = $_.Name $FruitsNew | % { $_ | Add-Member 'Tasty fruits' -NotePropertyValue $_.$Name $_.PSObject.Properties.Remove($Name) } } } Rename-ObjectName 

The desired result is 2 completely separate arrays.

$ FruitsOriginal

 Type ---- Banana Apple Pear 

$ FruitsNew

 Tasty fruits ------------ Banana Apple Pear 

Thank you for your help.

+4
source share
4 answers

You can use serialization to deeply clone your array:

 #Original data $FruitsOriginal = Get-Fruits # Serialize and Deserialize data using BinaryFormatter $ms = New-Object System.IO.MemoryStream $bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $bf.Serialize($ms, $FruitsOriginal) $ms.Position = 0 #Deep copied data $FruitsNew = $bf.Deserialize($ms) $ms.Close() 
+8
source

Since Powershell 3.0, the same approach as Jaco answer , but using PSSerializer .
It uses the CliXML format, compatible with Export-Clixml and Import-Clixml , and it’s easier for me personally to read it.
Theoretically supports nested hierarchy up to [int32]::MaxValue levels-deep

 # Original data $FruitsOriginal = Get-Fruits # Serialize and Deserialize data using PSSerializer: $_TempCliXMLString = [System.Management.Automation.PSSerializer]::Serialize($FruitsOriginal, [int32]::MaxValue) $FruitsNew = [System.Management.Automation.PSSerializer]::Deserialize($_TempCliXMLString) # Deep copy done. 
+2
source
 # Copy the array here $FruitsCopy = @() $FruitsCopy = $FruitsCopy + $FruitsOriginal 
+1
source

Depending on what you need to do with the objects, and if they are simple enough (as in your example), you can simply replace them with a new object.

$NewFruits = $FruitsOriginal | %{ [PSCustomObject]@{ "Tasty Fruits" = $_.Type } }

0
source

Source: https://habr.com/ru/post/1268678/


All Articles