private/New-InternalStack.ps1

#requires -Version 3
Set-StrictMode -Version Latest
function New-InternalStack(){
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function')]
    Param($Name)

    if($Name -eq ""){
        $Name = "(unnamed)";
    }

    $new = [PSCustomObject]@{
        PSTypeName  = 'PwshEnvironment.Stack'
        StackName   = $Name
        Data        = (New-Object System.Collections.Stack)
    }
    $new | Add-Member -MemberType ScriptMethod -Name Clone -Value {

        $c = $this.PSObject.Copy()

        $c.Data = (New-Object System.Collections.Stack)

        $dat = @($this.Data)
        [Array]::Reverse($dat)

        $dat | ForEach-Object {
            if($_ -is [System.Array]){
                $c.Push(($_ | ForEach-Object {
                    $_.Clone()
                }))
            }else{
                $c.Push($_.Clone())
            }
        }

        $c

    }

    $new | Add-Member -MemberType ScriptProperty -Name "Count" -Value {
        $this.Data.Count
    }
    $new | Add-Member -MemberType ScriptMethod -Name "Push" -Value {
        param($o)
        $this.Data.Push($o)
    }
    $new | Add-Member -MemberType ScriptMethod -Name "Pop" -Value {
        param()
        $this.Data.Pop()
    }
    $new | Add-Member -MemberType ScriptMethod -Name "Peek" -Value {
        param()
        $this.Data.Peek()
    }

    $new

}