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

时间:2018-09-20 05:38:35

标签: powershell shortcut com-interop powershell-v4.0 path-manipulation

我遇到一种情况,即%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() 
}

1 个答案:

答案 0 :(得分:0)

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

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

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

更正后,PowerShell提供了自己的string replacement operators-replace-ireplace区分大小写,-creplace区分大小写。所有这些运算符的第一个操作数是regular expression,并且由于regex中的反斜杠表示特殊字符,因此您需要像这样在搜索模式中转义\ ...

[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"}

...您可以在文件like this中过滤 ...

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

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

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