Powershell:编辑我所有以 X:\ 开头的快捷方式的驱动器号

Powershell: Edit the drive letter of all my shortcuts that begin with X:\

我遇到这样一种情况,位于 %AppData%\Microsoft\Windows\Start Menu\Programs 文件夹和子文件夹中的快捷方式文件中的所有路径都指向一个不正确的盘符。这包括 Target: 值、Start In: 值以及图标文件的所有路径。我想将它们全部从 X:\ 更改为 C:\

有几个正确指向 C:\,但只有少数几个。

这是我使用的代码。我可以更改 TargetPath 但不能更改 WorkingDirectory 值。我试过删除第 20 行的注释,但这会产生关于 $null 值表达式的错误。我也试过将 TargetPath 的位复制到 WorkingDirectory 但它没有改变:

$folder = "C:\Temp\Shortcuts" 
[string]$from = "X:\" 
[string]$to = "C:\" 
$list = Get-ChildItem -Path $folder -Recurse  | Where-Object { $_.Attributes -ne "Directory"} | select -ExpandProperty FullName 
$obj = New-Object -ComObject WScript.Shell 

ForEach($lnk in $list) 
{ 
    $obj = New-Object -ComObject WScript.Shell 
    $link = $obj.CreateShortcut($lnk) 
    [string]$path = $link.TargetPath  
    [string]$path = [string]$path.Replace($from.tostring(),$to.ToString()) 
#   [string]$path = $link.WorkingDirectory
#   [string]$path = [string]$path.Replace($from.tostring(),$to.ToString()) 

    #If you need workingdirectory change please uncomment the below line. 
    #$link.WorkingDirectory = [string]$WorkingDirectory.Replace($from.tostring(),$to.ToString()) 
    $link.TargetPath = [string]$path 
    $link.Save() 
}

您发布的代码中的第 20 行是结尾 },但我假设这...

#$link.WorkingDirectory = [string]$WorkingDirectory.Replace($from.tostring(),$to.ToString()) 

...是真正的第 20 行。该错误的原因是因为您试图在 $WorkingDirectory 而不是 $link.WorkingDirectory 上调用 .Replace()$WorkingDirectory,如果未在任何地方设置,将计算为 $null

更正后,PowerShell 提供了自己的 string replacement operators: -replace and -ireplace are case-insensitive, -creplace is case-sensitive. The first operand to all of these operators is a regular expression,并且由于正则表达式中的反斜杠表示特殊字符,因此您需要像这样在搜索模式中转义 \...

[string]$from = "X:\"

然后您可以更改 WorkingDirectory 属性 的驱动器号...

$link.WorkingDirectory = [string] $link.WorkingDirectory -replace $from.tostring(),$to.ToString()

...或...

$link.WorkingDirectory = [string] $link.WorkingDirectory -ireplace $from.tostring(),$to.ToString()

请注意 $link.WorkingDirectory$from$to 已经是 [String] 类型,因此 [String] 转换和调用 .ToString() 是不必要的,可以删除...

$link.WorkingDirectory = $link.WorkingDirectory -replace $from,$to

您可以做的一个小优化是在您的搜索模式中添加一个 anchor,这样它就不会费心搜索超出 [String] 的绝对开头的驱动器号...

[string]$from = "^X:\"

此外,由于您使用的是 PowerShell 3+,所以不要像这样过滤掉目录...

$list = Get-ChildItem -Path $folder -Recurse  | Where-Object { $_.Attributes -ne "Directory"}

...您可以过滤 in 个文件 like this...

$list = Get-ChildItem -Path $folder -Recurse -File

更好的是,您还可以使用 -Filter 参数仅包含扩展名为 .lnk 的文件...

$list = Get-ChildItem -Path $folder -Recurse -File -Filter '*.lnk'