Clean all shortcuts on the all users desktop (because users cannot delete them) and also remove unwanted shortcuts from the Start menu such as "Uninstall"-shortcuts.
I run this on our student computers in computer rooms where the Onedrive client cannot be used, instead we mount Onedrive as a mapped folder instead using
.
We also want to remove unnecessary shortcuts for Java & Silverlight.
The script is based on several functions that could be used to remove files and folers other than the desktop and start menu shortcuts.
# David Djerf 2017-05-11
Function Remove-UnwantedFolders {
<#
.SYNOPSIS
Removes unwanted folders in a path
.DESCRIPTION
Will remove one or more folders from a path, for example use this to remove unwanted folders in the start menu.
.NOTES
davpe67 2017-02-18
.PARAMETER WorkFolder
Define a path where script should seach recursive for the folders to remove
For example: "C:\" or "$ENV:Temp"
.PARAMETER SearchStartMenu
Will Set Workfolder to "$ENV:Programdata\Microsoft\Windows\Start Menu"
.PARAMETER UnwantedFolders
Specify one or more folders you want to remove.
For example: "Java","Silverlight"
.EXAMPLE
Remove-UnwantedFolders -SearchStartMenu -UnwantedFolders "Java","Unique Admin Generator" -WhatIf
#>
[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="WorkFolder")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="WorkFolder", Position=0, HelpMessage='Specify folder(s) serch in: ["C:\path\to\folders"]')]
[string]$WorkFolder,
[Parameter(Mandatory=$True, ParameterSetName="SearchStartMenu", Position=0)]
[switch]$SearchStartMenu,
[Parameter(Mandatory=$True, HelpMessage='Specify folder(s) to remove: ["Folder1","Folder"]')]
[string[]]$UnwantedFolders
)
BEGIN {
Write-Verbose "Begin..."
IF ($SearchStartMenu) {
$IsAdmin=Test-Admin
Write-Verbose "`$IsAdmin is $IsAdmin"
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:ProgramData\Microsoft\Windows\Start Menu")
} ELSE {
$WorkFolder = Resolve-Path "$WorkFolder"
} # End of IF ELSE
Write-Verbose "`$WorkFolder=`"$WorkFolder`""
Write-Verbose "`$UnwantedFolders=`"$UnwantedFolders`""
} # End of Begin
PROCESS {
# Remove Unwanted Folders in Start Menu
IF ($UnwantedFolders -and $WorkFolder) { # Only run if not empty
Write-Verbose "Processing..."
IF ($UnwantedFolders) {
ForEach ($UnwantedFolder in $UnwantedFolders) {
Get-ChildItem -Recurse -Path $WorkFolder -Directory | Where-Object {$_.Name -like "$UnwantedFolder" } | Resolve-Path | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
} # End of ForEach
} # End of IF
} # End of IF
} # End of Process
} # End of function Remove-UnwantedFolders
Function Remove-UnwantedFiles {
<#
.SYNOPSIS
Removes unwanted files in a path
.DESCRIPTION
Will remove one or more files from a path, for example use this to remove unwanted files in the start menu.
.NOTES
davpe67 2017-03-03
.PARAMETER WorkFolder
Define a path where script should seach recursive for the folders to remove
For example: "C:\" or "$ENV:Temp"
.PARAMETER SearchStartMenu
Will Set Workfolder to "$ENV:Programdata\Microsoft\Windows\Start Menu"
.PARAMETER UnwantedFiles
Specify one or more folders you want to remove.
For example: "Onedrive","Onedrive for Business"
.EXAMPLE
Remove-UnwantedFiles -SearchStartMenu -UnwantedFiles "Onedrive","Onedrive for Business" -WhatIf
#>
[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="WorkFolder")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="WorkFolder", Position=0, HelpMessage='Specify folder(s) serch in: ["C:\path\to\folders"]')]
[string]$WorkFolder,
[Parameter(Mandatory=$True, ParameterSetName="SearchStartMenu", Position=0)]
[switch]$SearchStartMenu,
[Parameter(Mandatory=$True, HelpMessage='Specify files(s) to remove: ["File1","File"]')]
[string[]]$UnwantedFiles
)
BEGIN {
Write-Verbose "Begin..."
IF ($SearchStartMenu) {
$IsAdmin=Test-Admin
Write-Verbose "`$IsAdmin is $IsAdmin"
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:ProgramData\Microsoft\Windows\Start Menu")
} ELSE {
$WorkFolder = Resolve-Path "$WorkFolder"
} # End of IF ELSE
Write-Verbose "`$WorkFolder=`"$WorkFolder`""
Write-Verbose "`$UnwantedFiles=`"$UnwantedFiles`""
} # End of Begin
PROCESS {
# Remove Unwanted Folders in Start Menu
IF ($UnwantedFiles -and $WorkFolder) { # Only run if not empty
Write-Verbose "Processing..."
IF ($UnwantedFiles) {
ForEach ($UnwantedFile in $UnwantedFiles) {
Get-ChildItem -Recurse -Path $WorkFolder -File | Where-Object {$_.Name -like "$UnwantedFile" } | Resolve-Path | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
} # End of ForEach
} # End of IF
} # End of IF
} # End of Process
} # End of function Remove-UnwantedFiles
function Test-Admin {
<#
.SYNOPSIS
Test if script is run as administrator
.DESCRIPTION
Use to check if script is run with administrator privilegues or not.
Will return true or false.
.NOTES
Downloaded from: http://www.powertheshell.com/testadmin/
.EXAMPLE
Test-Admin
#>
$wid = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$prp = New-Object System.Security.Principal.WindowsPrincipal($wid)
$adm = [System.Security.Principal.WindowsBuiltInRole]::Administrator
$prp.IsInRole($adm)
}
Function Remove-UninstallLinks {
<#
.SYNOPSIS
Removes unwanted Uninstall links in a path
.DESCRIPTION
Will remove links that begin with "uninstall" from a path,
for example use this to remove unwanted uninstall-links in the start menu.
.NOTES
davpe67 2017-02-18
.PARAMETER WorkFolder
Define a path where script should seach recursive for the folders to remove
For example: "C:\" or "$ENV:Temp"
.PARAMETER SearchStartMenu
Will Set Workfolder to "$ENV:Programdata\Microsoft\Windows\Start Menu"
.EXAMPLE
Remove-UnwantedFolders -SearchStartMenu -WhatIf
#>
[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="WorkFolder")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="WorkFolder", Position=0, HelpMessage='Specify folder(s) serch in: ["C:\path\to\folders"]')]
[string]$WorkFolder,
[Parameter(Mandatory=$True, ParameterSetName="SearchStartMenu", Position=0)]
[switch]$SearchStartMenu
)
BEGIN {
Write-Verbose "Begin..."
IF ($SearchStartMenu) {
$IsAdmin=Test-Admin
Write-Verbose "`$IsAdmin is $IsAdmin"
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:ProgramData\Microsoft\Windows\Start Menu")
} ELSE {
$WorkFolder = Resolve-Path "$WorkFolder"
} # End of IF ELSE
Write-Verbose "`$WorkFolder=`"$WorkFolder`""
} # End of Begin
PROCESS {
Write-Verbose "Processing..."
# Remove all Uninstall-links
$UninstallLinks=Get-ChildItem -Recurse -Path $WorkFolder -File "*.lnk" | Where-Object {$_.Name -like "Uninstall*" } | Resolve-Path
$UninstallLinks | ForEach-Object {
Write-Verbose "Removing `"$_`""
Remove-Item "$_" -Recurse -Force -ErrorAction SilentlyContinue
}
} # End of Process
} # End of Remove-UninstallLinks
Function Remove-EmptyFolders {
<#
.SYNOPSIS
Removes empty folders in a path.
.DESCRIPTION
Will remove empty folders in a path.
Script will loop x times to ensure folders that became empty, default number is 10.
.NOTES
davpe67 2017-02-18
.PARAMETER WorkFolder
Define a path where script should seach recursive for the folders to remove
For example: "C:\" or "$ENV:Temp"
.PARAMETER SearchStartMenu
Will Set Workfolder to "$ENV:Programdata\Microsoft\Windows\Start Menu"
.PARAMETER KeepFolders
Will not remove folders with these names.
For example: "StartUp","Maintenance"
.PARAMETER Looptimes
Script will loop this many times to remove new empty folders from previous runs.
.EXAMPLE
Remove-EmptyFolders -SearchStartMenu -Looptimes 10 -WhatIf
#>
[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="WorkFolder")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="WorkFolder", Position=0, HelpMessage='Specify folder(s) serch in: ["C:\path\to\folders"]')]
[string]$WorkFolder,
[Parameter(Mandatory=$True, ParameterSetName="SearchStartMenu", Position=0)]
[switch]$SearchStartMenu,
[int]$Looptimes,
[string[]]$KeepFolders
)
BEGIN {
Write-Verbose "Begin..."
IF (!$Looptimes) { $Looptimes=10 }
IF ($SearchStartMenu) {
$IsAdmin=Test-Admin
Write-Verbose "`$IsAdmin is $IsAdmin"
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:ProgramData\Microsoft\Windows\Start Menu")
} ELSE {
$WorkFolder = Resolve-Path "$WorkFolder"
} # End of IF ELSE
Write-Verbose "`$WorkFolder=`"$WorkFolder`""
} # End of Begin
PROCESS {
Write-Verbose "Processing..."
# Remove all folders with no links
$LoopCounter=0
do {
Write-Verbose "Loop number $LoopCounter of $Looptimes"
$EmptyFolders = Get-ChildItem $WorkFolder -Directory -Recurse -Force -Exclude $KeepFolders | Where-Object { (Get-ChildItem $_.fullName).count -eq 0 } | Select-Object -ExpandProperty FullName
$EmptyFolders | ForEach-Object { Write-Verbose "Removing `"$_`"" }
$EmptyFolders | ForEach-Object { Remove-Item "$_" -Recurse -Force -ErrorAction Continue }
$LoopCounter=$LoopCounter+1
} while ($EmptyFolders.count -gt 0 -and $LoopCounter -le $Looptimes)
} # End of Process
} # End of Remove-EmptyFolders
Function Remove-FiletypeFromFolder {
<#
.SYNOPSIS
Removes files of defined type in a path
.DESCRIPTION
Will remove all files of defined file type in a path and subfolders,
could be used to remove all links from the common desktop.
Use the -whatif to see what files that will be removed.
.NOTES
davpe67 2017-02-25
davpe67 2017-05-11 Added support for exclution of files
.PARAMETER WorkFolder
Define a path where script should seach recursive for the folders to remove
For example: "C:\" or "$ENV:Temp"
.PARAMETER SearchStartMenu
Will Set Workfolder to "$ENV:Programdata\Microsoft\Windows\Start Menu"
.PARAMETER SearchPublicDesktop
Will Set Workfolder to "$ENV:PUBLIC\Desktop"
.PARAMETER KeepFiles
Define files that should not be deleted
.EXAMPLE
Remove-FiletypeFromFolder -SearchPublicDesktop -FileTypes ".lnk" -WhatIf
Remove-FiletypeFromFolder -SearchPublicDesktop -FileTypes ".lnk","*.tmp" -Verbose
#>
[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="WorkFolder")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="WorkFolder", Position=0, HelpMessage='Specify folder(s) serch in: ["C:\path\to\folders"]')]
[string]$WorkFolder,
[Parameter(Mandatory=$True, ParameterSetName="SearchStartMenu", Position=0)]
[switch]$SearchStartMenu,
[Parameter(Mandatory=$True, ParameterSetName="SearchPublicDesktop", Position=0)]
[switch]$SearchPublicDesktop,
[Parameter(Mandatory=$True, HelpMessage='Specify filetypes to search for: [".lnk",".tmp"]')]
[string[]]$FileTypes,
[string[]]$KeepFiles
)
BEGIN {
Write-Verbose "Begin..."
$IsAdmin=Test-Admin
Write-Verbose "`$IsAdmin is $IsAdmin"
IF ($SearchStartMenu) {
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:ProgramData\Microsoft\Windows\Start Menu")
} ELSEIF ($SearchPublicDesktop) {
IF ($IsAdmin -like $false) { Write-Error "Script need to run as administrator" ; Break }
$WorkFolder = Resolve-Path $("$ENV:PUBLIC\Desktop")
} ELSE {
$WorkFolder = Resolve-Path "$WorkFolder"
} # End of IF ELSE
Write-Verbose "`$WorkFolder=`"$WorkFolder`""
} # End of Begin
PROCESS {
Write-Verbose "Processing..."
# Search and remove
foreach ($FileType in $FileTypes) {
$FilesToRemove=Get-ChildItem $WorkFolder -Force -Exclude $KeepFiles | Resolve-Path
$FilesToRemove | ForEach-Object {
Write-Verbose "Removing `"$_`""
Remove-Item "$_" -Recurse -Force
}
} # End of foreach
} # End of Process
} # End of Remove-FiletypeFromFolder
Remove-FiletypeFromFolder -SearchPublicDesktop -FileTypes "*.lnk" -KeepFiles "Mount Onedrive for Business.lnk"
Remove-UnwantedFolders -SearchStartMenu -UnwantedFolders "Java","Microsoft Silverlight"
Remove-UnwantedFiles -SearchStartMenu -UnwantedFiles "Onedrive*.lnk"
Remove-UninstallLinks -SearchStartMenu
Remove-EmptyFolders -SearchStartMenu -KeepFolders "StartUp","Maintenance"
=== SCRIPT Cleanup-Desktop_and_StartMenu.ps1 ENDS ===
How it runs