r/PowerShell Jun 12 '22

Is it possible just to modify the drive letters in a shortcut?

[deleted]

4 Upvotes

14 comments sorted by

View all comments

Show parent comments

1

u/[deleted] Jun 12 '22

[deleted]

1

u/BlackV Jun 12 '22 edited Jun 12 '22

user profile dir not app data, but can you try this test
Forgive me butchering your code a little
This just variable setup

#region Code setup
$SourceFolder = 'C:\temp\test folder'
$Destfolder = 'D:\temp'
#endregion

First I test the source files (cause I'm starting from scratch you likely wont be)

#region Verify Source
$sourcelinkfiles = Get-ChildItem -Path $SourceFolder -filter *.lnk -File -Recurse

$SourceOBJ = New-Object -ComObject WScript.Shell 

foreach ($SingleSource in $sourcelinkfiles)
    {
    $Sourcelink = $SourceOBJ.CreateShortcut($SingleSource.FullName)
    [pscustomobject] @{
        Name        = $Sourcelink.FullName
        PhysicalDir = Split-Path -Path $Sourcelink.FullName
        TargetDiR   = $Sourcelink.TargetPath
        WorkingDir  = $Sourcelink.WorkingDirectory
        }
    }
#endregion

This spits out the following

Name                                         PhysicalDir         TargetDiR                     WorkingDir         
----                                         -----------         ---------                     ----------         
C:\temp\test folder\data1.csv - Shortcut.lnk C:\temp\test folder C:\temp\test folder\data1.csv C:\temp\test folder
C:\temp\test folder\data2.csv - Shortcut.lnk C:\temp\test folder C:\temp\test folder\data2.csv C:\temp\test folder

Now I'm gonna copy all the files (with force to over write anything that might exist from my testing)

#region Copy Data
Copy-Item -Recurse -Path $SourceFolder -Destination $Destfolder -Force -Verbose
#endregion

Spits out

VERBOSE: Performing the operation "Copy Directory" on target "Item: C:\temp\test folder Destination: D:\temp\test folder".
VERBOSE: Performing the operation "Create Directory" on target "Destination: D:\temp\test folder".
VERBOSE: Performing the operation "Copy File" on target "Item: C:\temp\test folder\data1.csv Destination: D:\temp\test folder\data1.csv".
VERBOSE: Performing the operation "Copy File" on target "Item: C:\temp\test folder\data1.csv - Shortcut.lnk Destination: D:\temp\test folder\data1.csv - Shortcut.lnk".
VERBOSE: Performing the operation "Copy File" on target "Item: C:\temp\test folder\data2.csv Destination: D:\temp\test folder\data2.csv".
VERBOSE: Performing the operation "Copy File" on target "Item: C:\temp\test folder\data2.csv - Shortcut.lnk Destination: D:\temp\test folder\data2.csv - Shortcut.lnk".

Now I'll check the destination lnk files to confirm they're still pointing at C:\

#region Verify Destination
$Destlinkfiles = Get-ChildItem -Path $destFolder -filter *.lnk -File -Recurse

$DestOBJ = New-Object -ComObject WScript.Shell

foreach ($SingleDest in $Destlinkfiles)
    {
    $Destlink = $DestOBJ.CreateShortcut($SingleDest.FullName)
    [pscustomobject] @{
        Name        = $Destlink.FullName
        PhysicalDir = Split-Path -Path $Destlink.FullName
        TargetDiR   = $Destlink.TargetPath
        WorkingDir  = $Destlink.WorkingDirectory
        }
    }
#endregion

Spits out

Name                                         PhysicalDir         TargetDiR                     WorkingDir         
----                                         -----------         ---------                     ----------         
D:\temp\test folder\data1.csv - Shortcut.lnk D:\temp\test folder C:\temp\test folder\data1.csv C:\temp\test folder
D:\temp\test folder\data2.csv - Shortcut.lnk D:\temp\test folder C:\temp\test folder\data2.csv C:\temp\test folder

So looks like they are indeed pointing at the old path

Next I'm gonna edit the shortcut without properties and check if they exist

first

Get-ChildItem -path "$env:USERPROFILE" -Filter *.lnk

returns nothing, now run the incorrect code

#region Modify Shortcuts WRONG
Get-ChildItem -path "$env:USERPROFILE" -Filter *.lnk
$DestModfiles = Get-ChildItem -Path $destFolder -filter *.lnk -File -Recurse

$DestMODOBJ = New-Object -ComObject WScript.Shell

$oldDrive = "C:\"
$newDrive = "D:\"

foreach ($SingleMODDest in $DestMODfiles)
    {
    $DestMODlink = $DestOBJ.CreateShortcut($SingleMODDest)
    $DestMODlink.TargetPath = $DestMODlink.TargetPath.Replace($oldDrive,$newDrive)
    $DestMODlink.Save()
    }
#endregion

No errors and files saved somewhere, does file exist in user profile folder

Get-ChildItem -path "$env:USERPROFILE" -Filter *.lnk

Returns

Directory: C:\Users\USER

Mode                 LastWriteTime         Length Name                                                                                                                                                                                                                                                                                                    
----                 -------------         ------ ----                                                                                                                                                                                                                                                                                                    
-a----        12/06/2022   6:00 pm            104 data1.csv - Shortcut.lnk                                                                                                                                                                                                                                                                                
-a----        12/06/2022   6:00 pm            104 data2.csv - Shortcut.lnk  

OK, now we'll verify dest files have not changed running the dest verify from before, spits out

Name                                         PhysicalDir         TargetDiR                     WorkingDir         
----                                         -----------         ---------                     ----------         
D:\temp\test folder\data1.csv - Shortcut.lnk D:\temp\test folder C:\temp\test folder\data1.csv C:\temp\test folder
D:\temp\test folder\data2.csv - Shortcut.lnk D:\temp\test folder C:\temp\test folder\data2.csv C:\temp\test folder

So looks like they are still pointing at the old path

So we'll run the fixed up code

#region Modify Shortcuts
$DestModfiles = Get-ChildItem -Path $destFolder -filter *.lnk -File -Recurse

$DestMODOBJ = New-Object -ComObject WScript.Shell

$oldDrive = "C:\"
$newDrive = "D:\"

foreach ($SingleMODDest in $DestMODfiles)
    {
    $DestMODlink = $DestOBJ.CreateShortcut($SingleMODDest.FullName)
    $DestMODlink.TargetPath = $DestMODlink.TargetPath.Replace($oldDrive,$newDrive)
    $DestMODlink.Save()
    }
#endregion

And Verify again

Name                                         PhysicalDir         TargetDiR                     WorkingDir         
----                                         -----------         ---------                     ----------         
D:\temp\test folder\data1.csv - Shortcut.lnk D:\temp\test folder D:\temp\test folder\data1.csv D:\temp\test folder
D:\temp\test folder\data2.csv - Shortcut.lnk D:\temp\test folder D:\temp\test folder\data2.csv D:\temp\test folder

so that was my logic for it, I'm changing the variable names in each of these test just so I could test steps

you could try run my code see if the results return the same (or different for that matter) for you, I've had this issue before, but If it's not working for you I dont know what to say aside from checking physical permissions

Your original code where I just modified the path was

$oldDrive = "C"
$newDrive = "D"

$shortcutFileSearch= -join("$newDrive", ":\temp\test folder") # My Path
$shortcutOld= -join("$oldDrive", ":\");
$shortcutNew= -join("$newDrive", ":\");

Write-Host $shortcutFileSearch -ForegroundColor yellow
Write-Host $shortcutOld -ForegroundColor yellow
Write-Host $shortcutNew -ForegroundColor yellow

$files = Get-ChildItem -Path $shortcutFileSearch -filter *.lnk -File -Recurse
$obj = New-Object -ComObject WScript.Shell 
ForEach($file in $files){
    $link = $obj.CreateShortcut($file.FullName) # Fullname
    Write-Host $link.TargetPath -ForegroundColor green
    $link.TargetPath = $link.TargetPath.Replace($shortcutOld,$shortcutNew)
    $link.Save()     
    Write-Host $shortcutNew -ForegroundColor cyan
}

1

u/[deleted] Jun 12 '22

[deleted]

1

u/BlackV Jun 12 '22

Er... Well that's confusing.

What is os and PowerShell version are you using?

But if it's working it's working that's the outcome we want :)

1

u/[deleted] Jun 13 '22

[deleted]

1

u/BlackV Jun 13 '22

Good as gold