当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell WhatIf 参数:三思而后行

作者:精品下载站 日期:2024-12-14 20:51:38 浏览:14 分类:玩电脑

PowerShell WhatIf 参数:三思而后行


“我并不总是测试我的脚本,但当我这样做时,我会在生产中进行”

不要说谎。你以前已经做过了。我们都曾在某个时间点经历过。不过,在生产中运行 PowerShell 脚本时不一定有风险。请记住使用内置的 PowerShell WhatIf 参数!

如果能够知道 PowerShell 命令在更改您的环境之前会执行什么操作,这不是很好吗?想象一下,你可以问你的命令:“如果你要逃跑,你会怎么做?”您可以使用 WhatIf 参数。

所有已编译的 PowerShell cmdlet 都包含一个名为 WhatIf 的参数。此参数可帮助您评估命令是否按预期工作或者是否会引发核熔毁。

方便的 WhatIf 参数不仅适用于所有内置 cmdlet,还适用于您的脚本和高级函数!如果您的代码将改变您环境中的事物,那么如果您选择实现它,您将受益于故障安全机制。

先决条件

本文将是一个演练。如果您想跟随这个旅程,您应该准备好几件事。

  • 能够运行 Powershell v5.1 的 Windows 计算机。 (推荐Windows 10及以上版本)
  • 脚本编辑器,例如 Notepad++Windows PowerShell ISEVisual Studio Code

请注意,在本文中,我将在 Windows 10 计算机上使用 Visual Studio Code 1.38(2019 年 8 月)。

WhatIf PowerShell 参数:已定义

简而言之,WhatIf 参数是可用于所有高级函数和 cmdlet 的内置开关参数(通过将 PowerShell CmdletBinding 关键字添加到脚本和函数)。使用时,该命令会向控制台报告该命令的预期效果。但并不实际执行该命令。

所有 cmdlet 和高级函数都具有可用的 WhatIf 参数。在本文中,我们将使用 Get-ServiceStop-ServiceNew-Item cmdlet 演示此参数。

检查 Powershell WhatIf 支持

如果您不确定特定命令是否支持 WhatIf,可以使用两种快速方法进行检查。

使用 Get 命令

您可以使用 Get-Command 命令通过使用 Syntax 参数来查看命令元数据,如下所示。如果您看到 -WhatIf 引用,则说明 WhatIf 受支持。

使用制表符补全

您还可以使用制表符补全检查 WhatIf 参数支持。只需在 PowerShell 控制台中键入您想要检查的命令,然后输入空格、破折号、“Wh”和 Tab 键。

如果出现 WhatIf,则表明该命令具有 WhatIf 参数。

将 PowerShell WhatIf 参数与 Cmdlet 结合使用

您可以通过多种不同的方式利用 WhatIf 参数。在本部分中,您将了解如何使用内置 cmdlet 立即开始使用 WhatIf 参数。

创建文件

与所有 cmdlet 一样,New-Item cmdlet 具有 WhatIf 参数。在此示例中,您将使用 New-Item cmdlet 在同一工作目录中创建名为 newfile1.txt 的文件。

如果您要运行以下命令,它将创建名为 newfile.txt 的文件。

但是,如果此命令创建的文件如果创建不成功可能会导致问题怎么办?没问题。您可以将 WhatIf 参数添加到末尾。

停止服务

您还可以将 WhatIf 参数与 Stop-Service cmdlet 结合使用。在此示例中,您将获取前五个服务的列表,并使用 Stop-Service 命令停止它们。但你不是。

相反,您只是看到 PowerShell 控制台的输出消息,让您知道 Stop-Service cmdlet 将停止哪些服务。

[玩转系统] PowerShell WhatIf 参数:三思而后行

全局更改 Powershell WhatIf 行为

此时,您应该知道,将 WhatIf 参数与 cmdlet 或高级函数一起使用只能模拟操作。您正在影响命令级别的 WhatIf 行为。

WhatIf 行为还可以通过操作自动变量 $WhatIfPreference 在影响所有命令的更高级别进行设置。

$WhatIfPreference 变量是布尔值。它只能是 TrueFalse。默认情况下,它设置为 False 意味着在所有命令上禁用 WhatIf 支持,除非在命令级别覆盖。如果设置为 True所有 支持它的命令,无论是否显式使用 WhatIf 参数,都将位于“WhatIf模式。”

您可以通过 $WhatIfPreference=$true$WhatIfPreference 的值更改为 True 来测试这一点。您可以在下面看到,使用 New-Item 而没有 WhatIf 参数现在的行为就像传递参数一样。

如果您已将 $WhatIfPreference 更改为 True,请不要忘记通过 $WhatIfPreference 将其改回 False=$false.

在本部分中,您了解了如何将 WhatIf 支持与现有 cmdlet 结合使用。在下一步中,您将学习如何在自定义脚本和函数中构建 WhatIf 支持。

在函数中实现 Powershell WhatIf 支持

在尝试在脚本中实现 WhatIf 支持 之前,有必要了解执行此操作的正确方法和错误方法。您将在接下来的部分中看到这些是什么。

做错了:不要重新发明轮子

脚本开发人员重新发明轮子并通过一些 if/then 逻辑实现自己的 WhatIf 支持的情况并不罕见。下面您可以看到一个示例。

请注意,开发人员已经定义了自己的 WhatIf 开关参数。然后,使用该参数的值,他们使用 if/then 构造来处理使用或不使用 WhatIf 参数时的逻辑。

Function Remove-LogFile {
    param (
        [Parameter(Mandatory)]
        [string]$name,

        [switch]$WhatIf
    )
    
    if ($WhatIf.IsPresent) { # WhatIf switch is on.
        Write-Host "WhatIf: I will remove the log file ""$name""" -ForegroundColor Yellow
    } else {
        # WhatIf switch is off.
        Write-Host "Delete log file ""$name""" -ForegroundColor Green
    }
}

当使用 WhatIf 参数运行上述函数时(如下所示),看起来它完成了它的工作。该函数实际上并没有删除任何内容并向控制台返回消息。

如果有效的话,那么这个方法有什么问题呢?因为你忽略了高级功能的内置功能。您需要将此功能构建到您创建的每个函数中,而不是仅仅关注命令关闭时将执行的操作。

相反,不要重新发明轮子,而是将 SupportsShouldProcess 关键字 $PSCmdlet.ShouldProcess() 结合使用。即将到来。

正确做法:使用 SupportsShouldProcess

所有使用[CmdletBinding()] 关键字的函数都使它们变得“高级”。该关键字为函数添加了各种功能,包括 WhatIf 支持。

所有高级函数都支持 WhatIf 功能,但是否利用它取决于您。为此,您必须首先在 [CmdletBinding()] 括号之间使用 SupportsShouldProcess 关键字,如下所示。

[CmdletBinding(SupportsShouldProcess)]

该函数现在允许您调用 $PSCmdlet 函数变量上的 ShouldProcess() 方法,以确定 WhatIf 参数是否已传递给该函数或不。使用 WhatIf 参数时,ShouldProcess() 返回 False。否则,它将始终返回True

Function Remove-LogFile {
     [cmdletbinding(SupportsShouldProcess)]
     param (
         [Parameter(Mandatory)]
         [string]$name
     )
     if ($PSCmdlet.ShouldProcess($name)) {
         ## The -WhatIf parameter was NOT used. The function should process as normal.
         Write-Host ("Delete log file " + $name) -ForegroundColor Green
     } else {
         ## The -WhatIf parameter was used. The function should NOT process.
     }
 }
True

错误的

False

真的

现在您可以在下面看到当使用 WhatIf 参数执行 Remove-LogFile 时;它显示与内置 cmdlet 相同的行为。

总结

在本文中,您了解了 PowerShell WhatIf 参数。您现在应该了解它是如何工作的以及它可以带来什么好处。

您还应该知道,下次您需要 PowerShell 函数的故障保护时,不要重新发明轮子。相反,请利用现有的 PowerShell WhatIf 支持!

进一步阅读

  • 如何使用 PowerShell 模块编写更好的脚本
  • 关于函数 CmdletBindingAttribute #SupportsShouldProcess
  • 关于偏好变量

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯