adding path cleanup utility Reset-PWSHSystemPath.ps1 (#6892)

This commit is contained in:
Darwin 2018-05-22 15:58:51 -04:00 committed by Travis Plunk
parent 6d7799b766
commit 862d99f595

View file

@ -0,0 +1,77 @@
<#
.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 it's 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")
}
}