Skip to content

Instantly share code, notes, and snippets.

@AzimsTech
Last active November 22, 2019 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AzimsTech/6969910f20bf763b24e2c4f8b58fbb9e to your computer and use it in GitHub Desktop.
Save AzimsTech/6969910f20bf763b24e2c4f8b58fbb9e to your computer and use it in GitHub Desktop.
Update-StartMenu powershell script: cleans up Start Menu after software installation | Thanks to @macxcool
:: Example of usage
:: Must be run as administrator
echo Cleaning Steam
powershell.exe -noprofile -executionpolicy bypass -file %~dp0\Update-StartMenu.ps1 -Folder "Steam" -GoodLinks "All"
PAUSE
echo Cleaning Python 3.7
powershell.exe -noprofile -executionpolicy bypass -file %~dp0\Update-StartMenu.ps1 -Folder "Python 3.7" -GoodLinks "Python 3.7 (64-bit)"
PAUSE
<#
.SYNOPSIS
Cleans up the Start Menu by moving shortcuts and deleting unwanted shortcuts and folders.
.DESCRIPTION
Moves shortcuts to the root or a folder of the Menu and deletes unwanted shortcuts and leftover folders.
.PARAMETER Folder
The name of the Start Menu subfolder to work in
.PARAMETER GoodLinks
An array of shortcut names to keep and move to the Menu root. 'All' will keep all links... not useful in some contexts.
.PARAMETER $KeepFolder
A Switch parameter that retains the folder but keeps only the listed links. Can't be used with $OtherFolder or $MoveLinks
.PARAMETER $OtherFolder
A switch that creates a folder (if necessary) into which the links will be placed. Links from anywhere in the Start Menu
can be used here. The script will look for them recursively. Only filenames unique in the hierarchy will work.
Can't be used with $KeepFolder or $MoveLinks
.PARAMETER $MoveLinks
The default mode. A Switch to tell the script to Move the links rather than keeping or creating a folder for them.
This switch is assumed and so does not have to be specified.
.EXAMPLE
Update-StartMenu -Folder 'Greenshot' -GoodLinks 'Greenshot','Readme'
.EXAMPLE
Update-StartMenu -Folder 'Some App' -GoodLinks 'All'
.EXAMPLE
Update-StartMenu -Folder 'Some Other App' -GoodLinks 'This App','App Website' -KeepFolder
.NOTES
Created by macxcool
#>
[CmdletBinding(DefaultParametersetName='MoveLinks')]
Param (
[Parameter(Mandatory=$true,HelpMessage='Enter the name of a Start Menu subfolder.')]
[ValidateNotNullorEmpty()]
[string]$Folder,
[Parameter(Mandatory=$true,HelpMessage='Enter a list of links to keep. "All" can be used to keep all links.')]
[ValidateNotNullorEmpty()]
[string[]]$GoodLinks,
[Parameter(ParameterSetName='KeepFolder')]
[switch]$KeepFolder,
[Parameter(ParameterSetName='OtherFolder')]
[switch]$OtherFolder,
[Parameter(ParameterSetName='MoveLinks')]
[switch]$MoveLinks
)
# Set up a couple of useful variables
[string]$envCommonStartMenuPrograms = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs'
[string]$envCommonStartMenuProgramsUsers = "$Env:USERPROFILE\AppData\Roaming\Microsoft\Windows\Start Menu\Programs"
$folderPath = "$envCommonStartMenuPrograms\${Folder}"
$folderPath2 = "$envCommonStartMenuProgramsUsers\${Folder}"
#### Using the KeepFolder Mode #### Keep certain files in an existing Folder and delete the rest.
If ($KeepFolder) {
# Check to see if the folder exists. This doesn't make much sense if it doesn't
If (Test-Path -Path $folderPath -PathType Container) {
# See if 'All' is being used and it's the only thing in GoodLinks
If (($GoodLinks -contains 'All') -and ($GoodLinks.Count -eq 1)) {
Write-Host 'Warning: Doing nothing. This combination of parameters leaves everything as-is!'
}
# If 'All' is not being used we can go ahead and remove anything not in GoodLinks
ElseIf ($GoodLinks -notcontains 'All') {
Write-Host "Removing unwanted links from Start Menu folder [${Folder}]"
# Get a full listing of the files in Folder
Get-ChildItem -Path $folderPath -File -Recurse | ForEach-Object {
# If this file's name isn't in GoodLinks then remove it.
If ($GoodLinks -notcontains $_.BaseName) {
Remove-Item -Path $_.FullName -Force
}
}
}
Else {
Write-Host 'Error: It does not make sense to use [All] with anything else.'
}
}
Else {
Write-Host "Error: Folder [$($Folder)] does not exist."
}
}
#### Using the OtherFolder Mode #### Move files into another folder from anywhere in the Start Menu hierarchy.
ElseIf ($OtherFolder) {
# Using 'All' with OtherFolder doesn't really make sense. We aren't going to move all the start menu files
If (($GoodLinks -contains 'All') -and ($GoodLinks.Count -eq 1)) {
Write-Host 'Error: [All] cannot be used with [OtherFolder]. You need to specify lnk names.'
}
ElseIf ($GoodLinks -notcontains 'All') { # 'All' is not being used, so go ahead
New-Item -Path $folderPath -ItemType Directory -Force
# Now it's time to move all the goodlinks files into the folder
ForEach ($link in $GoodLinks) {
# Look recursively through the Start Menu for this filename and move it. Only names unique in the Start hierarchy will work.
$fileObj = Get-ChildItem -Path "$envCommonStartMenuPrograms" -Include "$($link).*" -File -Recurse
Write-Host "Moving [$($fileObj.Name)] into folder [$($Folder)]"
Move-Item -Path $fileObj.FullName -Destination $folderPath
#Write-Host "[$($fileObj.FullName)] to [$($envCommonStartMenuPrograms)\$($Folder)] "
}
}
Else {
Write-Host 'Error: It does not make sense to use [All] with anything else.'
}
}
#### Using the MoveFiles Mode #### Move files into the root of the Start Menu.
Else {
If (Test-Path -Path $folderPath -PathType Container) {
If (($GoodLinks -contains 'All') -and ($GoodLinks.Count -eq 1)) {
Write-Host 'Moving all Links into main Start Menu folder.'
Get-ChildItem -Path $folderPath -File -Recurse | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $envCommonStartMenuPrograms -Force
}
Remove-Item -Path $folderPath -Force
}
ElseIf ($GoodLinks -notcontains 'All') {
ForEach ($link in $GoodLinks) {
$filePath = (Get-ChildItem "$folderPath\$($link).*" -File -Recurse).FullName
Copy-Item -Path $filePath -Destination $envCommonStartMenuPrograms -Force
}
Remove-Item -Path $folderPath -Force
}
Else {
Write-Host 'Error: It does not make sense to use [All] with anything else.'
}
}
ElseIf (Test-Path -Path $folderPath2 -PathType Container) {
If (($GoodLinks -contains 'All') -and ($GoodLinks.Count -eq 1)) {
Write-Host 'Moving all Links into main Start Menu folder.'
Get-ChildItem -Path $folderPath2 -File -Recurse | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $envCommonStartMenuProgramsUsers -Force
}
Remove-Item -Path $folderPath2 -Force
}
ElseIf ($GoodLinks -notcontains 'All') {
ForEach ($link in $GoodLinks) {
$filePath = (Get-ChildItem "$folderPath2\$($link).*" -File -Recurse).FullName
Copy-Item -Path $filePath -Destination $envCommonStartMenuProgramsUsers -Force
}
Remove-Item -Path $folderPath2 -Force
}
Else {
Write-Host 'Error: It does not make sense to use [All] with anything else.'
}
}
Else {
Write-Host "Error: Folder [$($Folder)] does not exist. Cannot complete moving of links."
Write-Host $folderPath2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment