代码之家  ›  专栏  ›  技术社区  ›  william007

Powershell-在函数中执行命令之前进行确认

  •  0
  • william007  · 技术社区  · 2 年前

    我在powershell配置文件中放入了以下函数 (路径来自 echo $profile ,我的就像 D:\C_Drive\Hardlink\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 )

    function test {
        [cmdletbinding(SupportsShouldProcess)]
        ls
    }
    Set-Alias ggg test
    

    具有 [cmdletbinding(SupportsShouldProcess)] 以提示确认,但运行时出现以下错误 ggg

    At D:\C_Drive\Hardlink\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:2 char:5
    +     [cmdletbinding(SupportsShouldProcess)]
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Unexpected attribute 'cmdletbinding'.
    At D:\C_Drive\Hardlink\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:3 char:5
    +     ls
    +     ~~
    Unexpected token 'ls' in expression or statement.
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : UnexpectedAttribute
    

    在执行函数中的命令之前,正确的确认方式是什么?

    1 回复  |  直到 2 年前
        1
  •  6
  •   Santiago Squarzon    2 年前

    你在正确的轨道上使用 SupportsShouldProcess ,但是它不见了 ConfirmImpact 具有 ConfirmImpact set to High 。通过这种方式,您可以定义您的函数是 高风险函数 PowerShell总是请求确认。这也是由您的 $ConfirmPreference preference variable 默认情况下,设置为 高的 :

    高:在运行具有高风险的cmdlet或函数之前,PowerShell会提示进行确认。

    例如,如果首选项变量设置为 没有一个 ,PowerShell将不再要求您确认该操作。

    function test {
        [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
        param([string] $myParam)
    
        if($PSCmdlet.ShouldProcess([string] $myParam)) {
            Get-ChildItem $myParam
        }
    }
    

    然后,如果我们尝试调用函数:

    PS /> test C:\
    

    将出现以下确认提示:

    Are you sure you want to perform this action?
    Performing the operation "test" on target "C:\".
    [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
    

    最后一点 Cmdlet.ShouldProcess 有很多 Overloads 它提供了一种更详细的请求确认的方式。上当前使用的 test 函数是最简单的一个。

    至于您在尝试运行函数时看到的错误,发生这种情况是因为函数有 cmdletbinding attribute 声明您的职能和 Advanced Function 但它缺少一个 param block 即使函数没有任何参数,它也应该存在。此外,一个函数 支持应处理 必须调用 $PSCmdlet.ShouldProcess(...) 提示确认 .

    function test {
        [cmdletbinding()]
        param()
    
    }
    
        2
  •  2
  •   Bolton    2 年前

    试试这个:

    function test {
       $confirmation = Read-Host "Do you want to continue? [y to continue] "
        if ($confirmation -eq 'y') {
            ls
        }
    }
    Set-Alias ggg test
    

    更多信息请参阅此处: https://www.delftstack.com/howto/powershell/powershell-yes-no-prompt/

        3
  •  2
  •   mklement0    2 年前

    让我试着通过提供一个系统的概述来补充这些答案:

    PowerShell具有 两个独立的机制 用于制作 advanced (cmdlet-like) functions 提示确认 :

    • 有条件的 确认提示 ,基于

      $PSCmdlet.ShouldProcess(...)
      calls-记下单词 过程 -与集成 common -Confirm parameter 以及相关 $ConfirmPreference preference variable ,并隐式地支持 common -WhatIf parameter 以及相关 $WhatIfPreference preference variable .

      • 此机制需要:

        • A. [CmdletBinding(...)] 上面的属性 param(...) 块(这使函数成为 先进的 (类似cmdlet)一个),具有 ShouldProcess 属性设置为 $true 以及,可选地 Confirm 属性设置为之一 'Low' , 'Medium' 'Default' (默认为 中等的 ; 请参阅 System.Management.Automation.ConfirmImpact 枚举)

        • 保护函数(或脚本)要执行的操作 if 调用的语句 $PSCmdlet.ShouldProcess() 方法,并且仅在以下情况下执行操作 $true 返回。

          • 但是,请注意 预计会出现提示 每个输入对象一次 ,在 process 高级功能块(即接受 管道输入 ,这是典型的)。PowerShell 自动地 处理与相关的响应 全部的 在后续调用中的(后续)输入对象( [A] Yes to All [L] No to All ),通过自动返回 $true $false 在随后的调用中。

          • 这个 违约 迅速反应 -只需按下即可选择 进来 一成不变 [Y] Yes ,即确认要处理的意图(手头的输入对象)。

      • 是否有确认提示 将实际显示 调用时可以按如下方式进行控制/取决于以下内容:

        • 镇压 提示,通过 -Confirm:$false 或者,为了达到范围广泛的效果,设置 $ConfirmPreference = 'None' .

        • 明确请求提示 使用 证实 -Confirm:$true )

        • 否则,只有当的值为 $ConfirmPreference -默认为 'High' 等于或小于 命令声明的确认影响级别。

          • 例如,标准 Remove-Item cmdlet声明的确认影响级别为 Medium ,所以如果你设置 $ConfirmPreference = 'Medium' , 删除项目 调用(不使用 -确认:$false )将在删除文件之前提示确认。
    • 无条件的 确认提示 ,基于

      $PSCmdlet.ShouldContinue(...)
      calls-记下单词 持续 ,它们是 不相关的 到上面提到的公共参数/偏好变量。

      • 此机制需要:

        • A. [CmdletBinding()] 上面的属性 参数(…) 块,以便使其成为 先进的 函数,该函数允许访问 automatic $PSCmdlet variable ,但需要 要设置的属性的属性。

        • 保护函数(或脚本)要执行的操作 如果 调用的语句 $PSCmdlet.ShouldContinue() 方法,并且仅在以下情况下执行操作 $true 返回。

          • 与不同 .ShouldProcess() 方法 通常只显示提示 一旦 每个函数调用,并且在两个参数重载中只显示 [Y] 是 [N] No 选择。

            • 但是,其他重载允许您显示 [A] 对所有人都是 [L] 全部为否 也有选择,但不同于 .ShouldProcess -你必须 手动 基于这些选择管理对后续输入对象的调用中的跳过提示/处理,这些选择通过返回 [ref] 参数。
          • 这个 违约 迅速反应 -只需按下即可选择 进来 [Y] 是 也是,但是你 可以将其更改为 [N] 否 通过使用具有 hasSecurityImpact 参数和传递 $false 对它。

            • 不幸的是,从PowerShell 7.2.x开始,正在执行此操作 一成不变 还显示了 [A] 对所有人都是 [L] 全部为否 选择,可能不受欢迎-请参阅 GitHub issue #9428 .
      • 的标准机制 抑制 这样的提示 然而 依照惯例 ,命令 应该 实现 -Force 转换 这样做。

        • 一个例子是 Set-ExecutionPolicy cmdlet 在Windows PowerShell中 ,默认情况下会提示确认,但允许使用 武力 以取消提示。

    你可以 结合 这两种机制 ,尽管这样做的唯一好理由是如果你想支持 -WhatIf 无条件提示之外的功能-请参阅 这个答案 例如。