internal/functions/Get-ClonedObject.ps1
function Get-ClonedObject { [CmdletBinding()] param( [parameter(Position = 0, ValueFromPipeline = $true)] $InputObject, [switch] $AsHashTable, [switch] $AsShallowClone ) $clone = $InputObject if ($AsHashTable) { # only support deep cloning to hashtable if ($null -ne $InputObject) { $json = ConvertTo-Json $InputObject -Depth 100 -Compress $clone = ConvertFrom-Json $json -NoEnumerate -Depth 100 -AsHashTable } else { $clone = @{} } } else { if ($null -ne $InputObject) { if ($AsShallowClone) { if ($InputObject -is [System.ICloneable]) { $clone = $InputObject.Clone() } } elseif ($InputObject -is [System.ValueType] -or $InputObject -is [datetime]) { $clone = $InputObject } else { if ($InputObject -is [System.Collections.IDictionary]) { $clone = $InputObject.Clone() foreach ($key in $InputObject.Keys) { $value = $InputObject[$key] $isComplex = -not ($null -eq $value -or $value -is [string] -or $value -is [System.ValueType] -or $value -is [datetime]) if ($isComplex) { $clone[$key] = Get-ClonedObject -InputObject $value } } } elseif ($InputObject -is [System.Collections.IList]) { $clone = $InputObject.Clone() for ($i = 0; $i -lt $clone.Count; $i++) { $value = $InputObject[$i] $isComplex = -not ($null -eq $value -or $value -is [string] -or $value -is [System.ValueType] -or $value -is [datetime]) if ($isComplex) { $clone[$i] = Get-ClonedObject -InputObject $value } else { # assumin uniform IList break } } } elseif ($InputObject -is [psobject]) { $clone = $InputObject.PSObject.Copy() foreach ($propertyName in $InputObject.PSObject.Properties.Name) { $value = $InputObject.$propertyName $isComplex = -not ($null -eq $value -or $value -is [string] -or $value -is [System.ValueType] -or $value -is [datetime]) if ($isComplex) { $clone.$propertyName = Get-ClonedObject -InputObject $value } } } } } } if ($clone -is [System.Collections.IList]) { Write-Output $clone -NoEnumerate } else { Write-Output $clone } } |