Source/Environment/Add-EnvironmentVariable.ps1

<#
.SYNOPSIS
    Adds one or more values to a separator delimited environment variable.
.DESCRIPTION
    Reads the current value of the environment variable via Get-EnvironmentVariable, appends every given value that isn't already present, and writes the result back via Set-EnvironmentVariable in a single write per distinct name.
    Does nothing if every value is already present.
.PARAMETER Name
    The name of the environment variable.
.PARAMETER Value
    The value(s) to add.
.PARAMETER Scope
    The scope to read from and write to: Process, User, or Machine. Defaults to Process.
.PARAMETER Separator
    The delimiter between entries. Defaults to ",".
.EXAMPLE
    Add-EnvironmentVariable -Name "Foo" -Value "Bar" -Scope "User"
.EXAMPLE
    "Bar", "Baz" | Add-EnvironmentVariable -Name "Foo" -Scope "User"
.EXAMPLE
    [pscustomobject]@{ Name = "Foo"; Value = "Bar" } | Add-EnvironmentVariable -Scope "User"
.INPUTS
    [System.String] The value to add. Accepts pipeline input by value or by property name.
    [System.String] The name of the environment variable. Accepts pipeline input by property name.
.OUTPUTS
    None.
#>


function Add-EnvironmentVariable {

    [CmdletBinding(SupportsShouldProcess)]

    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [string]
        $Name,

        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [string]
        $Value,

        [string]
        $Separator = ",",

        [System.EnvironmentVariableTarget]
        $Scope = [System.EnvironmentVariableTarget]::"Process"
    )

    begin {

        $entriesByName = @{}

    }

    process {

        if (-not $entriesByName.ContainsKey($Name)) {

            $currentValue = Get-EnvironmentVariable -Name $Name -Scope $Scope

            $entriesByName[$Name] = @{
                Entries = @($currentValue -split [regex]::Escape($Separator) | Where-Object -FilterScript { -not [string]::IsNullOrEmpty($_) })
                Changed = $false
            }

        }

        if ($entriesByName[$Name].Entries -contains $Value) {

            return

        }

        if ($PSCmdlet.ShouldProcess($Name, "Add '$Value' to environment variable ($Scope)")) {

            $entriesByName[$Name].Entries += $Value
            $entriesByName[$Name].Changed = $true

        }

    }

    end {

        foreach ($name in $entriesByName.Keys) {

            if ($entriesByName[$name].Changed) {

                Set-EnvironmentVariable -Name $name -Value ($entriesByName[$name].Entries -join $Separator) -Scope $Scope

            }

        }

    }

}