Search code examples
powershellsymlinkshortcut

Replace shortcut with relative symlink in nested folders


I need help to convert all the Windows shortcut to relative soft links (symlinks) with PowerShell. All the original files (targets of the shortcuts) are on a single folder, and inside it there is another folder with files, shortcuts and other folders (that can contain other files, shortcuts and folders).

What I'm looking is thus make this command for every shortcut (with eventually more ../):

cmd /c 'mklink "path/shortcut.txt" "../file.txt"' && del "path/shortcut.txt.lnk"

With this code I can get the absolute path of the target of the shortcut:

dir * -Include *.lnk -Recurse | ForEach-Object {
  $sh = New-Object -ComObject WScript.Shell
  $fullpath = $sh.CreateShortcut($_.FullName).TargetPath
}

Any help? How can I make it find the path and the number of ../ needed?


Solution

  • I think I found how to do it. This is the script:

    $obj = New-Object -ComObject WScript.Shell;
    dir * -Include *.lnk -Recurse | ForEach-Object {
        $file = $obj.CreateShortcut($_.FullName).TargetPath -Replace '.*\\'
        $name = $(Resolve-Path -Relative $_) -Replace '^\.\\' -Replace "\.lnk$"
        $rel = '';
        for ($i=0; $i -le ([regex]::Matches($name, '\\' )).count; $i++) {
            $rel = $rel + '..\\'
        }
        cmd /c mklink "$name" "$($rel + $file)"
        del "$($name + '.lnk')"
    }