Create a Shortcut and Cusomize the Icon in Windows from the CLI
Creating a shortcut with Windows CLI is as simple as envoking the mklink command with a link name and target.
mklink "C:\users\public\desktop\Logoff" "C:\windows\system32\logoff.exe"
The result works, but is not pretty. It also doesn’t give the user any visual clue as to what this shortcut does, even if the name should give it away.
This looks better, but it takes a lot of clicks in the GUI to get it done:
Scripting this will allow deployment to a lot of PCs much faster. There isn’t really a good way to do this in Windows CLI or PowerShell. VBScript can do what we need with the CreateShortcut method and, thankfully, we can envoke VBScript in PowerShell using WScript.Shell. Use the following in a PowerShell prompt or script.
First, we need to set some variables. This will set the location where we want the shortcut and the dll file that contains the standard Windows icons:
$ShortcutPath = "C:\users\public\desktop\Logoff.lnk"
$IconLocation = "C:\windows\System32\SHELL32.dll"
There are many icons in the SHELL32.dll and we need to specify the one we want with an index number.
$IconArrayIndex = 27
27 happens to be the index of the red power button icon.
There are over 300 icons in the SHELL32.dll file in Windows 10! Here are the first few.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
You can see the rest by right clicking a shortcut, select properties, shortcut, change icon.
The icons are numbers starting at 0 from the top right corner and going down each column. Like this:
0 | 4 | 8 | 12 | 16 | 20 | 24 |
1 | 5 | 9 | 13 | 17 | 21 | 25 |
2 | 6 | 10 | 14 | 18 | 22 | 26 |
3 | 7 | 11 | 15 | 19 | 23 | 27 |
You can also extract the SHELL32.dll file with 7zip. Find the “ICON” folder in the resulting folders after extraction. The icon files are not named in a very useful way, but all most the icons are there as .ico files. See imageres.dll also in C:\Windows\System32 for more icons.
SHELL32.dll and imageres.dll are just the Windows icons. Other applications include icons that you can access the same way if you know where they are stored. Google Chrome for example stores icons here: %ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe.
Back to our script. Set a $Shell variable to envoke the WScript.Shell.
$Shell = New-Object -ComObject ("WScript.Shell")
The next command creates the shortcut without a target. It seems odd to create the shortcut without specifying the target first, but sure, whatever.
$Shortcut = $Shell.CreateShortcut($ShortcutPath)
Now set your target path.
$Shortcut.TargetPath = "C:\windows\System32\logoff.exe"
And finally, set the icon using the variables we set eariler and save.
$Shortcut.IconLocation = "$IconLocation, $IconArrayIndex"
$Shortcut.Save()
That’s it. A newly minted shortcut is now on the public desktop.
Here is the resulting script that will create a shortcut for logoff.exe and set the icon:
$ShortcutPath = "C:\users\public\desktop\Logoff.lnk"
$IconLocation = "C:\windows\System32\SHELL32.dll"
$IconArrayIndex = 27
$Shell = New-Object -ComObject ("WScript.Shell")
$Shortcut = $Shell.CreateShortcut($ShortcutPath)
$Shortcut.TargetPath = "C:\windows\System32\logoff.exe"
$Shortcut.IconLocation = "$IconLocation, $IconArrayIndex"
$Shortcut.Save()
Further Reading:
https://ss64.com/nt/mklink.html
https://stackoverflow.com/questions/8435/how-do-you-get-the-icons-out-of-shell32-dll