|
| 1 | +<# |
| 2 | +.SYNOPSIS |
| 3 | + Idempotently removes extra PowerShell Core paths from the machine, user and/or process environment scope with no reordering. |
| 4 | +
|
| 5 | +.DESCRIPTION |
| 6 | + Defaults to machine scope and leaving the last sorted path alone. |
| 7 | + Does not touch path if there is nothing to clean. |
| 8 | + Emits one simple log line about it's actions for each scope. |
| 9 | +
|
| 10 | + Also accessible in the powershell-core Chocolatey package by using -params '"/CleanUpSystemPath"' |
| 11 | +
|
| 12 | +.PARAMETER PathScope |
| 13 | + Set of machine scopes to clean up. Valid options are one or more of: Machine, User, Process. |
| 14 | + Default: machine |
| 15 | +
|
| 16 | +.PARAMETER RemoveAllOccurences |
| 17 | + By default the cleanup leaves the highest sorted PowerShell Core path alone. |
| 18 | + This switch causes it to be cleaned up as well. |
| 19 | + Default: false |
| 20 | +
|
| 21 | +.EXAMPLE |
| 22 | + .\Reset-PWSHSystemPath.ps1 |
| 23 | +
|
| 24 | + Removes all PowerShell core paths but the very last one when sorted in ascending order from the Machine level path. |
| 25 | + Good for running on systems that already has at least one valid PowerShell install. |
| 26 | +
|
| 27 | +.EXAMPLE |
| 28 | + .\Reset-PWSHSystemPath.ps1 -RemoveAllOccurences |
| 29 | +
|
| 30 | + Removes ALL PowerShell core paths from the Machine level path. |
| 31 | + Good for running right before upgrading PowerShell core. |
| 32 | +.EXAMPLE |
| 33 | + .\Reset-PWSHSystemPath.ps1 -PathScope Machine, User, Process |
| 34 | +
|
| 35 | + Removes all paths but the very last one when sorted in ascending order. |
| 36 | + Processes all path scopes including current process. |
| 37 | +.EXAMPLE |
| 38 | + .\Reset-PWSHSystemPath.ps1 -PathScope Machine, User, Process -RemoveAllOccurencs |
| 39 | +
|
| 40 | + Removes all paths from all path scopes including current process. |
| 41 | +#> |
| 42 | +param ( |
| 43 | + [ValidateSet("machine","user","process")] |
| 44 | + [string[]]$PathScope="machine", |
| 45 | + [switch]$RemoveAllOccurences |
| 46 | +) |
| 47 | + |
| 48 | +#Do the cleanup for all specified path scopes |
| 49 | +ForEach ($PathScopeItem in $PathScope) |
| 50 | +{ |
| 51 | + $AssembledNewPath = $NewPath = '' |
| 52 | + #From the current path scope. retrieve the array of paths that match the pathspec of PowerShell Core (to use as a filter) |
| 53 | + $pathstoremove = @([Environment]::GetEnvironmentVariable("PATH","$PathScopeItem").split(';') | Where { $_ -ilike "*\Program Files\Powershell\6*"}) |
| 54 | + If (!$RemoveAllOccurences) |
| 55 | + { |
| 56 | + #If we are not removing all occurances of powershell core paths, then remove the highest sorted path from the filter |
| 57 | + $pathstoremove = @($pathstoremove | sort-object | Select-Object -skiplast 1) |
| 58 | + } |
| 59 | + Write-Verbose "Reset-PWSHSystemPath: Found $($pathstoremove.count) paths to remove from $PathScopeItem path scope: $($Pathstoremove -join ', ' | out-string)" |
| 60 | + If ($pathstoremove.count -gt 0) |
| 61 | + { |
| 62 | + foreach ($Path in [Environment]::GetEnvironmentVariable("PATH","$PathScopeItem").split(';')) |
| 63 | + { |
| 64 | + #rebuild the path in the same order, but eliminate the paths in the filter array and blanks |
| 65 | + If ($Path) |
| 66 | + { |
| 67 | + If ($pathstoremove -inotcontains "$Path") |
| 68 | + { |
| 69 | + [string[]]$Newpath += "$Path" |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + $AssembledNewPath = ($newpath -join(';')).trimend(';') |
| 74 | + $AssembledNewPath -split ';' |
| 75 | + [Environment]::SetEnvironmentVariable("PATH",$AssembledNewPath,"$PathScopeItem") |
| 76 | + } |
| 77 | +} |
0 commit comments