• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Changing target path of windows shortcuts

#1
I have a user who created a lot of windows shortcuts and now the
target path has changed so we need to modify these with a script. And
its not as simple as replacing one server name with another. In fact,
all the shortcuts in question point to files on the user's C: drive.
Because of a change in an application, those files now have to be
stored in a different directory on the C: drive.

If it matters, old path is "c:\documents and settings\localservice
\application data". New path is "c:\documents and settings\username
\local settings\application data\."

Is there an easy way to do a recursive search for shortcut files and
modify the target path for each one if it has a specific string in
it?

Thanks,

Tim
 

My Computer

S

Shay Levi

#2
There is no specific command for it. You'll have to use wscript.shell com
object.
You can't *get* the lnk file target path, the trick is to *create* it again:

1. Create new shortcut for each shortcut you find
2. Get its targetpath for comparison
4. If your criteria matches, set the new target path
5. Save the lnk file.

$shell = new-object -com wscript.shell

get-childitem -filter *.lnk -recurse | foreach {
$lnk = $shell.CreateShortcut($_.fullname)
$oldpath= $lnk.TargetPath
if($oldpath -eq $yourCriteria"){
$lnk.TargetPath = "new_path"
$lnk.Save()
}
}



-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com



> I have a user who created a lot of windows shortcuts and now the
> target path has changed so we need to modify these with a script. And
> its not as simple as replacing one server name with another. In fact,
> all the shortcuts in question point to files on the user's C: drive.
> Because of a change in an application, those files now have to be
> stored in a different directory on the C: drive.
>
> If it matters, old path is "c:\documents and settings\localservice
> \application data". New path is "c:\documents and settings\username
> \local settings\application data\."
>
> Is there an easy way to do a recursive search for shortcut files and
> modify the target path for each one if it has a specific string in it?
>
> Thanks,
>
> Tim
>
 

My Computer

S

Shay Levi

#3
I missed the get-childitem's -path parameter
it should be:

get-childitem <path> -filter *.lnk -recurse ...


-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com



> There is no specific command for it. You'll have to use wscript.shell
> com
> object.
> You can't *get* the lnk file target path, the trick is to *create* it
> again:
> 1. Create new shortcut for each shortcut you find
> 2. Get its targetpath for comparison
> 4. If your criteria matches, set the new target path
> 5. Save the lnk file.
> $shell = new-object -com wscript.shell
>
> get-childitem -filter *.lnk -recurse | foreach {
> $lnk = $shell.CreateShortcut($_.fullname)
> $oldpath= $lnk.TargetPath
> if($oldpath -eq $yourCriteria"){
> $lnk.TargetPath = "new_path"
> $lnk.Save()
> }
> }
> -----
> Shay Levi
> $cript Fanatic
> http://scriptolog.blogspot.com

>> I have a user who created a lot of windows shortcuts and now the
>> target path has changed so we need to modify these with a script.
>> And its not as simple as replacing one server name with another. In
>> fact, all the shortcuts in question point to files on the user's C:
>> drive. Because of a change in an application, those files now have to
>> be stored in a different directory on the C: drive.
>>
>> If it matters, old path is "c:\documents and settings\localservice
>> \application data". New path is "c:\documents and settings\username
>> \local settings\application data\."
>>
>> Is there an easy way to do a recursive search for shortcut files and
>> modify the target path for each one if it has a specific string in
>> it?
>>
>> Thanks,
>>
>> Tim
>>
 

My Computer

#4
On Oct 31, 9:34 am, Shay Levi <[email protected]> wrote:

> There is no specific command for it. You'll have to use wscript.shell com
> object.
> You can't *get* the lnk file target path, the trick is to *create* it again:
>
> 1. Create new shortcut for each shortcut you find
> 2. Get its targetpath for comparison
> 4. If your criteria matches, set the new target path
> 5. Save the lnk file.
>
> $shell = new-object -com wscript.shell
>
> get-childitem -filter *.lnk -recurse | foreach {
> $lnk = $shell.CreateShortcut($_.fullname)
> $oldpath= $lnk.TargetPath
> if($oldpath -eq $yourCriteria"){
> $lnk.TargetPath = "new_path"
> $lnk.Save()
> }
>
> }
>
> -----
> Shay Levi
> $cript Fanatichttp://scriptolog.blogspot.com
>
Thanks Shay for the quick response!

You have me on the right path. I made a couple of changes to your
script and have listed it below. I don't want to change the entire
target path of the shortcut so I need to be able to replace a block of
text with another. Here is what I'm trying:

$psshell = new-object -com wscript.shell
$oldtarget = "C:\Documents and Settings\LocalService\Application Data
\ColligoOfflineClient\Storage3\Files\Sites"
$newtarget = "C:\Documents and Settings\username\Local Settings
\Application Data\ColligoOfflineClient\storage5\Files\Sites"

get-childitem c:\testshortcut -filter *.lnk -recurse | foreach {
$lnk = $psshell.CreateShortcut($_.fullname)
$oldpath = $lnk.TargetPath
if($oldpath -match "ColligoOfflineClient"){
$newpath = $oldpath -replace($oldtarget,$newtarget)
$lnk.TargetPath = $newpath
$lnk.Save()
}
}

When I run this, I'm getting this error:

Invalid regular expression pattern: C:\Documents and Settings
\LocalService\Application Data\ColligoOfflineClient\Storage3\Files
\Sites.
At H:\scripts\shortcut.ps1:10 char:47
+ $newpath = $oldpath -replace($oldtarget, <<<< $newtarget)

I'm sure this is something simple? What am I missing?
 

My Computer

S

Shay Levi

#5
This is because the backslash ("\") char is a regular expression meta character.
To avoid such issues you can use the [regex] static methods: escape & unescape

$psshell = new-object -com wscript.shell
$oldtarget = [regex]::escape("C:\Documents and Settings\LocalService\Application
Data\ColligoOfflineClient\Storage3\Files\Sites")
$newtarget = [regex]::escape("C:\Documents and Settings\username\Local Settings\Application
Data\ColligoOfflineClient\storage5\Files\Sites")

get-childitem c:\testshortcut -filter *.lnk -recurse | foreach {
$lnk = $psshell.CreateShortcut($_.fullname)
$oldpath = [regex]::escape($lnk.TargetPath)
if($oldpath -match "ColligoOfflineClient"){
$newpath = $oldpath -replace($oldtarget,$newtarget)
$lnk.TargetPath = [regex]::unescape($newpath)
$lnk.Save()
}
}


-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com



> On Oct 31, 9:34 am, Shay Levi <[email protected]> wrote:
>

>> There is no specific command for it. You'll have to use wscript.shell
>> com
>> object.
>> You can't *get* the lnk file target path, the trick is to *create* it
>> again:
>> 1. Create new shortcut for each shortcut you find
>> 2. Get its targetpath for comparison
>> 4. If your criteria matches, set the new target path
>> 5. Save the lnk file.
>> $shell = new-object -com wscript.shell
>>
>> get-childitem -filter *.lnk -recurse | foreach {
>> $lnk = $shell.CreateShortcut($_.fullname)
>> $oldpath= $lnk.TargetPath
>> if($oldpath -eq $yourCriteria"){
>> $lnk.TargetPath = "new_path"
>> $lnk.Save()
>> }
>> }
>>
>> -----
>> Shay Levi
>> $cript Fanatichttp://scriptolog.blogspot.com
> Thanks Shay for the quick response!
>
> You have me on the right path. I made a couple of changes to your
> script and have listed it below. I don't want to change the entire
> target path of the shortcut so I need to be able to replace a block of
> text with another. Here is what I'm trying:
>
> $psshell = new-object -com wscript.shell
> $oldtarget = "C:\Documents and Settings\LocalService\Application Data
> \ColligoOfflineClient\Storage3\Files\Sites"
> $newtarget = "C:\Documents and Settings\username\Local Settings
> \Application Data\ColligoOfflineClient\storage5\Files\Sites"
> get-childitem c:\testshortcut -filter *.lnk -recurse | foreach {
> $lnk = $psshell.CreateShortcut($_.fullname)
> $oldpath = $lnk.TargetPath
> if($oldpath -match "ColligoOfflineClient"){
> $newpath = $oldpath -replace($oldtarget,$newtarget)
> $lnk.TargetPath = $newpath
> $lnk.Save()
> }
> }
> When I run this, I'm getting this error:
>
> Invalid regular expression pattern: C:\Documents and Settings
> \LocalService\Application Data\ColligoOfflineClient\Storage3\Files
> \Sites.
> At H:\scripts\shortcut.ps1:10 char:47
> + $newpath = $oldpath -replace($oldtarget, <<<< $newtarget)
> I'm sure this is something simple? What am I missing?
>
 

My Computer

#6
Thanks again. That didn't work out like I had planned, but then I
discovered that there is a difference between -replace and .replace.
Here is the working script and it seems to be working well:

$psshell = new-object -com wscript.shell

get-childitem c:\testshortcut -filter *.lnk -recurse | foreach {
$lnk = $psshell.CreateShortcut($_.fullname)
$oldpath = $lnk.TargetPath
if($oldpath -match "ColligoOfflineClient"){
$newtarget = $oldpath.replace("C:\Documents and Settings
\LocalService\Application Data\ColligoOfflineClient\Storage3\Files
\Sites","C:\Documents and Settings\username\Local Settings\Application
Data\ColligoOfflineClient\storage5\Files\Sites")
$lnk.TargetPath = $newtarget
$lnk.Save()
}
}

I'm amazed on a daily basis by the power (and complexity) of
powershell.

On Oct 31, 2:03 pm, Shay Levi <[email protected]> wrote:

> This is because the backslash ("\") char is a regular expression meta character.
> To avoid such issues you can use the [regex] static methods: escape & unescape
>
> $psshell = new-object -com wscript.shell
> $oldtarget = [regex]::escape("C:\Documents and Settings\LocalService\Application
> Data\ColligoOfflineClient\Storage3\Files\Sites")
> $newtarget = [regex]::escape("C:\Documents and Settings\username\Local Settings\Application
> Data\ColligoOfflineClient\storage5\Files\Sites")
>
> get-childitem c:\testshortcut -filter *.lnk -recurse | foreach {
> $lnk = $psshell.CreateShortcut($_.fullname)
> $oldpath = [regex]::escape($lnk.TargetPath)
> if($oldpath -match "ColligoOfflineClient"){
> $newpath = $oldpath -replace($oldtarget,$newtarget)
> $lnk.TargetPath = [regex]::unescape($newpath)
> $lnk.Save()
> }
>
> }
>
> -----
> Shay Levi
> $cript Fanatichttp://scriptolog.blogspot.com
>

> > On Oct 31, 9:34 am, Shay Levi <[email protected]> wrote:
>
 

My Computer

sbarak

New Member
Posts
5
#7
I need to do something similar and need some assistance. A user has a lot of shortcuts on his desktop that point to c:\data\ and a bunch of subflders. I need to replace just the c:\data portion to \\server\data

From what I understand the final script should do just that but I do not know how to run this script in powershell. I installed powershell 1.0 for Vista x64 Edition (KB928439) but have no idea how to run the script.

Thanks for any help here.

Vista x64 Business machine

Steve Barak.
 

My Computer

S

Shay Levi

#8
Hi Steve,

Try this version:


dir "$env:USERPROFILE\desktop" -filter *.lnk -recurse | foreach {
$lnk = $shell.createShortcut($_.fullname)
$oldPath= $lnk.targetPath

if($oldpath -match "^c:\\data"){
$lnk.targetPath = $oldPath -replace "c:\\data","\\server"
$lnk.save()
}
}




---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

> I need to do something similar and need some assistance. A user has a
> lot of shortcuts on his desktop that point to c:\data\ and a bunch of
> subflders. I need to replace just the c:\data portion to \\server\data
>
> From what I understand the final script should do just that but I do
> not know how to run this script in powershell. I installed powershell
> 1.0 for Vista x64 Edition (KB928439) but have no idea how to run the
> script.
>
> Thanks for any help here.
>
> Vista x64 Business machine
>
> Steve Barak.
>
 

My Computer

S

Shay Levi

#10
Put the below in file and save it as a .ps1 file (powershell script file).



####### shortCut.ps1 ######

dir "$env:USERPROFILE\desktop" -filter *.lnk -recurse | foreach {
$lnk = $shell.createShortcut($_.fullname)
$oldPath= $lnk.targetPath

if($oldpath -match "^c:\\data"){
$lnk.targetPath = $oldPath -replace "c:\\data","\\server"
$lnk.save()
}
}


######################


For example, if you saved it to the d:\scripts folder then open PowerShell
console
, type the full path to the script and press enter to excute it:

D:\Scripts\shortCut.ps1





---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

> How do I actually run the script? Do I have to save it as a .vbs or
> something?
>
 

My Computer

S

Shay Levi

#11
Put the below in a file and save it as a .ps1 file (powershell script file).



####### shortCut.ps1 ######

dir "$env:USERPROFILE\desktop" -filter *.lnk -recurse | foreach {
$lnk = $shell.createShortcut($_.fullname)
$oldPath= $lnk.targetPath

if($oldpath -match "^c:\\data"){
$lnk.targetPath = $oldPath -replace "c:\\data","\\server"
$lnk.save()
}
}


######################


For example, if you saved it to the d:\scripts folder then open PowerShell
console
, type the full path to the script and press enter to excute it:

D:\Scripts\shortCut.ps1





---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

> How do I actually run the script? Do I have to save it as a .vbs or
> something?
>
 

My Computer

sbarak

New Member
Posts
5
#12
I run it and get this error

PS C:\Windows\System32> c:\temp\shortcut.ps1
You cannot call a method on a null-valued expression.
At C:\temp\shortcut.ps1:2 char:29
+ $lnk = $shell.createShortcut( <<<< $_.fullname)
You cannot call a method on a null-valued expression.
At C:\temp\shortcut.ps1:2 char:29
+ $lnk = $shell.createShortcut( <<<< $_.fullname)
You cannot call a method on a null-valued expression.
At C:\temp\shortcut.ps1:2 char:29
+ $lnk = $shell.createShortcut( <<<< $_.fullname)
You cannot call a method on a null-valued expression.
At C:\temp\shortcut.ps1:2 char:29
+ $lnk = $shell.createShortcut( <<<< $_.fullname)
You cannot call a method on a null-valued expression.
At C:\temp\shortcut.ps1:2 char:29
+ $lnk = $shell.createShortcut( <<<< $_.fullname)
 

My Computer

S

Shay Levi

#13
What happens if you run only this"

dir "$env:USERPROFILE\desktop" -filter *.lnk -recurse


---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

> I run it and get this error
>
> PS C:\Windows\System32> c:\temp\shortcut.ps1
> You cannot call a method on a null-valued expression.
> At C:\temp\shortcut.ps1:2 char:29
> + $lnk = $shell.createShortcut( <<<< $_.fullname)
> You cannot call a method on a null-valued expression.
> At C:\temp\shortcut.ps1:2 char:29
> + $lnk = $shell.createShortcut( <<<< $_.fullname)
> You cannot call a method on a null-valued expression.
> At C:\temp\shortcut.ps1:2 char:29
> + $lnk = $shell.createShortcut( <<<< $_.fullname)
> You cannot call a method on a null-valued expression.
> At C:\temp\shortcut.ps1:2 char:29
> + $lnk = $shell.createShortcut( <<<< $_.fullname)
> You cannot call a method on a null-valued expression.
> At C:\temp\shortcut.ps1:2 char:29
> + $lnk = $shell.createShortcut( <<<< $_.fullname)
 

My Computer

S

Shay Levi

#14
Reading through your post again...
You can remove the -recurse parameter.


---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

> What happens if you run only this"
>
> dir "$env:USERPROFILE\desktop" -filter *.lnk -recurse
>
> ---
> Shay Levi
> $cript Fanatic
> http://scriptolog.blogspot.com

>> I run it and get this error
>>
>> PS C:\Windows\System32> c:\temp\shortcut.ps1
>> You cannot call a method on a null-valued expression.
>> At C:\temp\shortcut.ps1:2 char:29
>> + $lnk = $shell.createShortcut( <<<< $_.fullname)
>> You cannot call a method on a null-valued expression.
>> At C:\temp\shortcut.ps1:2 char:29
>> + $lnk = $shell.createShortcut( <<<< $_.fullname)
>> You cannot call a method on a null-valued expression.
>> At C:\temp\shortcut.ps1:2 char:29
>> + $lnk = $shell.createShortcut( <<<< $_.fullname)
>> You cannot call a method on a null-valued expression.
>> At C:\temp\shortcut.ps1:2 char:29
>> + $lnk = $shell.createShortcut( <<<< $_.fullname)
>> You cannot call a method on a null-valued expression.
>> At C:\temp\shortcut.ps1:2 char:29
>> + $lnk = $shell.createShortcut( <<<< $_.fullname)
 

My Computer