PowerShell/tools/windows/Reset-PWSHSystemPath.ps1
Bram Crielaard 7031954669 Make install scripts more consistent over different operating systems (#9071)
I noticed a couple of inconsistencies when reading through the install bash scripts. 

- Make documentation for switches consistent over all files.
- Replace all `sed` implementations of `lowercase` with a more maintainable `tr` implementation.
- Set the `OS` variable in every install script, making it so previously unused checks are actually used.
- Exit with a non-zero exit code when the script reaches an illegal state.


## PR Context

A lot of people, including myself, read the install scripts before executing them. While doing so I noticed they contained inconsistencies. For example, certain flags you can pass to the install script were either undocumented or had an incorrect description. This PR fixes some of these inconsistencies, which should make them easier to maintain and easier to read.

Co-authored-by: Travis Plunk <github@ez13.net>
2019-03-08 13:00:04 -08:00

81 lines
3.1 KiB
PowerShell

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Idempotently removes extra PowerShell Core paths from the machine, user and/or process environment scope with no reordering.
.DESCRIPTION
Defaults to machine scope and leaving the last sorted path alone.
Does not touch path if there is nothing to clean.
Emits one simple log line about its actions for each scope.
Also accessible in the powershell-core Chocolatey package by using -params '"/CleanUpSystemPath"'
.PARAMETER PathScope
Set of machine scopes to clean up. Valid options are one or more of: Machine, User, Process.
Default: machine
.PARAMETER RemoveAllOccurences
By default the cleanup leaves the highest sorted PowerShell Core path alone.
This switch causes it to be cleaned up as well.
Default: false
.EXAMPLE
.\Reset-PWSHSystemPath.ps1
Removes all PowerShell core paths but the very last one when sorted in ascending order from the Machine level path.
Good for running on systems that already has at least one valid PowerShell install.
.EXAMPLE
.\Reset-PWSHSystemPath.ps1 -RemoveAllOccurences
Removes ALL PowerShell core paths from the Machine level path.
Good for running right before upgrading PowerShell core.
.EXAMPLE
.\Reset-PWSHSystemPath.ps1 -PathScope Machine, User, Process
Removes all paths but the very last one when sorted in ascending order.
Processes all path scopes including current process.
.EXAMPLE
.\Reset-PWSHSystemPath.ps1 -PathScope Machine, User, Process -RemoveAllOccurencs
Removes all paths from all path scopes including current process.
#>
param (
[ValidateSet("machine","user","process")]
[string[]]$PathScope="machine",
[switch]$RemoveAllOccurences
)
#Do the cleanup for all specified path scopes
ForEach ($PathScopeItem in $PathScope)
{
$AssembledNewPath = $NewPath = ''
#From the current path scope. retrieve the array of paths that match the pathspec of PowerShell Core (to use as a filter)
$pathstoremove = @([Environment]::GetEnvironmentVariable("PATH","$PathScopeItem").split(';') | Where { $_ -ilike "*\Program Files\Powershell\6*"})
If (!$RemoveAllOccurences)
{
#If we are not removing all occurances of powershell core paths, then remove the highest sorted path from the filter
$pathstoremove = @($pathstoremove | sort-object | Select-Object -skiplast 1)
}
Write-Verbose "Reset-PWSHSystemPath: Found $($pathstoremove.count) paths to remove from $PathScopeItem path scope: $($Pathstoremove -join ', ' | out-string)"
If ($pathstoremove.count -gt 0)
{
foreach ($Path in [Environment]::GetEnvironmentVariable("PATH","$PathScopeItem").split(';'))
{
#rebuild the path in the same order, but eliminate the paths in the filter array and blanks
If ($Path)
{
If ($pathstoremove -inotcontains "$Path")
{
[string[]]$Newpath += "$Path"
}
}
}
$AssembledNewPath = ($newpath -join(';')).trimend(';')
$AssembledNewPath -split ';'
[Environment]::SetEnvironmentVariable("PATH",$AssembledNewPath,"$PathScopeItem")
}
}