Powershell删除项%1(上下文菜单)

时间:2019-02-23 14:06:06

标签: powershell

曾经与Powershell战斗以做我需要做的事情。这可能是一个简单的解决方案,但我没有找到它。 如果这个问题重复出现,我会道歉,但是找不到我想要的答案。

TL; DR在底部。

所以,关于我的问题。 我正在尝试通过regedit将PS脚本添加到上下文菜单中,该脚本删除其中的文件夹+文件,它在其中没有任何空格的文件夹上效果很好,但是当我尝试删除有空格的文件夹(例如“ New Folder”)时,引发错误并关闭。 (试图通过Remove-Item寻找暂停/睡眠命令,但运气不好,除了长脚本有错误处理等)。

我怀疑错误类似于

Remove-Item : A positional parameter cannot be found that accepts argument 'Folder'.
  

在线:1个字符:12个   +删除项目<<<<新文件夹       + CategoryInfo:InvalidArgument:(:) [Remove-Item],ParameterBindingException       + FullyQualifiedErrorId:PositionalParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand

我当前使用的代码是

cmd /c  PowerShell Remove-Item "%1" -recurse -force

我尝试过各种变体,以使其运气不佳。 即用“ pathAsString”替换"%1",添加另一个"% 1",添加通配符"* *",删除标记。 我尝试过的代码有一些不同的变化:

cmd /c PowerShell Remove-Item \"%1\" -recurse -force
cmd /c PowerShell Remove-Item & "{"%1" -recurse -force"}"

TL; DR cmd /c PowerShell Remove-Item "%1" -recurse -force忽略带有空格的文件夹,尝试了各种操作。 在上下文菜单中使用(通过Regedit)。

可能是一个显而易见的解决方案,但我看不到。

2 个答案:

答案 0 :(得分:0)

以下对我有用:

cmd /c PowerShell -command "& {Remove-Item -path '%1' -recurse -force -confirm:$false}"

使用cmd.exe时,没有脚本块之类的东西。这意味着传递给-command的值将始终是字符串。我在('')周围加上了单引号%1,以使双引号("")与您的论点保持一致。显然,如果文件路径中有单引号('),则此方法将失败。此外,即使在线文档中指出,也不需要呼叫运营商&

有关如何使用PowerShell.exe的更多信息,请参见PowerShell.exe Command-Line Help

请参阅About Quoting Rules,以获取有关PowerShell单引号和双引号如何工作的更多信息。

答案 1 :(得分:0)

您的尝试之一:

  

cmd /c PowerShell Remove-Item \"%1\" -recurse -force

实际上起作用,尽管只有那些具有嵌入空格的路径不包含 multiple 个相邻空格(请参阅底部的 first < / em>使用"%1"而不是\"%1\"的尝试无效)。

使命令健壮(并提高效率),请使用以下变体,不涉及cmd.exe (因为没有必要),并且传递给PowerShell的命令包含在"..." 整体 中,其中嵌入了 {{1} }以" 的身份转义(如您的尝试):

\"

使用的PowerShell CLI选项:

  • powershell.exe -noprofile -command "Remove-Item -LiteralPath \"%1\" -Recurse -Force" 禁止加载当前用户的配置文件(-noprofile),这只会不必要地降低命令速度(或更糟糕的是,可能会更改其行为)。

    < / li>
  • $PROFILE告诉PowerShell,其余参数是PowerShell命令(一段源代码,与-command不同,后者用于调用 script

    • 虽然您不必严格要求在Windows PowerShell中指定-file,因为它暗示了 ,而在PowerShell Core 中已不再是这种情况,默认为-command

-file命令传递给PowerShell:

  • Remove-Item中包含 entire PowerShell命令可确保命令内的空格按原样保留,这与发生在以下位置的路径有关包含多个空格的运行,例如"..."

  • "c:\Users\jdoe\Invoices<space><space>2018"是PowerShell要求嵌套(嵌入)\"字符的方式。 使用" 从命令行调用时会被转义-参见以下说明。

  • -command确保-LiteralPath将字面意义解释为 而不是通配符模式(默认情况下,隐含的Remove-Item参数);虽然不太可能,但如果将-Path之类的路径当作通配符,则会破坏该命令。

注意事项

  • 由于(最终)使用了双引号(c:\tmp\folder[])来封闭路径(文件资源管理器将"..."扩展到的目录路径),它变成了可扩展字符串< / em>,即受字符串内插约束,这意味着包含%1个字符(例如$)的文件夹路径可能会被误解。

  • 您可以通过将c:\tmp\$foo替换为\"%1\"来抑制此插值,即使用单引号字符串(PowerShell始终按字面意义对待),但是问题是您将无法在路径恰好具有'%1'个字符的文件夹上使用该命令。在它们中(例如'


为什么仅仅c:\tmp\o'reilly还不够:

"%1"(您的(第一条)命令行(您将其用作文件资源管理器上下文菜单的命令定义))如下处理:

  • “文件资源管理器”将cmd /c PowerShell Remove-Item "%1" -recurse -force替换为右键单击的文件夹的文件的绝对路径,即按原样显示该路径是否包含空格;例如:

    • %1
  • 然后执行结果命令行;例如:

    • c:\Users\jdoe\Invoices 2018
  • cmd /c PowerShell Remove-Item "c:\Users\jdoe\Invoices 2018" -recurse -force在这里是偶然的(并且不是必需的):它实际上只是将命令行中继到PowerShell(通过其可执行文件cmd /c);例如:

    • powershell.exe
  • PowerShell first 处理各个参数-powershell.exe Remove-Item "c:\Users\jdoe\Invoices 2018" -recurse -forceRemove-Item"c:\Users\jdoe\Invoices 2018"-recurse删除封闭的双引号

  • 由于隐含-force选项,因此将 quote-stripped 参数重新连接在一起,并以空格作为分隔符,然后 then 解释为PowerShell源代码的片段 ;例如:

    • -command

    • 如您所见,双引号的删除导致PowerShell命令损坏,因为带空格的路径现在缺少引号,因此Remove-Item c:\Users\jdoe\Invoices 2018 -recurse -force不再被识别为单< / em>参数,并被解释为 2 参数,前缀c:\Users\jdoe\Invoices 2018后跟c:\Users\jdoe\Invoices是它自己的语法无关参数。

    • 同时使用2018而不是\"%1\"可以防止前期报价剥离-通过告诉PowerShell "%1"字符。将在初始参数解析期间被保留-另外,为了正确保留具有多个相邻空格的文件路径,必须在"中包含 entire PowerShell命令 / em>(即使此类路径可能是文件夹创建过程中输入错误的结果)

      • 总体上不包含"..."的情况下,用"..."引用的路径(例如\")将导致以下 2 参数:

        • C:\Users\jdoe\Invoices<space><space>2018
        • \"C:\Users\jdoe\Invoices
        • PowerShell稍后在各个参数之间重新加入单个 空格时(在将2018\"识别为转义的 \"之后, (保留 ),解释为PowerShell代码之前,它将看到",即只有单个空间。 / li>
      • 总体上包含"C:\Users\jdoe\Invoices<space>2018",整个PowerShell命令被解析为单个参数,而内部空格按原样保留,可以避免此问题。