Recreate Desktop and Start Menu shortcuts #ASRmageddon

It’s just a beautiful Friday 13th, due to a Windows Defender update that removed shortcuts from many machines with Attack Surface Reduction enabled for Macros. (Work-around “Setdefender ASR rule 92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b to audit only unit issue is resolved.”) This blog post describes how you can recreate the missing shortcuts and deploy this using Intune or run it manually on the affected system(s).

How does the script work?

The script has a list of program names and their locations in a variable. It checks to see if the program is available in the specified path and if the shortcut is present in C:\ProgramData\Microsoft\Windows\Start Menu\Programs (Or subfolders) or the user’s Desktop folder. (It will detect the standard desktop folder or the one in OneDrive is Known Folder Move is used) If not, it will create a shortcut for it. It will not create a Desktop shortcut if the icon is already on the All Users desktop.

Running the scripts

You can save the scripts to c:\temp and run them as Administrator or use it in an Intune script as System without any parameters for the Start Menu script or as User for the Desktop script. The output will look like this for the Start Menu script as an example: (I removed the Firefox, Outlook, and Cisco shortcuts in this case)

Specified folder Cisco Webex Meetings doesn't exist for the Cisco Webex Meetings shortcut, creating now...
Creating shortcut for Cisco Webex Meetings with path C:\Program Files (x86)\Webex\Webex\Applications\ptoneclk.exe in folder Cisco Webex Meetings...
Shortcut for Firefox not found with path C:\Program Files\Mozilla Firefox\firefox.exe, creating it now...
Shortcut for Outlook not found with path C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE, creating it now...
Shortcut for Firefox Private Browsing not found with path C:\Program Files\Mozilla Firefox\private_browsing.exe, creating it now...
Specified folder Cisco\Cisco AnyConnect Secure Mobility Client doesn't exist for the Cisco AnyConnect Secure Mobility Client shortcut, creating now...
Creating shortcut for Cisco AnyConnect Secure Mobility Client with path C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe in folder Cisco\Cisco AnyConnect Secure Mobility Client...

The scripts

Below are the scripts which were written in a short period, but they work 😉 Adjust the script to include or exclude more programs if needed, and the Desktop script has fewer shortcuts than the Start Menu script because I don’t like that many icons on my Desktop 😀

Note: Format the Create_Common_StartMenu_Shortcuts.ps1 correctly! The first value is the name of the shortcut, the second one is the path, and the third is either None (No subfolder) or the subfolder name, which can include multiple levels like the Cisco AnyConnect client shortcut.

Create_Common_Desktop_Shortcuts

$programs = @{
    "Adobe Acrobat"  = "C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
    "Excel"          = "C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
    "Firefox"        = "C:\Program Files\Mozilla Firefox\firefox.exe"
    "Google Chrome"  = "C:\Program Files\Google\Chrome\Application\chrome.exe"
    "Microsoft Edge" = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    "OneNote"        = "C:\Program Files\Microsoft Office\root\Office16\ONENOTE.EXE"
    "Outlook"        = "C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE"
    "Remote Desktop" = "C:\Program Files\Remote Desktop\msrdcw.exe"
    "TeamViewer"     = "C:\Program Files\TeamViewer\TeamViewer.exe"
    "Word"           = "C:\Program Files\Microsoft Office\root\Office16\WINWORD.exe"
}


#Check for shortcuts on user Desktop and in All Users desktop, if program is available and the shortcut isn't... Then recreate the shortcut on users desktop
#if not already present in ALl Users desktop folder
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$programs.GetEnumerator() | ForEach-Object {
    if (Test-Path -Path $_.Value) {
        if (-not (Test-Path -Path "$($DesktopPath)\$($_.Key).lnk") -and -not (Test-Path -Path "C:\Users\Public\Desktop\$($_.Key).lnk")) {
            write-host ("Shortcut for {0} not found in {1}, creating it now..." -f $_.Key, $_.Value)
            $shortcut = "$($DesktopPath)\$($_.Key).lnk"
            $target = $_.Value
            $description = $_.Key
            $workingdirectory = (Get-ChildItem $target).DirectoryName
            $WshShell = New-Object -ComObject WScript.Shell
            $Shortcut = $WshShell.CreateShortcut($shortcut)
            $Shortcut.TargetPath = $target
            $Shortcut.Description = $description
            $shortcut.WorkingDirectory = $workingdirectory
            $Shortcut.Save()
        }
    }
}

Create_Common_StartMenu_Shortcuts.ps1

$programs = @{
    "Access"                                  = @("C:\Program Files\Microsoft Office\root\Office16\MSACCESS.EXE", "None")
    "Adobe Acrobat"                           = @("C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe", "None")
    "Cisco Webex Meetings"                    = @("C:\Program Files (x86)\Webex\Webex\Applications\ptoneclk.exe", "Cisco Webex Meetings")
    "Cisco AnyConnect Secure Mobility Client" = @("C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe", "Cisco\Cisco AnyConnect Secure Mobility Client")
    "Excel"                                   = @("C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE", "None")
    "Firefox Private Browsing"                = @("C:\Program Files\Mozilla Firefox\private_browsing.exe", "None")
    "Firefox"                                 = @("C:\Program Files\Mozilla Firefox\firefox.exe", "None")
    "Google Chrome"                           = @("C:\Program Files\Google\Chrome\Application\chrome.exe", "None")
    "Microsoft Edge"                          = @("C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe", "None")
    "Notepad++"                               = @("C:\Program Files\Notepad++\notepad++.exe", "None")
    "OneNote"                                 = @("C:\Program Files\Microsoft Office\root\Office16\ONENOTE.EXE", "None")
    "Outlook"                                 = @("C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE", "None")
    "PowerPoint"                              = @("C:\Program Files\Microsoft Office\root\Office16\POWERPNT.EXE", "None")
    "Project"                                 = @("C:\Program Files\Microsoft Office\root\Office16\WINPROJ.EXE", "None")
    "Publisher"                               = @("C:\Program Files\Microsoft Office\root\Office16\MSPUB.EXE", "None")
    "Remote Desktop"                          = @("C:\Program Files\Remote Desktop\msrdcw.exe", "None")
    "TeamViewer"                              = @("C:\Program Files\TeamViewer\TeamViewer.exe", "None")
    "Visio"                                   = @("C:\Program Files\Microsoft Office\root\Office16\VISIO.EXE", "None")
    "Word"                                    = @("C:\Program Files\Microsoft Office\root\Office16\WINWORD.exe", "None")
}



#Check for shortcuts in Start Menu, if program is available and the shortcut isn't... Then recreate the shortcut
$programs.GetEnumerator() | ForEach-Object {
    if (Test-Path -Path $_.Value[0]) {
        #start with empty $create variable
        $create = $null

        #Shortcut variables for root of Start Menu folder
        if ($_.Value[1] -eq 'None') {
            if (-not (Test-Path -Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Key).lnk")) {
                write-host ("Shortcut for {0} not found with path {1}, creating it now..." -f $_.Key, $_.Value[0])
                $create = "Yes"
                $shortcut = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Key).lnk"
                $target = $_.Value[0]                
            }
        }

        #Shortcut variables for subfolder(s) inside the Start Menu folder
        if ($_.Value[1] -ne 'None') {
            if (-not (Test-Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Value[1])\$($_.Key).lnk")) {
                if (-not (Test-Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Value[1])")) {
                    write-host ("Specified folder {0} doesn't exist for the {1} shortcut, creating now..." -f $_.Value[1], $_.Key)
                    New-Item -ItemType Directory -Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Value[1])" -Force | Out-Null
                    write-host ("Creating shortcut for {0} with path {1} in folder {2}..." -f $_.Key, $_.Value[0], $_.Value[1])
                }
                else {
                    write-host ("Shortcut for {0} not found with path {1} in existing folder {2}, creating it now..." -f $_.Key, $_.Value[0], $_.Value[1])
                }
                $create = "Yes"
                $shortcut = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\$($_.Value[1])\$($_.Key).lnk"
                $target = $_.Value[0]                
            }
        }

        #If $create is Yes, set Shortcut variables and create shortcut
        if ($create -eq 'Yes') {     
            $description = $_.Key
            $workingdirectory = (Get-ChildItem $target).DirectoryName
            $WshShell = New-Object -ComObject WScript.Shell
            $Shortcut = $WshShell.CreateShortcut($shortcut)
            $Shortcut.TargetPath = "$target"
            $Shortcut.Description = $description
            $shortcut.WorkingDirectory = $workingdirectory
            $Shortcut.Save()
        }
    }
}

Download the script(s) from GitHub here

25 thoughts on “Recreate Desktop and Start Menu shortcuts #ASRmageddon

    • It recreates shortcut in the root of the Start Menu and only the ones that you specify in the programs variable. What are the locations of those? (This was a quick one to get our customers and colleagues up and running)

  1. Great script. May also need to check for application locations in the Program Files (x86) directory. For users with OneDrive backing up the desktop, some personal files may be recovered from the OD Recycle Bin

  2. Pingback: PowerShell is fun :) Recreating Start Menu Shortcuts #ASRmageddon | hoolus.in – hoolus.in

  3. Pingback: PowerShell is fun 🙂 Recreating Start Menu Shortcuts #ASRmageddon - newsnss.in

  4. I dont know if i am allowed to do this but for those that need it here is some additiona stuff added to this list

    “Access” = “C:\Program Files\Microsoft Office\root\Office16\MSACCESS.EXE”
    “Adobe Acrobat” = “C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe”
    “Acrobat Reader DC” = “C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe”
    “Excel” = “C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE”
    “Firefox Private Browsing” = “C:\Program Files\Mozilla Firefox\private_browsing.exe”
    “Firefox” = “C:\Program Files\Mozilla Firefox\firefox.exe”
    “Google Chrome” = “C:\Program Files\Google\Chrome\Application\chrome.exe”
    “Microsoft Edge” = “C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe”
    “Notepad++” = “C:\Program Files\Notepad++\notepad++.exe”
    “Notepad++” = “C:\Program Files (x86)\Notepad++\notepad++.exe”
    “OneNote” = “C:\Program Files\Microsoft Office\root\Office16\ONENOTE.EXE”
    “Outlook” = “C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE”
    “PowerPoint” = “C:\Program Files\Microsoft Office\root\Office16\POWERPNT.EXE”
    “Project” = “C:\Program Files\Microsoft Office\root\Office16\WINPROJ.EXE”
    “Publisher” = “C:\Program Files\Microsoft Office\root\Office16\MSPUB.EXE”
    “Remote Desktop” = “C:\Program Files\Remote Desktop\msrdcw.exe”
    “TeamViewer” = “C:\Program Files\TeamViewer\TeamViewer.exe”
    “Visio” = “C:\Program Files\Microsoft Office\root\Office16\VISIO.EXE”
    “Word” = “C:\Program Files\Microsoft Office\root\Office16\WINWORD.exe”
    “Cisco AnyConnect Secure Mobility Client” = “C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe”
    “Representative Console” = “C:\Program Files\Bomgar\Representative Console\support.iomartdesktop.com\bomgar-rep.exe”
    “FileZilla” = “C:\Program Files\FileZilla FTP Client\filezilla.exe”
    “FileZilla” = “C:\Program Files (x86)\FileZilla FTP Client\filezilla.exe”
    “Putty” = “C:\Program Files\PuTTY\putty.exe”
    “Putty” = “C:\Program Files (x86)\PuTTY\putty.exe”
    “PuttyGen” = “C:\Program Files\PuTTY\puttygen.exe”
    “MobaXterm” = “C:\Program Files (x86)\Mobatek\MobaXterm\MobaXterm.exe”
    “VMware Horizon View Client” = “C:\Program Files\VMware\VMware Horizon View Client\vmware-view.exe”
    “Zoom” = “C:\Program Files\Zoom\bin\Zoom.exe”
    “Microsoft Teams (Iomart)” = “C:\Users\$username\AppData\Local\Microsoft\Teams\current\Teams.exe”
    “Spotify” = “C:\Users\$username\AppData\Roaming\Spotify\Spotify.exe”
    “WinRAR” = “C:\Program Files (x86)\WinRAR\WinRAR.exe”
    “WinRAR” = “C:\Program Files\WinRAR\WinRAR.exe”
    “Adobe Photoshop” = “C:\Program Files\Adobe\Adobe Photoshop\Photoshop.exe”
    “Adobe Illustrator” = “C:\Program Files\Adobe\Adobe Illustrator\Illustrator.exe”
    “Adobe Premiere Pro” = “C:\Program Files\Adobe\Adobe Premiere Pro\Premiere.exe”
    “Adobe After Effects” = “C:\Program Files\Adobe\Adobe After Effects\AfterFX.exe”
    “Git” = “C:\Program Files\Git\git-cmd.exe”
    “Blender” = “C:\Program Files\Blender Foundation\Blender\blender.exe”
    “Unity” = “C:\Program Files\Unity\Editor\Unity.exe”
    “Java” = “C:\Program Files (x86)\Java\jre\bin\javaw.exe”
    “Java” = “C:\Program Files\Java\jre
    \bin\javaw.exe”
    “Visual Studio” = “C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe”
    “Visual Studio” = “C:\Program Files\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe”
    “Oracle Virtual Box” = “C:\Program Files\Oracle\VirtualBox\VirtualBox.exe”
    “Opera” = “C:\Program Files (x86)\Opera\launcher.exe”
    “7-Zip” = “C:\Program Files\7-Zip\7z.exe”

  5. I’m reluctant to run a script and not knowing exactly how it will change my system. Is there a way to run it in a mode where it will describe what changes would be mode. In MVS, we could run a fix with a CHECK option which would only report on the changes it would make and by reoving the CHECK option the change would actually be made.

    • I don’t have a -WhatIf parameter like you would in PowerShell functions. But as the post describes, it checks for the locations mentioned in the programs variable and if you have a shortcut for that in your Start Menu folder. If not, it will create it for you. Nothing destructive in this script 😊

      • Since it’s always my option whether or not to use the shortcut I agree that nothing destructive could happen. Thanks,

  6. Pingback: Recovering from the Defender ASR Bug MO497128 #ASRmageddon | I.T. in Legal

  7. Pingback: Intune Newsletter - 20th January 2023 - Andrew Taylor

  8. Pingback: Исправить удаленные ярлыки приложений из меню «Пуск», «Рабочий стол», «Панель задач» в Windows 11 или 10. - wexm

  9. Pingback: I.T. in Legal

  10. Pingback: PowerShell is fun :)2023 overview

Leave a Reply to Harm VeenstraCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.