function Set-PathVariable { param ( [Parameter(Mandatory = $true)] [Alias("Store")] [Alias("Location")] [ValidateSet("Process","User","Machine","Any")] [string]$StoreName, [Parameter(Mandatory = $false)] [string[]]$Append, [Parameter(Mandatory = $false)] [string[]]$Prepend, [Parameter(Mandatory = $false)] [string[]]$Remove, [string]$PathSeparator = [IO.Path]::PathSeparator ) $processPath = @() $userPath = @() $machinePath = @() $processPathAny = $false $userPathAny = $false $machinePathAny = $false $processPathDirty = $false $userPathDirty = $false $machinePathDirty = $false $modifyAny = $StoreName -eq 'Any' if (Any $Remove) { $Remove = $Remove.Where({![string]::IsNullOrWhiteSpace($PSItem)}) } if (Any $Prepend) { $Prepend = $Prepend.Where({![string]::IsNullOrWhiteSpace($PSItem)}) } if (Any $Append) { $Append = $Append.Where({![string]::IsNullOrWhiteSpace($PSItem)}) } if (!(Any $Remove)) { $Remove = @() } $count = 0 # if we are prepending or appending any paths, yoink them from their existing place if (Any $Prepend) { $count = $Prepend.Count foreach ($prependPath in $Prepend) { if ($Remove -notcontains $prependPath) { $Remove += $prependPath } } } if (Any $Append) { # Can't both prepend and append entries. # Assume prepend wins for ($i=0;$i -lt $count; $i++) { $removeIfFound = $Prepend[$i] $at = $Append.IndexOf($removeIfFound) if ($at -gt -1) { $Append.RemoveAt($at) } } foreach ($appendPath in $Append) { if ($Remove -notcontains $appendPath) { $Remove += $appendPath } } } if (!(Any $Remove)) { Write-Warning "No paths provided to modify. Exiting with no action taken." return } if (('Process','Any') -contains $StoreName) { $processPath = (Get-EnvironmentVariable -Name Path -StoreName 'Process') -split $PathSeparator $processPathAny = (Any $processPath) # If we were told to modify the process variable but none exists, we should still modify it if (!$processPathAny -and !$modifyAny) { $processPath = @() $processPathAny = $true } if ($processPathAny) { # coerce so we can RemoveAt [System.Collections.ArrayList]$processPath = [System.Collections.ArrayList]$processPath } } if (('User','Any') -contains $StoreName) { $userPath = (Get-EnvironmentVariable -Name Path -StoreName 'User') -split $PathSeparator $userPathAny = (Any $userPath) # If we were told to modify the user variable but none exists, we should still modify it if (!$userPathAny -and !$modifyAny) { $userPath = @() $userPathAny = $true } if ($userPathAny) { # coerce so we can RemoveAt [System.Collections.ArrayList]$userPath = [System.Collections.ArrayList]$userPath } } if (('Machine','Any') -contains $StoreName) { $machinePath = (Get-EnvironmentVariable -Name Path -StoreName 'Machine') -split $PathSeparator $machinePathAny = (Any $machinePath) # If we were told to modify the machine variable but none exists, we should still modify it if (!$machinePathAny -and !$modifyAny) { $machinePath = @() $machinePathAny = $true } if ($machinePathAny) { # coerce so we can RemoveAt [System.Collections.ArrayList]$machinePath = [System.Collections.ArrayList]$machinePath } } $count = $Remove.Count # remove first if (Any $Remove) { if ($processPathAny) { for ($i=0;$i -lt $count; $i++) { $removeIfFound = $Remove[$i] $at = $processPath.IndexOf($removeIfFound) if ($at -gt -1) { $processPath.RemoveAt($at) $processPathDirty = $true } } } if ($userPathAny) { for ($i=0;$i -lt $count; $i++) { $removeIfFound = $Remove[$i] $at = $userPath.IndexOf($removeIfFound) if ($at -gt -1) { $userPath.RemoveAt($at) $userPathDirty = $true } } } if ($machinePathAny) { for ($i=0;$i -lt $count; $i++) { $removeIfFound = $Remove[$i] $at = $machinePath.IndexOf($removeIfFound) if ($at -gt -1) { $machinePath.RemoveAt($at) $machinePathDirty = $true } } } } # then append if (Any $Append) { if ($processPathAny) { foreach($appendPath in $Append) { if ($processPath -notcontains $appendPath) { $processPath.Add($appendPath) } } $processPathDirty = $true } if ($userPathAny) { foreach($appendPath in $Append) { if ($userPath -notcontains $appendPath) { $userPath.Add($appendPath) } } $userPathDirty = $true } if ($machinePathAny) { foreach($appendPath in $Append) { if ($machinePath -notcontains $appendPath) { $machinePath.Add($appendPath) } } $machinePathDirty = $true } } # then prepend if (Any $Prepend) { if ($processPathAny) { $processPath = $Prepend + $processPath $processPathDirty = $true } if ($userPathAny) { $userPath = $Prepend + $userPath $userPathDirty = $true } if ($machinePathAny) { $machinePath = $Prepend + $machinePath $machinePathDirty = $true } } # ensure we don't write bad paths by checking for .Where({![string]::IsNullOrWhiteSpace($PSItem)}) if ($processPathDirty) { Set-EnvironmentVariable -Name Path -Value ($processPath.Where({![string]::IsNullOrWhiteSpace($PSItem)}) -join $PathSeparator) -StoreName 'Process' } if ($userPathDirty) { Set-EnvironmentVariable -Name Path -Value ($userPath.Where({![string]::IsNullOrWhiteSpace($PSItem)}) -join $PathSeparator) -StoreName 'User' } if ($machinePathDirty) { Set-EnvironmentVariable -Name Path -Value ($machinePath.Where({![string]::IsNullOrWhiteSpace($PSItem)}) -join $PathSeparator) -StoreName 'Machine' } }