128

I want to create a shortcut with PowerShell for this executable:

C:\Program Files (x86)\ColorPix\ColorPix.exe

How can this be done?

TylerH
  • 20,799
  • 66
  • 75
  • 101
cethint
  • 2,231
  • 8
  • 28
  • 31

2 Answers2

188

I don't know any native cmdlet in powershell but you can use com object instead:

$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\ColorPix.lnk")
$Shortcut.TargetPath = "C:\Program Files (x86)\ColorPix\ColorPix.exe"
$Shortcut.Save()

you can create a powershell script save as set-shortcut.ps1 in your $pwd

param ( [string]$SourceExe, [string]$DestinationPath )

$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($DestinationPath)
$Shortcut.TargetPath = $SourceExe
$Shortcut.Save()

and call it like this

Set-ShortCut "C:\Program Files (x86)\ColorPix\ColorPix.exe" "$Home\Desktop\ColorPix.lnk"

If you want to pass arguments to the target exe, it can be done by:

#Set the additional parameters for the shortcut  
$Shortcut.Arguments = "/argument=value"  

before $Shortcut.Save().

For convenience, here is a modified version of set-shortcut.ps1. It accepts arguments as its second parameter.

param ( [string]$SourceExe, [string]$ArgumentsToSourceExe, [string]$DestinationPath )
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($DestinationPath)
$Shortcut.TargetPath = $SourceExe
$Shortcut.Arguments = $ArgumentsToSourceExe
$Shortcut.Save()
Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138
CB.
  • 58,865
  • 9
  • 159
  • 159
  • 1
    Very minor, but just for the sake of consistency I would have the syntax of `Set-ShortCut` cmdlet to be more like `MKLINK`, or `Set-Alias` where the alias or link comes as first argument and then the target. `param ( [string]$LinkPath, [string]$TargetPath )` – orad Jan 28 '14 at 18:51
  • One limitation of either the WshShell COM component or `cmd /c mklink` workarounds is a very limited character set for naming the .lnk file. A name containing a → will fail, for example. One way around this, if you need better character support, is to `[Web.HttpUtility]::UrlEncode()` (after `Add-Type -AN System.Web`) the filename while creating the .lnk file, then renaming it to the UrlDecoded name using Rename-Item. – brianary Nov 17 '15 at 07:06
  • 3
    When creating shortcut on *true* desktop (as opposed to assuming a hard-coded path which may or may not be true, a malpractice I have observed many times), the `SpecialFolders` method of a WScript object may come handy: `$WshShell.SpecialFolders("Desktop")` will yield you the true path to the desktop folder, which you may use subsequently when calling `CreateShortcut`. – Armen Michaeli Sep 28 '17 at 10:37
  • I used this method with `PS C:\Users\${myUser} $Shortcut = $WshShell.CreateShortcut("$C:\Users\${myUser}\home.lnk")`. It created a shortcut that can be seen from the windows explorer, but when I typed `cd home` in the PS itself I get an error `cd : Cannot find path 'C:\Users\carpb\home' because it does not exist.` – Ben Carp Apr 19 '18 at 06:50
  • +1 for amn's comment - a user can change the location of special folders like Desktop and Documents, so it's not necessarily going to be under the $Home folder. Another way to get the true Desktop location is `[Environment]::GetFolderPath("Desktop")` – Tim Goodman May 05 '21 at 20:10
  • This doesn't work with unicode characters in the path. `CreateShortcut` chokes on them, while `New-Item` doesn't. – hasufell Oct 13 '21 at 11:47
53

Beginning PowerShell 5.0 New-Item, Remove-Item, and Get-ChildItem have been enhanced to support creating and managing symbolic links. The ItemType parameter for New-Item accepts a new value, SymbolicLink. Now you can create symbolic links in a single line by running the New-Item cmdlet.

New-Item -ItemType SymbolicLink -Path "C:\temp" -Name "calc.lnk" -Value "c:\windows\system32\calc.exe"

Be Carefull a SymbolicLink is different from a Shortcut, shortcuts are just a file. They have a size (A small one, that just references where they point) and they require an application to support that filetype in order to be used. A symbolic link is filesystem level, and everything sees it as the original file. An application needs no special support to use a symbolic link.

Anyway if you want to create a Run As Administrator shortcut using Powershell you can use

$file="c:\temp\calc.lnk"
$bytes = [System.IO.File]::ReadAllBytes($file)
$bytes[0x15] = $bytes[0x15] -bor 0x20 #set byte 21 (0x15) bit 6 (0x20) ON (Use –bor to set RunAsAdministrator option and –bxor to unset)
[System.IO.File]::WriteAllBytes($file, $bytes)

If anybody want to change something else in a .LNK file you can refer to official Microsoft documentation.

JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • 4
    Is it possible to also set the icon for the shortcut? – orad Aug 10 '15 at 03:59
  • 17
    A symlink is very different from a shortcut, though. A symlink created using `New-Item` in `"${env:AppData}\Microsoft\Windows\SendTo"` won't show in the Explorer Send To menu, e.g., and doesn't allow customizing Shortcut properties like icon or working directory. – brianary Nov 16 '15 at 22:46
  • If I understand correctly, if you set a symbolic link, the shortcut can be used from any shell, and from any directory. It's somewhat like setting a system var. Is this correct? Can you also use it for directories? – Ben Carp Apr 19 '18 at 06:59
  • A symbolicLink is a special entry in the directory. So it can be used by any code. – JPBlanc Apr 19 '18 at 08:55
  • 4
    It surprising how PowerShell Dev's rather have us write contorted and incomprehensible code like shown above, instead of just implementing the 3 lines into a new parameter like this: `New-Item -ItemType SymbolicLink -RunAsAdmin ...`. – not2qubit Jan 09 '20 at 00:02
  • The `New-Item` cmdlet creates an empty file. I event copied/pasted the example and I get the same result. – Luke Aug 06 '20 at 19:55
  • 1
    @Luke, but of course, it's an explorer link, so when you double click on it, it starts calc.exe. So it does when you start it whith PowerShell (`& C:\temp\calc.lnk`). What do you expect ? – JPBlanc Aug 07 '20 at 12:08
  • Sorry! My bad :) You are right: a symbolic link is not a file but a junction in the MBR / GPT table. I was searching for a shortcut with more options like *RunAsAdministrator*, *WorkingDirectory*, *WindowsStyle*... For this usage, the WScript.Shell object is more appropriate. The fact that a shortcut and a symbolic link have the same extension is a bit misleading. Anyway, thanks for your answer and contribution :) – Luke Aug 07 '20 at 16:16
  • 1
    Adding to @brianary's comment, a symlink also won't show up in the Start Menu, Taskbar Search, or PowerToys Run. I was trying to automate the creation of shortcuts to a cloud-synced folder of portable apps that I use on multiple machines, with the goal of launching via Search and PowerToys Run. – Travis Troyer Apr 11 '22 at 17:13
  • 1
    @Luke, symbolic links have no designated filename extension - you're free to choose any filename, with or without an extension - though in the case of a creating a symlink to a _file_, it is advisable (but not technically necessary) to use the _same_ extension as the target file, though _omitting_ an extension may be the best choice when the target is an _executable_ if you want to _emulate_ a shortcut file. Choosing `.lnk` as the extension is best avoided, because it falsely suggests a shortcut file. JPBlanc, please consider using just `-Name calc` in lieu of `-Name calc.lnk` in your example. – mklement0 Aug 01 '23 at 13:07