# encoding: ascii
# api: powershell
# title: New-Shortcut
# description: A script to create shortcuts … with support for short “special folder” names. (fixed) the [parameter named as [param bug
# version: 0.1
# type: function
# author: Joel Bennett
# license: CC0
# function: New-Shortcut
# x-poshcode-id: 1302
# x-archived: 2016-04-21T13:53:24
# x-published: 2010-09-03T10:49:00
#
#
#requires -version 2.0
function New-Shortcut {
<#
.SYNOPSIS
Creates a new shortcut (.lnk file) pointing at the specified file.
.DESCRIPTION
The New-Shortcut script creates a shortcut pointing at the target in the location you specify. You may specify the location as a folder path (which must exist), with a name for the new file (ending in .lnk), or you may specify one of the "SpecialFolder" names like "QuickLaunch" or "CommonDesktop" followed by the name.
If you specify the path for the link file without a .lnk extension, the path is assumed to be a folder.
.EXAMPLE
New-Shortcut C:\Windows\Notepad.exe
Will make a shortcut to notepad in the current folder named "Notepad.lnk"
.EXAMPLE
New-Shortcut C:\Windows\Notepad.exe QuickLaunch\Editor.lnk -Description "Run Notepad"
Will make a shortcut to notepad on the QuickLaunch bar with the name "Editor.lnk" and the tooltip "Run Notepad"
.EXAMPLE
New-Shortcut C:\Windows\Notepad.exe F:\User\
Will make a shortcut to notepad in the F:\User\ folder with the name "Notepad.lnk"
.NOTE
Partial dependency on Get-SpecialPath ( http://poshcode.org/858 )
#>
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=$true)]
[string]$TargetPath,
## Put the shortcut where you want: "Special Folder" names allowed!
[Parameter(Position=1,Mandatory=$true)]
[string]$LinkPath,
## Extra parameters for the shortcut
[string]$Arguments="",
[string]$WorkingDirectory="",
[string]$WindowStyle="Normal",
[string]$IconLocation="",
[string]$Hotkey="",
[string]$Description="",
[string]$Folder=""
)
# Values for Window Style:
# 1 - Normal -- Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position.
# 3 - Maximized -- Activates the window and displays it as a maximized window.
# 7 - Minimized -- Minimizes the window and activates the next top-level window.
if(!(Test-Path $TargetPath) -and !($TargetPath.Contains("://"))) {
Write-Error "TargetPath must be an existing file for the link to point at (or a URL)"
return
}
function New-ShortCutFile {
param(
[string]$TargetPath=$(throw "Please specify a TargetPath for link to point to"),
[string]$LinkPath=$(throw "must pass a path for the shortcut file"),
[string]$Arguments="",
[string]$WorkingDirectory=$(Split-Path $TargetPath -parent),
[string]$WindowStyle="Normal",
[string]$IconLocation="",
[string]$Hotkey="",
[string]$Description=$(Split-Path $TargetPath -Leaf)
)
if(-not ($TargetPath.Contains("://") -or (Test-Path (Split-Path (Resolve-Path $TargetPath) -parent)))) {
Throw "Cannot create Shortcut: Parent folder does not exist"
}
if(-not (Test-Path variable:\global:WshShell)) {
$global:WshShell = New-Object -com "WScript.Shell"
}
$Link = $global:WshShell.CreateShortcut($LinkPath)
$Link.TargetPath = $TargetPath
[IO.FileInfo]$LinkInfo = $LinkPath
## Properties for file shortcuts only
## If the $LinkPath ends in .url you can't set the arguments, icon, etc
## if you make the same shortcut with a .lnk extension
## you can still point it at a URL, but you can set hotkeys, icons, etc
if( $LinkInfo.Extension -ne ".url" ) {
$Link.WorkingDirectory = $WorkingDirectory
## Validate $WindowStyle
if($WindowStyle -is [string]) {
if( $WindowStyle -like "Normal" ) { $WindowStyle = 1 }
if( $WindowStyle -like "Maximized" ) { $WindowStyle = 3 }
if( $WindowStyle -like "Minimized" ) { $WindowStyle = 7 }
}
if( $WindowStyle -ne 1 -and $WindowStyle -ne 3 -and $WindowStyle -ne 7) { $WindowStyle = 1 }
$Link.WindowStyle = $WindowStyle
if($Hotkey.Length -gt 0 ) { $Link.HotKey = $Hotkey }
if($Arguments.Length -gt 0 ) { $Link.Arguments = $Arguments }
if($Description.Length -gt 0 ) { $Link.Description = $Description }
if($IconLocation.Length -gt 0 ) { $Link.IconLocation = $IconLocation }
}
$Link.Save()
Write-Output (get-item $LinkPath)
}
## If they didn't explicitly specify a folder
if($Folder.Length -eq 0) {
if($LinkPath.Length -gt 0) {
$path = Split-Path $LinkPath -parent
[IO.FileInfo]$LinkInfo = $LinkPath
if( $LinkInfo.Extension.Length -eq 0 ) {
$Folder = $LinkPath
} else {
# If the LinkPath is just a single word with no \ or extension...
if($path.Length -eq 0) {
$Folder = $Pwd
} else {
$Folder = $path
}
}
}
else
{ $Folder = $Pwd }
}
## If they specified a link path, check it for an extension
if($LinkPath.Length -gt 0) {
$LinkPath = Split-Path $LinkPath -leaf
[IO.FileInfo]$LinkInfo = $LinkPath
if( $LinkInfo.Extension.Length -eq 0 ) {
# If there's no extension, it must be a folder
$Folder = $LinkPath
$LinkPath = ""
}
}
## If there's no Link name, make one up based on the target
if($LinkPath.Length -eq 0) {
if($TargetPath.Contains("://")) {
$LinkPath = "$($TargetPath.split('/')[2]).url"
} else {
[IO.FileInfo]$LinkInfo = $TargetPath
$LinkPath = "$(([IO.FileInfo]$TargetPath).BaseName).lnk"
}
}
## If the folder doesn't actually exist, maybe it's special...
if( -not (Test-Path $Folder)) {
$morepath = "";
if( $Folder.Contains("\") ) {
$morepath = $Folder.SubString($Folder.IndexOf("\"))
$Folder = $Folder.SubString(0,$Folder.IndexOf("\"))
}
$Folder = Join-Path (Get-SpecialPath $Folder) $morepath
# or maybe they just screwed up
trap { throw new-object ArgumentException "Cannot create shortcut: parent folder does not exist" }
}
$LinkPath = (Join-Path $Folder $LinkPath)
New-ShortCutFile $TargetPath $LinkPath $Arguments $WorkingDirectory $WindowStyle $IconLocation $Hotkey $Description
}