src/public/System/Add-AitherPathEntries.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Add entries to PATH environment variable .DESCRIPTION Adds one or more directories to the PATH variable at the specified scope. Validates that paths exist before adding them and skips duplicates. .PARAMETER Paths Array of directory paths to add to PATH .PARAMETER Scope PATH scope: Process, User, or Machine .PARAMETER DryRun Preview changes without applying .EXAMPLE Add-AitherPathEntries -Paths @('C:\Tools', 'C:\MyApp') -Scope User Add multiple directories to user PATH .EXAMPLE Add-AitherPathEntries -Paths '/usr/local/bin' -Scope Process -DryRun Preview adding a path to process PATH .OUTPUTS Boolean - True if any paths were added, False otherwise .NOTES Machine scope requires administrator privileges. Paths are validated to exist before being added. Duplicate paths are automatically skipped. .LINK Set-AitherEnvironmentConfig Set-AitherEnvVariable #> function Add-AitherPathEntries { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string[]]$Paths, [ValidateSet('Process', 'User', 'Machine')] [string]$Scope = 'User', [switch]$DryRun, [Parameter(HelpMessage = "Show command output in console.")] [switch]$ShowOutput ) begin { # Manage logging targets for this execution $originalLogTargets = $script:AitherLogTargets if ($ShowOutput) { if ($script:AitherLogTargets -notcontains 'Console') { $script:AitherLogTargets += 'Console' } } else { # Ensure Console is NOT in targets if ShowOutput is not specified $script:AitherLogTargets = $script:AitherLogTargets | Where-Object { $_ -ne 'Console' } } } process { try { # During module validation, skip execution if ($PSCmdlet.MyInvocation.InvocationName -eq '.') { return $false } # Check admin for Machine scope if ($Scope -eq 'Machine') { $isAdmin = if (Get-Command Test-AitherAdmin -ErrorAction SilentlyContinue) { Test-AitherAdmin } else { $false } if (-not $isAdmin) { Write-AitherLog -Message "Administrator privileges required for Machine scope" -Level Warning -Source 'Add-AitherPathEntries' return $false } } # Get current PATH $currentPath = [Environment]::GetEnvironmentVariable('PATH', $Scope) $pathEntries = $currentPath -split [IO.Path]::PathSeparator | Where-Object { $_ } $added = 0 foreach ($path in $Paths) { # Validate path exists if (-not (Test-Path $path)) { Write-AitherLog -Message "Path does not exist: $path (skipping)" -Level Warning -Source 'Add-AitherPathEntries' continue } # Check if already in PATH if ($pathEntries -contains $path) { Write-AitherLog -Message "Path already in $Scope PATH: $path" -Level Debug -Source 'Add-AitherPathEntries' continue } if ($DryRun) { Write-AitherLog -Message "[DRY RUN] Would add to $Scope PATH: $path" -Level Information -Source 'Add-AitherPathEntries' } else { $pathEntries += $path Write-AitherLog -Message "Added to $Scope PATH: $path" -Level Information -Source 'Add-AitherPathEntries' } $added++ } if ($added -gt 0 -and -not $DryRun) { $newPath = $pathEntries -join [IO.Path]::PathSeparator [Environment]::SetEnvironmentVariable('PATH', $newPath, $Scope) } return ($added -gt 0) } catch { Write-AitherLog -Message "Error adding path entries: $($_.Exception.Message)" -Level Error -Source 'Add-AitherPathEntries' -Exception $_ throw } finally { # Restore original log targets $script:AitherLogTargets = $originalLogTargets } } } |