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

Changing the target of multiple shortcuts with PowerShell

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

我目前所做的是不断将 LNK 的目标路径更改为 "Computer",然后使您无法编辑 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()
}
  • 尽管 Explorer 可能会显示包含在 "..." 中的快捷方式(*.lnk 文件)的 Target: 字段,以编程方式访问等效字段通常包含这些封闭的双引号。

  • -replace的第一个RHS操作数是一个regex(正则表达式),其中\是转义字符。因此,要替换 literal \,您必须 double 它。

    • 如所写(撇开双引号问题),您的代码会将 \server1 替换为 \\server2
  • 由于您正在无条件地重新创建快捷方式文件,因此不需要 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\'
    
  • 替换字符串(第二个RHS操作数)中,\个实例不需要转义;在那里,只有 $ 个实例需要转义,因为 $ 前缀标记指的是正则表达式匹配的部分内容(有关更多信息,请参见我的 )。