2020-03-24 11:08:37 -07:00
# Copyright (c) Microsoft Corporation.
2019-02-08 17:37:36 -05:00
# Licensed under the MIT License.
2018-05-22 15:58:51 -04:00
<#
. SYNOPSIS
2019-05-10 15:34:27 -07:00
Idempotently removes extra PowerShell paths from the machine, user and/or process environment scope with no reordering.
2018-05-22 15:58:51 -04:00
. DESCRIPTION
Defaults to machine scope and leaving the last sorted path alone.
Does not touch path if there is nothing to clean.
2019-03-08 22:00:04 +01:00
Emits one simple log line about its actions for each scope.
2018-05-22 15:58:51 -04:00
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
2019-05-10 15:34:27 -07:00
By default the cleanup leaves the highest sorted PowerShell path alone.
2018-05-22 15:58:51 -04:00
This switch causes it to be cleaned up as well.
Default: false
. EXAMPLE
.\Reset-PWSHSystemPath.ps1
2019-05-10 15:34:27 -07:00
Removes all PowerShell paths but the very last one when sorted in ascending order from the Machine level path.
2018-05-22 15:58:51 -04:00
Good for running on systems that already has at least one valid PowerShell install.
. EXAMPLE
.\Reset-PWSHSystemPath.ps1 -RemoveAllOccurences
2019-05-10 15:34:27 -07:00
Removes ALL PowerShell paths from the Machine level path.
Good for running right before upgrading PowerShell.
2020-11-25 01:53:55 -05:00
2018-05-22 15:58:51 -04:00
. 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.
2020-11-25 01:53:55 -05:00
2018-05-22 15:58:51 -04:00
. 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 = ''
2019-05-10 15:34:27 -07:00
#From the current path scope. retrieve the array of paths that match the pathspec of PowerShell (to use as a filter)
2020-11-18 23:25:52 -06:00
$pathstoremove = @ ([ Environment ]:: GetEnvironmentVariable ( "PATH" , " $PathScopeItem " ). split ( ';' ) | Where-Object { $_ -ilike "*\Program Files\Powershell\6*" })
2018-05-22 15:58:51 -04:00
If (! $RemoveAllOccurences )
{
2019-05-10 15:34:27 -07:00
#If we are not removing all occurances of PowerShell paths, then remove the highest sorted path from the filter
2020-05-07 13:00:30 +01:00
$pathstoremove = @ ( $pathstoremove | Sort-Object | Select-Object -SkipLast 1 )
2018-05-22 15:58:51 -04:00
}
2020-05-07 13:00:30 +01:00
Write-Verbose "Reset-PWSHSystemPath: Found $( $pathstoremove . count ) paths to remove from $PathScopeItem path scope: $( $Pathstoremove -join ', ' | Out-String ) "
2018-05-22 15:58:51 -04:00
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 " )
}
}