使用 PowerShell 更改多个快捷方式的目标



我正在编写一个PowerShell脚本来搜索C:\Users 目录,并将所有包含\server1的lnk文件更改为\server2,但保留链接的其余部分。

到目前为止,我所拥有的将继续将LNK的目标路径更改为"计算机",然后禁止您编辑LNK。谁能解释为什么这样做?

法典:

#Folder to search
$favourites_path = "C:Users" 
#Backup C:Users DISABLED by Default "
# Copy-Item $favourites_path "$favourites_path`1" -Recurse
$favourites = Get-ChildItem $favourites_path -Recurse -Filter *.lnk
foreach ($favourite in $favourites) {
$shortcut = (New-Object -ComObject 
'WScript.Shell').CreateShortCut($favourite.FullName)
$newpath=switch -Wildcard ($shortcut.TargetPath)
{
'"\server1*"'           { $_ -replace '"\server1"', '"\server2"'}
}
$shortcut.TargetPath=$newpath
$shortcut.Save()
}
  • 即使资源管理器可能会显示包含在"..."中的快捷方式(*.lnk文件)的Target:字段,以编程方式访问等效字段通常不包含这些双引号。

  • -replace的第一个RHS操作数是一个正则表达式(正则表达式),其中是转义字符。因此,要替换文字,必须将其加倍

    • 如前所述(撇开双引号问题不谈),您的代码将用\server2替换\server1
  • 由于您无条件地重新创建快捷方式文件,因此不需要switch语句,因为如果正则表达式与任何内容不匹配,-replace相当于无操作。

    • 您的switch语句只有 1 个分支,没有默认分支,因此任何不以\server1开头的目标(将双引号放在一边)都设置为$null

以下代码解决了这些问题:

#Folder to search
$favourites_path = "C:Users" 
Get-ChildItem $favourites_path -Recurse -Filter *.lnk | ForEach-Object {
$shortcut = (New-Object -ComObject 'WScript.Shell').CreateShortCut($favourite.FullName)
$shortcut.Target = $shortcut.Target -replace '^\\server1\', '\server2'
$shortcut.Save()
}
  • 请注意正则表达式如何使用^锚定到字符串的开头,确保文本\server1仅与字符串开头匹配。

  • 手动将实例加倍的替代方法是使用[regex]::Escape(),它转义输入字符串中的任何正则表达式元字符,以确保将其视为文字:

    $shortcut.Target = $shortcut.Target -replace ('^' + [regex]::Escape('\server1')), '\server2'
    
  • 替换字符串(第 2 个 RHS 操作数)中,实例不需要转义;在那里,只有$个实例需要转义,因为$前缀标记引用正则表达式匹配的部分内容(有关更多信息,请参阅我的这个答案)。

最新更新