public/Pop-EnvironmentStack.ps1

#requires -Version 3
Set-StrictMode -Version Latest


function Pop-EnvironmentStack{
    <#
    .SYNOPSIS
        Changes the current Environment Variable to the Environment Variable most recently pushed onto the stack.
    .DESCRIPTION
        The Pop-EnvironmentStack cmdlet changes the current Environment Variable to the Environment Variable most recently pushed onto the stack by using the Push-Environment cmdlet.
        You can pop a Environment Variable from the default stack or from a stack that you create by using a Push-Environment command.
    .EXAMPLE
        PS C:\> Pop-EnvironmentStack
    .EXAMPLE
        PS C:\> Pop-EnvironmentStack -Peek
    .EXAMPLE
        PS C:\> Pop-EnvironmentStack -Drop
    #>

    [CmdletBinding(DefaultParametersetName="Stack", SupportsShouldProcess)]
    Param(
        # Specifies the Environment Variable stack from which the Environment Variable is popped. Enter a Environment Variable stack name.
        #
        # Without this parameter, Pop-EnvironmentStack pops a Environment Variable from the current Environment Variable stack.
        # By default, the current Environment Variable stack is the unnamed default Environment Variable stack that Windows PowerShell creates.
        # To make a Environment Variable stack the current Environment Variable stack, use the StackName parameter of Set-Environment.
        [Parameter(Position=0, ParameterSetName="Stack", ValueFromPipelineByPropertyName)]
        [Parameter(Position=0, ParameterSetName="StackDrop", ValueFromPipelineByPropertyName)]
        [String]$StackName = ""
        ,
        # Peek Replace Mode
        # "Append" : not remove Environment Variable
        [Parameter(ParameterSetName="Stack")]
        [ValidateSet("Overwrite", "Append")]
        [string]$ReplaceMode = "Overwrite"
        ,
        # Peek Environment Stack
        [Parameter(ParameterSetName="Stack")]
        [switch]$Peek
        ,
        # Remove Environment Stack Top
        # not apply Environment Variable
        [Parameter(ParameterSetName="StackDrop")]
        [switch]$Drop
    )
    Begin
    {
        if($StackName -eq ""){
            $name = $script:DefaultEnvStackName
        }else{
            $name = $StackName
        }

        if(-not $script:EnvStack.Contains($name)){
            return
        }

        $stack = $script:EnvStack[$name]

        if($Drop){
            if($PSCmdlet.ShouldProcess("StackName: ${name}", "Drop Environment Stack Top")){
                [void]$stack.Pop()
                if($stack.Count -eq 0){
                    $script:EnvStack.Remove($name)
                }
            }
            return
        }

        if($Peek -or $WhatIfPreference){
            $applyEnvs = $stack.Peek()
        }else{
            $applyEnvs = $stack.Pop()
        }

        if($stack.Count -eq 0){
            $script:EnvStack.Remove($name)
        }

        $currentEnvs = New-InternalEnvHashTable
        Get-EnvironmentVariable | ForEach-Object {
            $currentEnvs[$_.Name] = $_
        }

        if($ReplaceMode -eq "Overwrite"){
            $currentEnvs.Values | ForEach-Object {
                if(-not $applyEnvs.Contains($_.Name)){
                    if($PSCmdlet.ShouldProcess("$($_.Name)", "Remove Environment Variable")){
                        Remove-EnvironmentVariable -LiteralName ($_.Name) -Confirm:$false
                    }
                }
            }
        }

        $applyEnvs.Values | ForEach-Object {
            if($currentEnvs.Contains($_.Name)){
                if($currentEnvs[$_.Name].Value -cne $_.Value){
                    if($PSCmdlet.ShouldProcess("$($_.Name)", "Update Environment Variable")){
                        Set-EnvironmentVariable -Name $_.Name -Value $_.Value -Confirm:$false
                    }
                }
            }else{
                if($PSCmdlet.ShouldProcess("$($_.Name)", "New Environment Variable")){
                    Set-EnvironmentVariable -Name $_.Name -Value $_.Value -Confirm:$false
                }
            }
        }

    }

}