If
If (<test1>)
{<statement list 1>}
[elseif (<test2>)
{<statement list 2>}]
[else
{<statement list 3>}]
簡略寫法
<condition> ? <if-true> : <if-false>
Switch
基本語法
Switch ( <test-expression> ){
<result1-to-be-matched> {<action>}
<result2-to-be-matched> {<action>}
Default {<action>}
}
特別參數及語法
Switch [-regex | -wildcard | -exact] [-casesensitive] ( <test-expression> ){
"string1" | number1 | variable1 | { <value-scriptblock1> } { <action-scriptblock> }
"string2" | number2 | variable2 | { <value-scriptblock2> } { <action-scriptblock> }
Default { <action-scriptblock> }
}
從檔案取得資料
Switch [-regex | -wildcard | -exact] [-casesensitive] -file filename {
"string" | number | variable | { <value-scriptblock> } { <action-scriptblock> }
default { <action-scriptblock> }
}
說明:
| 參數 |
說明 |
| -regex |
<test-expression> 的符合條件是正規式;如果 <test-expression> 變數型態不是字串,此參數會無效 |
| -wildcard |
使用萬用字元去比對,這裡不分大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
| -exact |
必須完全符合字串大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
| -casesensitive |
區分大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
| -file |
從文字型檔案讀取每一行來比較,這裡不分大小寫 |
-
範例1:使用 Script Blocks 來媒合,Switch 會執行所有吻合條件的部分
$a = 1,2,3
$Variable = 2
Switch($Variable){
{ $_ -in $a }{
"Variable is in Array"
}
{ $_ -match "[0-9]" }{
"Variable is matched regexp"
}
{ $_ -lt 10 -and $_ -gt 1 }{
"Variable is bigger than 1, and smaller than 10"
}
Default {
"Otherwise"
}
}

-
範例二:要中斷Switch繼續媒合所有 Script Block,要使用 Break
$a = 1,2,3
$Variable = 2
Switch($Variable){
{ $_ -in $a }{
"Variable is in Array"
break
}
{ $_ -match "[0-9]" }{
"Variable is matched regexp"
break
}
{ $_ -lt 10 -and $_ -gt 1 }{
"Variable is bigger than 1, and smaller than 10"
break
}
Default {
"Otherwise"
}
}

-
範例三:
$Variable = 42
Switch($Variable){
{ 0..20 -contains $_ }{
"Variable is between 0~20"
}
{ 21..40 -contains $_ }{
"Variable is between 21~40"
}
{ 41..60 -contains $_ }{
"Variable is between 41~60"
}
{ 61..80 -contains $_ }{
"Variable is between 61~80"
}
{ 81..100 -contains $_ }{
"Variable is between 81~100"
}
Default{
"Variable is not in 0~100"
}
}

-
範例四:媒合條件為正規式
$month = (Get-Date).Month
$month
switch -regex ([string]$month) {
"^[1-3]$" {"Q1"}
"^[4-6]$" {"Q2"}
"^[7-9]$" {"Q3"}
"^1[0-2]$" {"Q4"}
}

Comparison Operators 比較運算說明
| 比較 |
說明 |
| -and |
進行邏輯運算 AND |
| -or |
進行邏輯運算 OR |
| -not |
進行邏輯運算 NOT |
| -xor |
進行邏輯運算 XOR,而非 bit XOR運算 |
| -is |
判斷變數型態是否與比對的型態相同 |
| -isnot |
判斷變數型態是否與比對的型態不相同 |
| -like |
字串匹配通配符模式,忽略大小寫 |
| -ilike |
字串匹配通配符模式,忽略大小寫 |
| -clike |
字串匹配通配符模式,比較大小寫 |
| -notlike |
字串與通配符模式不匹配,忽略大小寫 |
| -inotlike |
字串與通配符模式不匹配,忽略大小寫 |
| -cnotlike |
字串與通配符模式不匹配,比較大小寫 |
| -match |
字串與正規表示式模式匹配,忽略大小寫 |
| -imatch |
字串與正規表示式模式匹配,忽略大小寫 |
| -cmatch |
字串與正規表示式模式匹配,比較大小寫 |
| -notmatch |
字串與正規表示式模式不匹配,忽略大小寫 |
| -inotmatch |
字串與正規表示式模式不匹配,忽略大小寫 |
| -cnotmatch |
字串與正規表示式模式不匹配,比較大小寫 |
| -in |
變數值存在於集合之中,忽略大小寫 |
| -iin |
變數值存在於集合之中,忽略大小寫 |
| -cin |
變數值存在於集合之中,比較大小寫 |
| -notin |
變數值不存在於集合之中,忽略大小寫 |
| -inotin |
變數值不存在於集合之中,忽略大小寫 |
| -cnotin |
變數值不存在於集合之中,比較大小寫 |
| -contains |
集合中包含變數值,忽略大小寫 |
| -icontains |
集合中包含變數值,忽略大小寫 |
| -ccontains |
集合中包含變數值,比較大小寫 |
| -eq |
Equal 等於(忽略大小寫) |
| -ieq |
Equal 等於,忽略大小寫 |
| -ceq |
Equal 等於,比較大小寫 |
| -ne |
Not Equal 不等於,忽略大小寫 |
| -ine |
Not Equal 不等於,忽略大小寫 |
| -cne |
Not Equal 不等於,比較大小寫 |
| -gt |
Great Than 大於,忽略大小寫 |
| -igt |
Great Than 大於,忽略大小寫 |
| -cgt |
Great Than 大於,比較大小寫 |
| -ge |
Great Equal 大於等於,忽略大小寫 |
| -ige |
Great Equal 大於等於,忽略大小寫 |
| -cge |
Great Equal 大於等於,比較大小寫 |
| -lt |
Less Than 小於,忽略大小寫 |
| -ilt |
Less Than 小於,忽略大小寫 |
| -clt |
Less Than 小於,比較大小寫 |
| -le |
Less Equal 小於等於,忽略大小寫 |
| -ile |
Less Equal 小於等於,忽略大小寫 |
| -cle |
Less Equal 小於等於,比較大小寫 |
-
仔細觀察可以發現,只要加上 i 就是不區分大小寫;加上 c 就是區分大小寫
-
從範例來理解 -in & -contains
$a = 5
1..3 -contains $a
1..10 -contains $a
$a -in 1..3
$a -in 1..10
-
從範例來了解 -is & -isnot
$a = 5
$b = "5"
$a.GetType()
$b.GetType()
$a -is [int]
$a -isnot $b.GetType()

-
需要特別注意的特例
$a = 1, 2, $null, 4, $null, 6
$a.GetType()
$a -ne $null
$null -ne $a

"abc" -eq "abc"
"abc" -eq "abc", "def"
"abc" -ne "def"
"abc" -ne "abc"
"abc" -ne "abc", "def"
"abc", "def" -eq "abc"
"abc", "def" -ne "abc"

說明:當集合在運算子左邊時,其結果會是過濾變數值
class MyFileInfoSet {
[String]$File
[Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
上面程式碼雖然透過自訂類別,設定了兩個變數,兩個變數的屬性值雖然都一樣,但這兩個變數是不同的物件, -eq 會認為這不是同一個物件。
所以要讓 -eq 能判斷物件"值" 是否一致,要改用以下程式,讓程式知道使用 -eq 比較時,是要比較兩個變數的值
class MyFileInfoSet : System.IEquatable[Object]{
[String]$File
[Int64]$Size
[bool] Equals([Object] $obj){
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$c = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$d = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$c -eq $d
我們再來看看兩個類別宣告出來的物件變數的方法有甚麼不同
class MyFileInfoSet {
[String]$File
[Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a | Get-Member
class MyFileInfoSet2 : System.IEquatable[Object]{
[String]$File
[Int64]$Size
[bool] Equals([Object] $obj){
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$c = [MyFileInfoSet2]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$c | Get-Member
($c | Get-Member) | Where-Object { $_.Name -eq "Equals" } | Select-Object -Property Definition

Break、Continue、Return、Exit
Break 中斷迴圈或是 Switch,或是 Trap
-
範例一:
$i=0
$varB = 10,20,30,40
foreach ($val in $varB) {
if ($val -eq 30) {
break
}
$i++
}
Write-Host "30 was found in array index $i"
-
範例二:中斷指定的迴圈(這是很差的程式習慣,請盡量不要使用)
Remove-Variable * -ErrorAction SilentlyContinue
$b = 3
:red while ($true) {
:yellow while ($true) {
while ($true) {
if ($a) {break}
if ($b) {break yellow}
if ($c) {break red}
}
Write-Host "中斷最內層迴圈"
}
Write-Host "中斷 :yellow 迴圈"
}
Write-Host "中斷 :red 迴圈"
如果有定義 $a,就會中斷最內層迴圈
如果有定義 $b,就會中斷 :yellow 迴圈
如果有定義 $c,就會中斷 :red 迴圈
請不要在迴圈(不包含 ForEach-Object)、Switch、Trap 之外使用 Break!這會目前的 Runspace 被終止!
function test {
"TEST"
break
}
test
"After Test"
當程式執行 test 函式時,輸出 “TEST” 之後,整個程式就被 break 終止了!所以 “After Test” 永遠不會被執行到。
1..10 | ForEach-Object{
If ($_ -eq 3){
Break
}
$_
}
"迴圈之後,繼續執行"
在 ForEach-Object 內使用 Break,也會導致整個程式被終止!
ForEach ($v in 1..10){
If ($v -eq 3){
Break
}
$v
}
"迴圈之後,繼續執行"
但是在 ForEach ($variable in <collection>){} 迴圈卻不會中斷整個程式
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_continue?view=powershell-7.3