ps/Modules/Cole.PowerShell.Developer/Public/Set-PathVariable.ps1
2023-05-30 22:51:22 -07:00

220 lines
6.8 KiB
PowerShell

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'
}
}