2020-03-24 19:08:37 +01:00
# Copyright (c) Microsoft Corporation.
2019-02-08 23:37:36 +01:00
# Licensed under the MIT License.
2018-05-22 21:58:51 +02:00
<#
. SYNOPSIS
2019-05-11 00:34:27 +02:00
Idempotently removes extra PowerShell paths from the machine , user and / or process environment scope with no reordering .
2018-05-22 21:58:51 +02: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 21:58:51 +02: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-11 00:34:27 +02:00
By default the cleanup leaves the highest sorted PowerShell path alone .
2018-05-22 21:58:51 +02:00
This switch causes it to be cleaned up as well .
Default : false
. EXAMPLE
. \ Reset-PWSHSystemPath . ps1
2019-05-11 00:34:27 +02:00
Removes all PowerShell paths but the very last one when sorted in ascending order from the Machine level path .
2018-05-22 21:58:51 +02:00
Good for running on systems that already has at least one valid PowerShell install .
. EXAMPLE
. \ Reset-PWSHSystemPath . ps1 -RemoveAllOccurences
2019-05-11 00:34:27 +02:00
Removes ALL PowerShell paths from the Machine level path .
Good for running right before upgrading PowerShell .
2018-05-22 21:58:51 +02: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 .
. 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-11 00:34:27 +02:00
#From the current path scope. retrieve the array of paths that match the pathspec of PowerShell (to use as a filter)
2018-05-22 21:58:51 +02:00
$pathstoremove = @ ( [ Environment ] :: GetEnvironmentVariable ( " PATH " , " $PathScopeItem " ) . split ( ';' ) | Where { $_ -ilike " *\Program Files\Powershell\6* " } )
If ( ! $RemoveAllOccurences )
{
2019-05-11 00:34:27 +02:00
#If we are not removing all occurances of PowerShell paths, then remove the highest sorted path from the filter
2018-05-22 21:58:51 +02:00
$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 " )
}
}