Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Editing shortcut (.lnk) properties with Powershell

I've found a nasty VBS way to do this, but I'm looking for a native PoSh procedure to edit the properties of a .LNK file. The goal is to reach out to remote machines, duplicate an existing shortcut with most of the correct properties, and edit a couple of them.

If it would just be easier to write a new shortcut file, that would work too.

like image 781
Doug Chase Avatar asked Jan 27 '09 18:01

Doug Chase


People also ask

How do I edit .LNK files?

Just drag and drop them into the Notepad window. If you open them via the Open dialog, Notepad will open the exe file pointed to by the . lnk file.

How do I create a .LNK shortcut?

doc file in a folder and select Copy and then right-click the Desktop and selectPaste Shortcut, Windows creates a . lnk file that points to the . doc file.


4 Answers

Copy-Item $sourcepath $destination  ## Get the lnk we want to use as a template
$shell = New-Object -COM WScript.Shell
$shortcut = $shell.CreateShortcut($destination)  ## Open the lnk
$shortcut.TargetPath = "C:\path\to\new\exe.exe"  ## Make changes
$shortcut.Description = "Our new link"  ## This is the "Comment" field
$shortcut.Save()  ## Save

Found the VB version of the code here: http://www.tutorialized.com/view/tutorial/Extract-the-target-file-from-a-shortcut-file-.lnk/18349

like image 138
JasonMArcher Avatar answered Sep 26 '22 20:09

JasonMArcher


Below are the functions I use for dealing with .lnk files. They are modified versions of the functions found here as mentioned by @Nathan Hartley. I've improved Get-Shortcut to handle wildcards like * by passing strings to dir to expand them into sets of FileInfo objects.

function Get-Shortcut {
  param(
    $path = $null
  )

  $obj = New-Object -ComObject WScript.Shell

  if ($path -eq $null) {
    $pathUser = [System.Environment]::GetFolderPath('StartMenu')
    $pathCommon = $obj.SpecialFolders.Item('AllUsersStartMenu')
    $path = dir $pathUser, $pathCommon -Filter *.lnk -Recurse 
  }
  if ($path -is [string]) {
    $path = dir $path -Filter *.lnk
  }
  $path | ForEach-Object { 
    if ($_ -is [string]) {
      $_ = dir $_ -Filter *.lnk
    }
    if ($_) {
      $link = $obj.CreateShortcut($_.FullName)

      $info = @{}
      $info.Hotkey = $link.Hotkey
      $info.TargetPath = $link.TargetPath
      $info.LinkPath = $link.FullName
      $info.Arguments = $link.Arguments
      $info.Target = try {Split-Path $info.TargetPath -Leaf } catch { 'n/a'}
      $info.Link = try { Split-Path $info.LinkPath -Leaf } catch { 'n/a'}
      $info.WindowStyle = $link.WindowStyle
      $info.IconLocation = $link.IconLocation

      New-Object PSObject -Property $info
    }
  }
}

function Set-Shortcut {
  param(
  [Parameter(ValueFromPipelineByPropertyName=$true)]
  $LinkPath,
  $Hotkey,
  $IconLocation,
  $Arguments,
  $TargetPath
  )
  begin {
    $shell = New-Object -ComObject WScript.Shell
  }

  process {
    $link = $shell.CreateShortcut($LinkPath)

    $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator() |
      Where-Object { $_.key -ne 'LinkPath' } |
      ForEach-Object { $link.$($_.key) = $_.value }
    $link.Save()
  }
}
like image 33
Tim Lewis Avatar answered Sep 26 '22 20:09

Tim Lewis


A short addition to @JasonMArcher's answer..

To see available properties you can just run $shortcut after $shortcut = $shell.CreateShortcut($destination) in a PS. This will print all properties and their current values.

like image 22
schtiefel Avatar answered Sep 26 '22 20:09

schtiefel


I don't think there's a native way.

There is this DOS util: Shortcut.exe.

You still need to copy the util to the remote system, then possibly call it using WMI to make the changes you're looking for.

I'm thinking the easier way will be to overwrite and/or create a new file.

Do you have access to these systems via a remote share?

like image 24
Marco Shaw Avatar answered Sep 25 '22 20:09

Marco Shaw