I want to create new instance of my custom PSObject. I have a Button object created as PSObject and I want to create new object Button2 which has the same members as Button
Based on the answer by @TeraFlux, here's a function that will do a deep copy on multiple objects and accepts pipeline input.
Note, it leverages json conversion with a default depth of 100, which lends it to a few weaknesses
I would be interested in any caveats or improvements to deal with these
function Clone-Object
{
[CmdletBinding()]
Param `
(
[Parameter(ValueFromPipeline)] [object[]]$objects,
[Parameter()] [int] $depth = 100
)
$clones = foreach
($object in $objects)
{
$object | ConvertTo-Json -Compress -depth $depth | ConvertFrom-Json
}
return $clones
}
Here are some very basic unit tests
$testClone = `
{
$test1 = $null
$test2 = $null
$test3 = $null
$Test1 = [psCustomObject]@{a=1; b=2; c=3; d=4}
$Test2 = $Test1 | ConvertTo-Json -depth 100 | ConvertFrom-Json
$Test2 | add-Member -Name "e" -Value "5" -MemberType noteproperty
$Test3 = $test2 | Clone-Object
$Test3 | add-Member -Name "f" -Value "6" -MemberType noteproperty
$Test1.a = 7
$Test2.a = 8
#$Expected0 = [psCustomObject]@{a=1; b=2; c=3; d=4}
$Expected1 = [pscustomobject]@{a=7; b=2; c=3; d=4}
$Expected2 = [pscustomobject]@{a=8; b=2; c=3; d=4; e=5}
$Expected3 = [pscustomobject]@{a=1; b=2; c=3; d=4; e=5; f=6}
$results1 = @(); $results1+=$test1; $results1+=$expected1
$results2 = @(); $results2+=$test2; $results2+=$expected2
$results3 = @(); $results3+=$test3; $results3+=$expected3
$results1 | Format-Table # if these don't match then its probably passing references (copy not clone)
$results2 | Format-Table # if these don't match the core approach is incorrect
$results3 | Format-Table # if these don't match the function didn't work
}
&$testClone