1

我正在编写一个 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()
}
4

1 回答 1

1
  • 尽管Explorer可能会显示包含在Target:中的快捷方式(*.lnk文件)的字段,但以编程"..."方式访问等效字段通常不包含这些封闭的双引号。

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

    • 如所写(撇开双引号问题),您的代码将替换\\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 操作数)中,\实例不需要转义;在那里,只有$实例需要转义,因为$-prefixed 标记指的是正则表达式匹配的部分(有关更多信息,请参见我的这个答案)。

于 2017-06-07T00:43:52.230 回答