Change shortcut targets in bulk?

15,149

Solution 1

I recently found myself with a similar issue, and decided to script modification of the links as originally requested. Perhaps someone else will find this useful. This is a PowerShell script based on a previously mentioned link, but has some improvements (only triggers on the leading path name, modifies the existing link instead of deleting/creating, has a dry-run mode, etc).

I'm not particularly knowledgeable when it comes to PowerShell, so I welcome any suggestions for improvement:

$oldPrefix = "\\OldServer\Archive\"
$newPrefix = "\\NewServer\Archive\"

$searchPath = "Z:\"

$dryRun = $TRUE

$shell = new-object -com wscript.shell

if ( $dryRun ) {
   write-host "Executing dry run" -foregroundcolor green -backgroundcolor black
} else {
   write-host "Executing real run" -foregroundcolor red -backgroundcolor black
}

dir $searchPath -filter *.lnk -recurse | foreach {
   $lnk = $shell.createShortcut( $_.fullname )
   $oldPath= $lnk.targetPath

   $lnkRegex = "^" + [regex]::escape( $oldPrefix ) 

   if ( $oldPath -match $lnkRegex ) {
      $newPath = $oldPath -replace $lnkRegex, $newPrefix

      write-host "Found: " + $_.fullname -foregroundcolor yellow -backgroundcolor black
      write-host " Replace: " + $oldPath
      write-host " With:    " + $newPath

      if ( !$dryRun ) {
         $lnk.targetPath = $newPath
         $lnk.Save()
      }
   }
}

Solution 2

Make

C:\Users\Herb\AppData\Local\Google

a directory junction which points to

C:\Program Files (x86)\Google

using Mklink, problem solved.

Solution 3

I have crazy network admins that always change the UNC path to my working directory. Using an example domain to illustrate the changes, I swear I've seen at least these four different UNCs to the same directory and files in the last 6 months:

\\contoso\Projects\rhinoexhibit\
\\contoso\Design\Projects\rhinoexhibit\
\\contoso.com\Design\Projects\rhinoexhibit\
\\city.contoso.com\Departments\Design\Projects\rhinoexhibit\
\\city.contoso.com\Departments\AlphaDesignGroup\Projects\rhinoexhibit\

I also use .LNK files that both link directly to a file in the Target box:

\\contoso\Projects\rhinoexhibit\rhinospecifications.pdf

and .LNK files that link to an application to open a file with specific parameters (here, I am using Foxit Reader to open a PDF file to a specific page) in the Target box:

"C:\Program Files (x86)\FOXIT READER\Foxit Reader.exe" /A page=37 "\\contoso\Projects\rhinoexhibit\rhinospecifications.pdf"

These directories are on corporate network shares, and I have no access to change the UNC to the shares or use any kind of redirection, so a modification of Terrence's answer worked best for me. As I was new to PowerShell, I had to figure out how to use that as well, so I'll give step-by-step instructions about how to use my modification of his excellent script:

  1. Using Notepad, paste the code below into a New Text Document. Save the document as Edit-LNK-files.ps1 into a directory that's easy to find and short to type (like C:\MyPowerShells)
  2. In Notepad, edit the $oldString parameter (line 4) to contain the string you want to find and the $newString parameter (line 7) to contain the string you want to replace it with. Edit the $searchPath parameter (line 10) to specify the directory your in which your .LNK files to edit reside. Alternatively, you can specify these variables later as you wish by running the script from the PowerShell command line and editing the parameters (i.e. & "C:\MyPowerShells\Edit-LNK-files.ps1" -oldString E:\ -newString D:\ -searchPath "C:\My LNKs\"
  3. Run Windows Powershell as administrator: Start > All Programs > Accessories > Windows PowerShell, right click Windows PowerShell and click Run As Administrator
  4. In Powershell, type set-executionpolicy remotesigned and press Enter
  5. Type Y and press Enter to allow PowerShell to run the script you just created in Notepad (you may want to change this back after you're done to keep your system secure).
  6. Type & "C:\MyPowerShells\Edit-LNK-files.ps1"
  7. Hit Enter to perform a "Dry Run" (Great idea Terrence! but I changed this to the default)
  8. Review the output from the "Dry Run" -- did the paths change appropriately? If not, change the $newString and $oldString variables appropriately, then repeat steps 6-8 to repeat the dry run. Othewise, continue to Step 9.
  9. If the dry run looks good, repeat step 6, but this time add the parameter -RealRun so it looks like & "C:\MyPowerShells\Edit-LNK-files.ps1" -RealRun. Now, when you hit Enter, it will actually change the .LNK files

Here's the edited script:

[CmdletBinding()]
Param(
    [Parameter(Mandatory=$False,Position=1)]
    [string] $oldString="\\contoso\Projects\rhinoexhibit\",

    [Parameter(Mandatory=$False,Position=2)]
    [string]$newString="\\city.contoso.com\Departments\AlphaDesignGroup\Projects\rhinoexhibit\",

    [Parameter(Mandatory=$False,Position=3)]
    [string]$searchPath="C:\My LNKs\",

    [switch]$RealRun
)

$shell = new-object -com wscript.shell
$filesFound= 0

if ( $RealRun ) {
   write-host "Executing real run" -foregroundcolor red -backgroundcolor black
} else {
   write-host "Executing dry run" -foregroundcolor green -backgroundcolor black
}

dir $searchPath -filter *.lnk -recurse | foreach {
   $lnk = $shell.createShortcut( $_.fullname )
   $oldPath= $lnk.targetPath
   $oldArgs= $lnk.Arguments


   $lnkRegex = ",*" + [regex]::escape( $oldString )

   if ( $oldPath -match $lnkRegex ) {
      $newPath = $oldPath -replace $lnkRegex, $newString

      write-host "Found: " $_.fullname -foregroundcolor yellow -backgroundcolor black
      write-host " Replace: " $oldPath
      write-host " With:    " $newPath
      $filesFound++

      if ( $RealRun ) {
         $lnk.targetPath = $newPath
         $lnk.Save()
      }
   }

   if ( $oldArgs -match $lnkRegex ) {
      $newArgs = $oldArgs -replace $lnkRegex, $newString

      write-host "Found:  " $_.fullname -foregroundcolor yellow -backgroundcolor black
      write-host "Target: " $oldPath -foregroundcolor yellow -backgroundcolor black
      write-host " Replace Args: " $oldArgs
      write-host " With Args:    " $newArgs
      $filesFound++

      if ( $RealRun ) {
         $lnk.Arguments = $newArgs
         $lnk.Save()
      }
   }
}

if ($filesFound -eq 0) {
    write-host "No LNK files found with " $oldString "in target or arguments" -foregroundcolor red -backgroundcolor black
}
else {
    if ($RealRun) {
        write-host $filesFound "files found and edited" -foregroundcolor red -backgroundcolor black
    }
    else {
        write-host $filesFound "files found" -foregroundcolor green -backgroundcolor black
    }
}

Running this script should successfully change .LNK shortuct files with the following in the Target: box

\\contoso\Projects\rhinoexhibit\rhinospecifications.pdf

to

\\city.contoso.com\Departments\AlphaDesignGroup\Projects\rhinoexhibit\rhinospecifications.pdf

and from

"C:\Program Files (x86)\FOXIT READER\Foxit Reader.exe" /A page=37 "\\contoso\Projects\rhinoexhibit\rhinospecifications.pdf"

to

"C:\Program Files (x86)\FOXIT READER\Foxit Reader.exe" /A page=37 "\\city.contoso.com\Departments\AlphaDesignGroup\Projects\rhinoexhibit\rhinospecifications.pdf"

Solution 4

For those who feel more comfortable with an .exe tool instead of a script:

'Shortcuts Search And Replace' can replace all faulty shortcut-paths in a specified folder with one click.

Solution 5

I have made a AutoIt script for this:

Will replace all substrings specified with your specified desired replacement substring in all Target and WorkingDir fields of LNKs specified in a directory you specify. Also has a simulated mode to show you the effects of your replacement in a text file so you can see what is found and what LNK target substring matches you have.

https://www.autoitscript.com/forum/topic/181812-lnksubstringreplacer-link-lnk-path-substring-replacer/ - LNKSubstringReplacer Link LNK Path Substring Replacer

Share:
15,149

Related videos on Youtube

Herb Caudill
Author by

Herb Caudill

Updated on September 18, 2022

Comments

  • Herb Caudill
    Herb Caudill over 1 year

    I have hundreds of shortcuts to websites where the target looks like this:

    C:\Users\Herb\AppData\Local\Google\Chrome\Application\chrome.exe www.somesite.com/foo

    I just upgraded to Windows 8, and the Chrome executable is now stored in Program Files; so to get these shortcuts to work, I have to change them to this:

    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" www.somesite.com/foo

    Is there any way I can automate this change? I'm a programmer but haven't done much with Windows scripting.

    • Admin
      Admin over 11 years
      Probably too late but making them simple links/URL files to "http://www.somesite.com/foo" would work much better in the future.
    • Admin
      Admin over 11 years
      Are these *.url files?
    • Admin
      Admin over 11 years
      No, they're not *.url files. These are shortcuts that are invoked via the Run box using the technique described here bit.ly/WVE6hs . For some reason *.url files aren't picked up - you have to make a shortcut to a browser with the URL as a command-line parameter.
  • Herb Caudill
    Herb Caudill over 11 years
    Perfect, thanks! Here's the command I ended up using: mklink /D "C:\Users\Herb\AppData\Local\Google\Chrome\Application" "C:\Program Files (x86)\Google\Chrome\Application" - works like a charm.
  • Tamara Wijsman
    Tamara Wijsman over 11 years
    @HerbCaudill: Ah, a symlink, if that ever doesn't work try /J instead as that is more low-level.
  • Herb Caudill
    Herb Caudill over 9 years
    This works like a charm.
  • MikeH
    MikeH over 7 years
    Just what I needed. I did tweak it to update the working directory (aka "Start In"). If anyone else needs to do that as well, just modify "lnk.WorkingDirectory"
  • Manuel Rozier
    Manuel Rozier about 2 years
    Easiest solution for those who don't have admin rights. 64bits version is available here : jacquelin.potier.free.fr/ShortcutsSearchAndReplace