回歸基礎:使用 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語句中的條件(測試n)。
  • 如果测试 n的结果返回,PowerShell将继续评估条件(测试n)在下一个ElseIf语句中,如果存在另一个 ElseIf 语句 -或者-
  • 如果测试 n 的结果返回,则在Else语句中的代码将运行,PowerShell 将退出 If 语句 -或者-
  • 如果测试 n 的结果返回真,则ElseIf语句中的代码将运行,并且 PowerShell 将退出 If 语句。

使用 PowerShell If-Else 语句

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

单个 If-Else 条件

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

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

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

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

将上面的代码粘贴到 PowerShell 中将给出以下结果。

Single If Condition Example

現在,如果你想添加一個預設的“fallback”操作,而不是讓 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,定義空閒空間百分比將被標記為關鍵的閾值。
  • 使用變量$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) { '正常' },以便可能更简洁地编写条件。

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

Free Disk Space Status Command Output

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

多个和嵌套的If-Else

假設您有一個包含在else塊中定義條件的if-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/