我正在编写一个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 操作数)中,
实例不需要转义;在那里,只有
$
个实例需要转义,因为$
前缀标记引用正则表达式匹配的部分内容(有关更多信息,请参阅我的这个答案)。