Bulk Change LNK (Shortcut) Files

I was transferring department folders and files from one server to another. I used Robocopy and FreeFileSync to get the job done. Just for my own future reference, this was the Robocopy command I used:

robocopy \\oldserver\d$\Data\SHARED \\newserver\SHAREDV11 /MIR /COPY:DATSO /DCOPY:DAT /R:10 /W:30 /MT:24 /LOG:"D:\transfer\SHAREDV11.log" /TEE

I fired this off once, then used FreeFileSync to sync any delta changes afterward. This is pretty boring and common, server administrators have been performing this ritual for many years. However, I’ve been in desktop engineering for the last 16 years and only 2 years in server administration, so it was “new to me”.

Weeks later, after I was done, I got an e-mail about invalid shortcuts. In order to save disk space, the users created shortcuts to other folders. These shortcuts of course included the name of the old server. Off to Google we go! One solution I found was this, but didn’t end up using it (our AV software kept deleting it for some reason) http://jacquelin.potier.free.fr/ShortcutsSearchAndReplace/.

Ultimately, I used this code from poster Terrance @ https://superuser.com/questions/495491/change-shortcut-targets-in-bulk

$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()
      }
   }
}

This works great, it even has a “dryrun” option so you can see what it’s going to do before it actually does anything. The only thing to watch out for is if the shortcut was already invalid to begin with. About 1/3 of the shortcuts the user had were already invalid on the old server due to them shifting and renaming various folders and not updating the shortcuts.

  • Soli Deo Gloria