回到基础知识:使用PowerShell If语句进行条件逻辑

此文章已更新至2023年!

脚本可以做出决策。如何?通过使用称为条件逻辑的概念。PowerShell if语句和if/else结构是定义条件的常用方式。

当您编写PowerShell脚本时,您会针对特定任务或目标进行操作。但是,一个操作可以根据一个或多个条件有多种可能的动作。这种情况是PowerShell If语句结构的用武之地。

在本文中,您将学习PowerShell If-Else结构,并了解其语法及其工作原理。您还将从示例中学习一些可以使用PowerShell If语句为脚本添加条件逻辑处理的方法。

理解PowerShell If语句的语法

PowerShell if-else结构评估一个或多个条件表达式。下面您将看到If语句的语法。这种风格通常称为流程控制。

if (<test1>)
    {<statement list 1>}
[elseif (<test2>)
    {<statement list 2>}]
[else
    {<statement list 3>}]

如上所示的语法,每个测试都包含在括号()中。测试可以使用不同的运算符,如比较运算符逻辑运算符

语句列表包含的代码意图在测试结果为true时运行。

在一个If语句组中有三种可能的语句。这些是IF、ELSEIF和ELSE语句。

  • if语句包含要评估的第一个测试,后面是用大括号{}括起来的第一个语句列表。PowerShell if语句是唯一必须出现的语句。
  • elseif语句用于添加条件。当有多个条件时,可以添加多个ElseIf语句。PowerShell会按顺序评估每个条件。
  • else语句不接受任何条件。此语句中的语句列表包含了如果所有先前测试的条件都为false时要运行的代码。

理解PowerShell If语句逻辑流程

为了进一步理解PowerShell If-Else的工作原理,请熟悉其逻辑流程。下面的图示了PowerShell If-Else的基本流程。

PowerShell If Statement Logic Flow

当if语句运行时,PowerShell会遍历每个条件,评估代码是否返回true或false。以下是行为摘要:

  • PowerShell评估Test 1中的条件。
  • 如果Test 1的结果返回true,则会运行If语句列表中的代码,然后PowerShell退出If语句。
  • 如果Test 1的结果返回false,PowerShell将继续评估下一个ElseIf语句中的条件(Testn)。
  • 如果测试 n的结果返回,PowerShell将继续评估条件(测试n)在下一个ElseIf语句中,如果存在另一个 ElseIf 语句 -OR-
  • 如果测试 n 的结果返回,则会执行Else语句中的代码,并且 PowerShell 将退出 If 语句 -OR-
  • 如果测试 n 的结果返回 true,则会执行ElseIf语句中的代码,并且 PowerShell 将退出 If 语句。

使用 PowerShell If-Else 语句

下面的部分是 PowerShell If 语句在编写脚本时的几个示例。您将学到的技巧可以指导您在遇到需要使用 If 语句的现实情况时使用它。

单个 If-Else 条件

从最基本的开始是单个 PowerShell If 语句。当只有一个条件需要测试时,应该使用单个 if 语句。

下面的示例测试变量$num的值是否大于 10。如果结果为真,则屏幕上会显示"$num is greater than 10"。如果结果为假,则 PowerShell 不执行任何操作,因为只有一个条件需要测试。

$num = 11
if ($num -gt 10) {
    "$num is greater than 10"
}

如果您只检查特定值,例如if ($Value) { },那么 PowerShell 将测试$Value是否不是$Null0$False、空字符串或空数组。

将上述代码粘贴到 PowerShell 中将给您以下显示的结果。

Single If Condition Example

现在,如果你想要添加一个默认的“回退”操作,而不是让 PowerShell 在测试结果为 false 时什么都不做,你可以添加 Else 语句。

在下面的示例中,如果 $num 变量的值不大于 10,那么 Else 语句中的代码将会运行。

$num = 9
if ($num -gt 10)
{
    "$num is greater than 10"
}
else
{
    "$num is NOT greater than 10"
}

在 PowerShell 中运行修改后的代码将会得到下面所示的输出。

Single If statement condition

从 PowerShell 7.0 开始,引入了一种新的 If 语句语法,使用了一个 三元运算符。单个 If 语句可以很好地利用这种新的语法。

使用上面相同的示例,这是使用 三元运算符的代码样式。

$num = 11
$num -gt 10 ? "$num is greater than 10" : "$num is NOT greater than 10"
If statement syntax using ternary operator

在 PowerShell If 语句中测试 $Null

你可能认为测试 $Null 条件很简单。但是,将 $Null 值放在哪一侧很重要,因为在每种条件下结果可能不同。最佳实践是始终将 $Null 条件放在左侧,如下所示。

$Null -NE $Value

如果你将 $Null 测试放在右侧,并且左侧的值是一个列表,比如一个数组,那么 $Null 将会起到过滤器的作用。正如下面的示例所示,如果将 $Null 放在左侧,你将会得到一致的布尔结果。

$List = @(1,2,2,3,4)
$List -NE $Null
$List -EQ $Null
$Null -NE $Null
$Null -EQ $Null
$Null testing conditions for PowerShell If Statement

使用 ElseIf 的多个 If-Else 条件

在评估多个条件时,您需要添加一个或多个 ElseIf 语句。每个 ElseIf 语句包含测试表达式及其要运行的代码。

执行下面的脚本时,将不断提示输入水果名称,直到发出 CTRL+C 键或用户输入字母“X”为止。

然后,If 语句将依次遍历每个条件,直到找到匹配项。如果输入不匹配任何条件,则将执行 Else 语句中的代码。

While ($fruit -ne "X") {
    $fruit = Read-Host "Name that fruit"

    if ($fruit -eq 'Apple') {
        'I have an Apple'
    }
    elseif ($fruit -eq 'Banana') {
        'I have a Banana'
    }
    elseif ($fruit -eq 'Orange') {
        'I have an Orange'
    }
    else {
        'Sorry, that fruit is not in the list'
    }
}

以下是 PowerShell 中运行上述脚本时的演示。

Multiple If-Else conditions

报告空闲磁盘空间状态

报告空闲磁盘空间是系统管理员常见的任务之一。在 Windows 机器上报告固定磁盘的空间信息的常规方法围绕以下代码展开。

Get-CimInstance -ClassName CIM_LogicalDisk | Where-Object {$_.DriveType -eq 3}

代码以上将返回的信息如下截图所示。

Plain disk space information report

如您所见,上面的输出显示了驱动器号、空闲空间值和其他属性。虽然上面的输出是可以接受的,但它不直观。信息的呈现方式并未指示磁盘空间是否处于关键状态、警告状态或正常状态。

使用 PowerShell If 语句改进代码

A more intuitive output can be achieved using the PowerShell If-Else statement by adding conditions to check if the free space is over or below certain thresholds. And these thresholds will define the status of the free disk space.

下面的示例脚本执行以下操作:

  • 使用变量值 $Critical,定义作为 critical 标记的空闲空间百分比的阈值。
  • 使用变量$Warning的值,定义将空闲空间百分比标记为warning的阈值。
  • 获取本地计算机的所有固定磁盘信息
  • 循环遍历所有磁盘信息以确定空闲空间并标记其状态。
    • 如果空闲空间百分比高于$Warning变量的值,则磁盘空间状态标记为normal
    • 如果空闲空间百分比高于$Critical变量的值,则磁盘空间状态标记为warning
    • 如果空闲空间百分比小于或等于$Critical变量的值,则磁盘空间状态标记为critical
  • 构建对象属性'Drive Letter''Drive Name''Total Space (GB)''Free Space (GB)''Free Space (%)''Status'
  • 返回最终报告。

复制下面的代码并将脚本保存为Get-DiskSpace.ps1文件。不要忘记更改$Critical$Warning变量的值以测试不同的阈值。

# 定义百分比阈值
$Critical = 20
$Warning = 70

# 获取所有固定磁盘信息
$diskObj = Get-CimInstance -ClassName CIM_LogicalDisk | Where-Object { $_.DriveType -eq 3 }

# 初始化一个空数组,用于保存最终结果
$finalReport = @()

# 遍历每个磁盘信息
$diskObj.foreach(
    {
        # 计算空闲空间百分比
        $percentFree = [int](($_.FreeSpace / $_.Size) * 100)

        # 确定“状态”
        if ($percentFree -gt $Warning) {
            $Status = 'Normal'
        }
        elseif ($percentFree -gt $Critical) {
            $Status = 'Warning'
        }
        elseif ($percentFree -le $Critical) {
            $Status = 'Critical'
        }

        # 组合要添加到报告中的对象属性
        $tempObj = [ordered]@{
            'Drive Letter'     = $_.DeviceID
            'Drive Name'       = $_.VolumeName
            'Total Space (GB)' = [int]($_.Size / 1gb)
            'Free Space (GB)'  = [int]($_.FreeSpace / 1gb)
            'Free Space (%)'   = "{0}{1}" -f [int]$percentFree, '%'
            'Status'           = $Status
        }

        # 将对象添加到最终报告中
        $finalReport += New-Object psobject -property $tempObj
    }
)

return $finalReport

您也可以将if/else条件的结果分配给变量,例如$Status = if ($percentFree -gt $Warning) { 'Normal' },以便可能制作更短的条件。

保存脚本后,通过在PowerShell中调用其名称来测试它。以下是该脚本如何运行的示例演示。

Free Disk Space Status Command Output

从输出中可以看出,每个磁盘的状态是通过自由磁盘空间百分比确定的,这是使用PowerShell If-Else进行多个条件的结果。

多重和嵌套If-Else

假设您有一个带有条件的 if-else 语句,条件是在 else 块中定义的。当 if-else 语句运行时,如果 if 块内的代码返回 false,则调用 else 块。

else 块内,您需要执行另一个条件测试。因此,您需要另一个 If-Else 语句。这种情况被称为嵌套的 If-Else。如果内部 If-Else 取决于外部 If-Else 的操作结果,则通常使用嵌套的 If-Else 语句。

使用多个和嵌套的 If-Else 语句可能会非常令人困惑。关键是要记住支架的放置位置,并确保对代码进行缩进。对代码进行缩进将有助于您轻松识别和分隔 If-Else 语句。

多/嵌套 If-Else 语句示例

下面的示例脚本显示了多个和嵌套 If-Else 如何依赖彼此的结果。下面代码的逻辑如下。

  • 如果 $SendEmail$false,则脚本将不执行任何操作并退出。
  • 如果 $SendEmail$true,那么 $From$To 变量必须不为空或 null。否则,$abortFlag 将被设置为 1。
  • 如果 $SendEmail$true 并且 $CCEnabled$true,那么 $CC 变量必须不为空或 null。否则,$abortFlag 将被设置为 1。
  • 如果$SendEmail$true并且$BCCEnabled$true,那么$BCC变量必须不为空或 null。否则,$abortFlag将设置为 1。
  • 如果$abortFlag值为 1,则脚本将在此处退出,不会继续。
  • 如果$abortFlag值为 0,则脚本会继续执行直到结束。

复制下面的代码并将其保存为Send-MyMail.ps1。暂时不要更改任何值。

$SendEmail = $true

$From = ""
$To = ""

$CCEnabled = $true
$CC = ""

$BCCEnabled = $true
$BCC = ""

$abortFlag = 0

if ($SendEmail) {
    if (!$From) {
        Write-Host "[From] is missing" -ForegroundColor Red
        $abortFlag = 1
    }

    if (!$To) {
        Write-Host "[To] is missing" -ForegroundColor Red
        $abortFlag = 1
    }

    if ($CCEnabled) {
        if (!$CC) {
            Write-Host "[CC] is missing" -ForegroundColor Red
            $abortFlag = 1
        }
    }

    if ($BCCEnabled) {
        if (!$BCC) {
            Write-Host "[BCC] is missing" -ForegroundColor Red
            $abortFlag = 1
        }
    }

    if ($abortFlag -eq 1) {
        Write-Host "The abort flag has been tripped. Exit script." -ForegroundColor Red
        break
    }
    else {
        Write-Host "Your email will be sent from this address $From" -ForegroundColor Green
        Write-Host "And will be sent to the following people:" -ForegroundColor Green
        Write-Host "To: $To" -ForegroundColor Green

        if ($CCEnabled -and $CC) {
            Write-Host "CC: $CC" -ForegroundColor Green
        }

        if ($BCCEnabled -and $BCC) {
            Write-Host "BCC: $BCC" -ForegroundColor Green
        }
    }
}

保存文件后,在 PowerShell 中运行它,如下所示。下面的演示展示了脚本在变量值未更改时的结果。

Nested If-Else example

接下来,编辑脚本并适当更新所有变量,就像下面的代码片段一样。

$SendEmail = $true

$From = "[email protected]"
$To = "[email protected]"

$CCEnabled = $true
$CC = "[email protected]"

$BCCEnabled = $true
$BCC = "[email protected]"

---SNIP---

编辑变量后,保存脚本并再次运行。它应该会显示与下面看到的相同的结果。

Another nested If-else example

现在,修改变量并尝试不同的组合以测试嵌套的 If-Else 如何受影响。通过自行修改和测试,可以帮助您进一步了解逻辑。

摘要

在本文中,您了解了条件逻辑结构 – PowerShell If 语句结构。If-Else 语句允许脚本编写人员根据测试结果制定条件逻辑并指导脚本的操作。

通过本文中的示例,您应该学会了在创建基于决策的代码时使用 If-Else 语句的方法和技巧。If-Else 可以简单地使用单个条件,并且在深入挖掘嵌套的 If-Else 语句时变得更加复杂。

你对 If-Else 语句有何看法?阅读了这篇文章后,你觉得你会越来越多地使用它吗?你还可以考虑将所学知识应用在哪些其他场景?

进一步阅读

Source:
https://adamtheautomator.com/powershell-if-else/