ทุกสิ่งที่คุณอยากรู้เกี่ยวกับคำสั่ง if
เช่นเดียวกับภาษาอื่นๆ หลายภาษา PowerShell มีคำสั่งสำหรับการรันโค้ดตามเงื่อนไขในสคริปต์ของคุณ หนึ่งในคำสั่งเหล่านั้นคือคำสั่ง If วันนี้เราจะเจาะลึกหนึ่งในคำสั่งพื้นฐานที่สุดใน PowerShell
บันทึก
ต้นฉบับของบทความนี้ปรากฏบนบล็อกที่เขียนโดย @KevinMarquette ทีม PowerShell ขอขอบคุณ Kevin สำหรับการแบ่งปันเนื้อหานี้กับเรา โปรดตรวจสอบบล็อกของเขาที่ PowerShellExplained.com
การดำเนินการตามเงื่อนไข
สคริปต์ของคุณมักจะจำเป็นต้องตัดสินใจและดำเนินการตามตรรกะที่แตกต่างกันตามการตัดสินใจเหล่านั้น นี่คือสิ่งที่ฉันหมายถึงโดยการดำเนินการตามเงื่อนไข คุณมีหนึ่งคำสั่งหรือค่าที่ต้องประเมิน จากนั้นรันโค้ดส่วนอื่นตามการประเมินนั้น นี่คือสิ่งที่คำสั่ง if ทำ
คำสั่ง if
นี่คือตัวอย่างพื้นฐานของคำสั่ง if:
$condition = $true
if ( $condition )
{
Write-Output "The condition was true"
}
สิ่งแรกที่คำสั่ง if ทำคือประเมินนิพจน์ในวงเล็บ หากประเมินเป็น $true แสดงว่าดำเนินการ scriptblock ในเครื่องหมายปีกกา หากค่าเป็น $false ระบบจะข้ามบล็อกสคริปต์นั้น
ในตัวอย่างก่อนหน้านี้ คำสั่ง if เป็นเพียงการประเมินตัวแปร $condition มันเป็น $true และจะต้องดำเนินการคำสั่ง Write-Output ภายใน scriptblock
ในบางภาษา คุณสามารถวางโค้ดบรรทัดเดียวหลังคำสั่ง if และโค้ดจะถูกดำเนินการ นั่นไม่ใช่กรณีใน PowerShell คุณต้องระบุ scriptblock แบบเต็มด้วยเครื่องหมายปีกกาเพื่อให้ทำงานได้อย่างถูกต้อง
ตัวดำเนินการเปรียบเทียบ
การใช้งานทั่วไปของคำสั่ง if คือการเปรียบเทียบสองรายการระหว่างกัน PowerShell มีตัวดำเนินการพิเศษสำหรับสถานการณ์การเปรียบเทียบที่แตกต่างกัน เมื่อคุณใช้ตัวดำเนินการเปรียบเทียบ ค่าทางด้านซ้ายมือจะถูกเปรียบเทียบกับค่าทางด้านขวามือ
-eq เพื่อความเท่าเทียมกัน
-eq จะตรวจสอบความเท่าเทียมกันระหว่างสองค่าเพื่อให้แน่ใจว่ามีค่าเท่ากัน
$value = Get-MysteryValue
if ( 5 -eq $value )
{
# do something
}
ในตัวอย่างนี้ ฉันใช้ค่าที่ทราบเป็น 5 และเปรียบเทียบกับ $value ของฉันเพื่อดูว่าตรงกันหรือไม่
กรณีการใช้งานหนึ่งที่เป็นไปได้คือการตรวจสอบสถานะของค่าก่อนที่คุณจะดำเนินการกับค่านั้น คุณสามารถรับบริการและตรวจสอบว่าสถานะกำลังทำงานอยู่ก่อนที่คุณจะเรียกว่า Restart-Service
เป็นเรื่องปกติในภาษาอื่นๆ เช่น C# ที่จะใช้ == เพื่อความเท่าเทียมกัน (เช่น: 5 == $value) แต่ใช้ไม่ได้กับ PowerShell ข้อผิดพลาดทั่วไปอีกประการหนึ่งที่ผู้คนทำคือการใช้เครื่องหมายเท่ากับ (เช่น 5=$value) ที่สงวนไว้สำหรับการกำหนดค่าให้กับตัวแปร การวางค่าที่ทราบไว้ทางซ้าย จะทำให้ทำผิดพลาดได้ยากขึ้น
โอเปอเรเตอร์นี้ (และอื่นๆ) มีรูปแบบที่แตกต่างกันเล็กน้อย
-eqความเท่าเทียมกันโดยไม่คำนึงถึงขนาดตัวพิมพ์-ieqความเท่าเทียมกันโดยไม่คำนึงถึงขนาดตัวพิมพ์-ceqความเท่าเทียมกันแบบคำนึงถึงขนาดตัวพิมพ์
-ไม่เท่ากัน
ตัวดำเนินการหลายตัวมีตัวดำเนินการที่เกี่ยวข้องซึ่งกำลังตรวจสอบผลลัพธ์ที่ตรงกันข้าม -ne ตรวจสอบว่าค่าไม่เท่ากัน
if ( 5 -ne $value )
{
# do something
}
ใช้สิ่งนี้เพื่อให้แน่ใจว่าการดำเนินการจะดำเนินการเฉพาะในกรณีที่ค่าไม่ใช่ 5 กรณีการใช้งานที่ดีซึ่งควรตรวจสอบว่าบริการอยู่ในสถานะกำลังทำงานอยู่หรือไม่ก่อนที่คุณจะพยายามเริ่มใช้งาน
รูปแบบต่างๆ:
-neไม่คำนึงถึงขนาดตัวพิมพ์-ineไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-cneคำนึงถึงขนาดตัวพิมพ์ไม่เท่ากัน
สิ่งเหล่านี้คือรูปแบบผกผันของ -eq ฉันจะจัดกลุ่มประเภทเหล่านี้เข้าด้วยกันเมื่อฉันแสดงรายการรูปแบบต่างๆ สำหรับโอเปอเรเตอร์อื่นๆ
-gt -ge -lt -le มากกว่าหรือน้อยกว่า
ตัวดำเนินการเหล่านี้ใช้ในการตรวจสอบว่าค่ามีขนาดใหญ่หรือเล็กกว่าค่าอื่นหรือไม่ -gt -ge -lt -le ย่อมาจาก GreaterThan, GreaterThanOrEqual, LessThan และ LessThanOrEqual
if ( $value -gt 5 )
{
# do something
}
รูปแบบต่างๆ:
-gtมากกว่า-igtมากกว่า ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่-cgtมากกว่า คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-geมากกว่าหรือเท่ากับ-igeมากกว่าหรือเท่ากับ ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่-cgeมากกว่าหรือเท่ากับ คำนึงถึงขนาดตัวพิมพ์-ltน้อยกว่า-iltน้อยกว่า ไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-cltน้อยกว่า คำนึงถึงขนาดตัวพิมพ์-leน้อยกว่าหรือเท่ากับ-ileน้อยกว่าหรือเท่ากับ ไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-cleน้อยกว่าหรือเท่ากับ คำนึงถึงขนาดตัวพิมพ์
ฉันไม่รู้ว่าทำไมคุณถึงใช้ตัวเลือกที่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่สำหรับตัวดำเนินการเหล่านี้
- เหมือนการแข่งขันไวด์การ์ด
PowerShell มีไวยากรณ์การจับคู่รูปแบบที่ใช้ไวด์การ์ดของตัวเอง และคุณสามารถใช้กับตัวดำเนินการ -like ได้ รูปแบบไวด์การ์ดเหล่านี้ค่อนข้างพื้นฐาน
?จับคู่อักขระเดี่ยวใดๆ*จับคู่อักขระจำนวนเท่าใดก็ได้
$value = 'S-ATX-SQL01'
if ( $value -like 'S-*-SQL??')
{
# do something
}
สิ่งสำคัญคือต้องชี้ให้เห็นว่ารูปแบบนั้นตรงกับสตริงทั้งหมด หากคุณต้องการจับคู่บางสิ่งที่อยู่ตรงกลางของสตริง คุณต้องวาง * ที่ปลายทั้งสองด้านของสตริง
$value = 'S-ATX-SQL02'
if ( $value -like '*SQL*')
{
# do something
}
รูปแบบต่างๆ:
- ไวด์การ์ด
-likeที่ไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ -ilikeไวด์การ์ดที่ไม่คำนึงถึงขนาดตัวพิมพ์-clikeไวด์การ์ดที่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-notlikeไวด์การ์ดไม่ตรงกัน-inotlikeไวด์การ์ดไม่ตรงกัน-cnotlikeไวด์การ์ดที่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ไม่ตรงกัน
- จับคู่นิพจน์ทั่วไป
ตัวดำเนินการ -match ช่วยให้คุณสามารถตรวจสอบสตริงสำหรับการจับคู่ตามนิพจน์ทั่วไป ใช้สิ่งนี้เมื่อรูปแบบไวด์การ์ดไม่ยืดหยุ่นเพียงพอสำหรับคุณ
$value = 'S-ATX-SQL01'
if ( $value -match 'S-\w\w\w-SQL\d\d')
{
# do something
}
รูปแบบ regex จะจับคู่ที่ใดก็ได้ในสตริงตามค่าเริ่มต้น ดังนั้นคุณจึงสามารถระบุสตริงย่อยที่คุณต้องการจับคู่ได้ดังนี้:
$value = 'S-ATX-SQL01'
if ( $value -match 'SQL')
{
# do something
}
Regex เป็นภาษาที่ซับซ้อนในตัวเองและควรค่าแก่การพิจารณา ฉันพูดถึง -match เพิ่มเติมและวิธีต่างๆ มากมายในการใช้ regex ในบทความอื่น
รูปแบบต่างๆ:
-matchregex ที่ไม่คำนึงถึงขนาดตัวพิมพ์-imatchregex ที่ไม่คำนึงถึงขนาดตัวพิมพ์-cmatchregex แบบคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-notmatchregex ที่ไม่ตรงตามตัวพิมพ์ใหญ่-เล็กไม่ตรงกัน-inotmatchregex ที่ไม่ตรงตามตัวพิมพ์ใหญ่-เล็กไม่ตรงกัน-cnotmatchregex แบบคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ไม่ตรงกัน
-เป็นประเภท
คุณสามารถตรวจสอบประเภทของค่าได้ด้วยตัวดำเนินการ -is
if ( $value -is [string] )
{
# do something
}
คุณสามารถใช้สิ่งนี้ได้หากคุณกำลังทำงานกับคลาสหรือยอมรับออบเจ็กต์ต่างๆ บนไปป์ไลน์ คุณสามารถมีทั้งบริการหรือชื่อบริการเป็นข้อมูลที่คุณป้อน จากนั้นตรวจสอบเพื่อดูว่าคุณมีบริการหรือไม่ และเรียกบริการหากคุณมีเพียงชื่อเท่านั้น
if ( $Service -isnot [System.ServiceProcess.ServiceController] )
{
$Service = Get-Service -Name $Service
}
รูปแบบต่างๆ:
-คือประเภท-isnotไม่ใช่ประเภท
ผู้ประกอบการรวบรวม
เมื่อคุณใช้ตัวดำเนินการก่อนหน้าที่มีค่าเดียว ผลลัพธ์จะเป็น $true หรือ $false สิ่งนี้จะได้รับการจัดการแตกต่างออกไปเล็กน้อยเมื่อทำงานกับคอลเลกชัน แต่ละรายการในคอลเลกชันจะได้รับการประเมิน และผู้ดำเนินการส่งคืนทุกค่าที่ประเมินเป็น $true
PS> 1,2,3,4 -eq 3
3
สิ่งนี้ยังคงทำงานได้อย่างถูกต้องในคำสั่ง if ดังนั้นค่าจะถูกส่งกลับโดยโอเปอเรเตอร์ของคุณ ดังนั้นคำสั่งทั้งหมดจึงเป็น $true
$array = 1..6
if ( $array -gt 3 )
{
# do something
}
มีกับดักเล็กๆ ซ่อนอยู่ในรายละเอียดซึ่งฉันต้องชี้ให้เห็น เมื่อใช้ตัวดำเนินการ -ne ด้วยวิธีนี้ เป็นเรื่องง่ายที่จะมองตรรกะย้อนกลับโดยไม่ได้ตั้งใจ การใช้ -ne กับคอลเลกชันจะส่งคืน $true หากรายการใดๆ ในคอลเลกชันไม่ตรงกับค่าของคุณ
PS> 1,2,3 -ne 4
1
2
3
นี่อาจดูเหมือนเป็นกลอุบายที่ชาญฉลาด แต่เรามีตัวดำเนินการ -contains และ -in ที่จัดการสิ่งนี้ได้อย่างมีประสิทธิภาพมากขึ้น และ -notcontains ทำสิ่งที่คุณคาดหวัง
-contains
ตัวดำเนินการ -contains จะตรวจสอบคอลเลกชันสำหรับค่าของคุณ ทันทีที่พบรายการที่ตรงกัน มันจะส่งคืน $true
$array = 1..6
if ( $array -contains 3 )
{
# do something
}
นี่เป็นวิธีที่เหมาะสมที่สุดในการดูว่าคอลเลกชันมีมูลค่าของคุณหรือไม่ การใช้ Where-Object (หรือ -eq) เป็นการเดินผ่านรายการทั้งหมดทุกครั้งและช้าลงอย่างมาก
รูปแบบต่างๆ:
-containsการจับคู่แบบไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-icontainsการจับคู่แบบไม่คำนึงถึงขนาดตัวพิมพ์-ccontainsการจับคู่แบบคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-notcontainsไม่คำนึงถึงขนาดตัวพิมพ์-inotcontainsไม่คำนึงถึงขนาดตัวพิมพ์-cnotcontainsคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ไม่ตรงกัน
-in
ตัวดำเนินการ -in ก็เหมือนกับตัวดำเนินการ -contains ยกเว้นว่าคอลเลกชันจะอยู่ทางด้านขวามือ
$array = 1..6
if ( 3 -in $array )
{
# do something
}
รูปแบบต่างๆ:
-inตรงกันโดยไม่คำนึงถึงขนาดตัวพิมพ์-iinการจับคู่แบบไม่คำนึงถึงขนาดตัวพิมพ์-cinตรงตามตัวพิมพ์เล็กและตัวพิมพ์ใหญ่-notinไม่คำนึงถึงขนาดตัวพิมพ์-inotinไม่คำนึงถึงขนาดตัวพิมพ์-cnotinคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ไม่ตรงกัน
ตัวดำเนินการเชิงตรรกะ
ตัวดำเนินการเชิงตรรกะใช้เพื่อกลับหรือรวมนิพจน์อื่นๆ
-not
ตัวดำเนินการ -not พลิกนิพจน์จาก $false เป็น $true หรือจาก $true เป็น $เท็จ. นี่คือตัวอย่างที่เราต้องการดำเนินการเมื่อ Test-Path เป็น $false
if ( -not ( Test-Path -Path $path ) )
ตัวดำเนินการส่วนใหญ่ที่เราพูดถึงมีรูปแบบที่คุณไม่จำเป็นต้องใช้ตัวดำเนินการ -not แต่ยังมีบางครั้งที่มันมีประโยชน์
- ตัวดำเนินการ
คุณสามารถใช้ ! เป็นนามแฝงสำหรับ -not
if ( -not $value ){}
if ( !$value ){}
คุณอาจเห็น ! ถูกใช้มากขึ้นโดยผู้ที่มาจากภาษาอื่นเช่น C# ฉันชอบพิมพ์ออกมาเพราะฉันพบว่ามันยากที่จะเห็นเมื่อดูสคริปต์อย่างรวดเร็ว
-and
คุณสามารถรวมนิพจน์เข้ากับตัวดำเนินการ -และ เมื่อคุณทำเช่นนั้น ทั้งสองฝ่ายจะต้อง $true เพื่อให้นิพจน์ทั้งหมดเป็น $true
if ( ($age -gt 13) -and ($age -lt 55) )
ในตัวอย่างนี้ $age จะต้องมีอายุ 13 ปีขึ้นไปสำหรับด้านซ้าย และน้อยกว่า 55 สำหรับด้านขวา ฉันเพิ่มวงเล็บเพิ่มเติมเพื่อให้ชัดเจนในตัวอย่างนี้ แต่ก็เป็นทางเลือกตราบใดที่สำนวนนั้นเรียบง่าย นี่คือตัวอย่างเดียวกันที่ไม่มีพวกเขา
if ( $age -gt 13 -and $age -lt 55 )
การประเมินเกิดขึ้นจากซ้ายไปขวา หากรายการแรกประเมินเป็น $false รายการดังกล่าวจะออกก่อนกำหนดและไม่สามารถเปรียบเทียบได้ถูกต้อง สิ่งนี้มีประโยชน์เมื่อคุณต้องการตรวจสอบให้แน่ใจว่ามีค่าอยู่ก่อนที่จะใช้งาน ตัวอย่างเช่น Test-Path ส่งข้อผิดพลาดหากคุณกำหนดเส้นทาง $null
if ( $null -ne $path -and (Test-Path -Path $path) )
-or
-หรือ ช่วยให้คุณสามารถระบุสองนิพจน์และส่งกลับ $true หากหนึ่งในนั้นคือ $true
if ( $age -le 13 -or $age -ge 55 )
เช่นเดียวกับตัวดำเนินการ -และ การประเมินจะเกิดขึ้นจากซ้ายไปขวา ยกเว้นว่าหากส่วนแรกเป็น $true คำสั่งทั้งหมดจะเป็น $true และจะไม่ประมวลผลส่วนที่เหลือของนิพจน์
จดบันทึกวิธีการทำงานของไวยากรณ์สำหรับตัวดำเนินการเหล่านี้ด้วย คุณต้องมีนิพจน์สองรายการแยกกัน ฉันเคยเห็นผู้ใช้พยายามทำสิ่งนี้ $value -eq 5 -or 6 โดยไม่ได้ตระหนักถึงข้อผิดพลาด
-xor พิเศษหรือ
อันนี้ผิดปกติเล็กน้อย -xor อนุญาตให้มีนิพจน์เดียวประเมินเป็น $true ดังนั้น หากทั้งสองรายการเป็น $false หรือทั้งสองรายการเป็น $true ดังนั้นนิพจน์ทั้งหมดจะเป็น $false อีกวิธีในการดูสิ่งนี้คือนิพจน์จะเป็น $true เท่านั้น เมื่อผลลัพธ์ของนิพจน์แตกต่างกัน
เป็นเรื่องยากที่ใครๆ จะใช้ตัวดำเนินการเชิงตรรกะนี้ และฉันไม่สามารถคิดตัวอย่างที่ดีได้ว่าทำไมฉันถึงใช้มัน
ตัวดำเนินการ Bitwise
ตัวดำเนินการระดับบิตจะทำการคำนวณบิตภายในค่าและสร้างค่าใหม่ตามผลลัพธ์ การสอนตัวดำเนินการระดับบิตนั้นอยู่นอกเหนือขอบเขตของบทความนี้ แต่นี่คือรายการของพวกเขา
-bandไบนารีและ-borไบนารีหรือ-bxorไบนารีพิเศษหรือ-bnotไบนารี่ ไม่-shlเลื่อนไปทางซ้าย-shrเลื่อนไปทางขวา
นิพจน์ PowerShell
เราสามารถใช้ PowerShell ปกติภายในคำสั่งเงื่อนไขได้
if ( Test-Path -Path $Path )
Test-Path ส่งคืน $true หรือ $false เมื่อดำเนินการ นอกจากนี้ยังใช้กับคำสั่งที่ส่งคืนค่าอื่นๆ ด้วย
if ( Get-Process Notepad* )
โดยจะประเมินเป็น $true หากมีกระบวนการส่งคืน และ $false หากไม่มี การใช้นิพจน์ไปป์ไลน์หรือคำสั่ง PowerShell อื่นๆ ในลักษณะนี้เหมาะสมอย่างยิ่ง:
if ( Get-Process | Where Name -eq Notepad )
นิพจน์เหล่านี้สามารถนำมารวมกันโดยใช้ตัวดำเนินการ -และ และ -หรือ แต่คุณอาจต้องใช้วงเล็บเพื่อแยกนิพจน์เหล่านี้ออกเป็นนิพจน์ย่อย
if ( (Get-Process) -and (Get-Service) )
กำลังตรวจสอบ $null
การไม่มีผลลัพธ์หรือค่า $null จะประเมินเป็น $false ในคำสั่ง if เมื่อตรวจสอบ $null โดยเฉพาะ แนวทางปฏิบัติที่ดีที่สุดคือวาง $null ทางด้านซ้ายมือ
if ( $null -eq $value )
มีความแตกต่างเล็กน้อยเมื่อต้องจัดการกับค่า $null ใน PowerShell หากคุณสนใจที่จะเจาะลึกยิ่งขึ้น ฉันมีบทความเกี่ยวกับทุกสิ่งที่คุณอยากรู้เกี่ยวกับ $null
การกำหนดตัวแปรภายในเงื่อนไข
เกือบลืมใส่อันนี้ไป จน ประสูร การุนันท์ วี เตือนให้นึกถึงเรื่องนี้
if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}
โดยปกติเมื่อคุณกำหนดค่าให้กับตัวแปร ค่าจะไม่ถูกส่งผ่านไปยังไปป์ไลน์หรือคอนโซล เมื่อคุณกำหนดตัวแปรในนิพจน์ย่อย ตัวแปรนั้นจะถูกส่งต่อไปยังไปป์ไลน์
PS> $first = 1
PS> ($second = 2)
2
ดูว่าการกำหนด $first ไม่มีเอาต์พุตและการมอบหมาย $second ทำอย่างไร เมื่อการมอบหมายเสร็จสิ้นในคำสั่ง if ก็จะดำเนินการเหมือนกับการมอบหมาย $second ด้านบน นี่คือตัวอย่างที่ชัดเจนเกี่ยวกับวิธีการใช้งาน:
if ( $process = Get-Process Notepad* )
{
$process | Stop-Process
}
หาก $process ได้รับการกำหนดค่า ดังนั้นคำสั่งจะเป็น $true และ $process จะถูกหยุด
ตรวจสอบให้แน่ใจว่าคุณไม่สับสนกับ -eq เนื่องจากนี่ไม่ใช่การตรวจสอบความเท่าเทียมกัน นี่เป็นคุณลักษณะที่คลุมเครือมากขึ้นซึ่งคนส่วนใหญ่ไม่รู้ว่าวิธีนี้ใช้ได้ผล
การกำหนดตัวแปรจาก scriptblock
คุณยังสามารถใช้คำสั่ง if scriptblock เพื่อกำหนดค่าให้กับตัวแปรได้
$discount = if ( $age -ge 55 )
{
Get-SeniorDiscount
}
elseif ( $age -le 13 )
{
Get-ChildDiscount
}
else
{
0.00
}
แต่ละบล็อกสคริปต์กำลังเขียนผลลัพธ์ของคำสั่งหรือค่าเป็นเอาต์พุต เราสามารถกำหนดผลลัพธ์ของคำสั่ง if ให้กับตัวแปร $discount ตัวอย่างนั้นสามารถกำหนดค่าเหล่านั้นให้กับตัวแปร $discount โดยตรงในแต่ละ scriptblock ได้อย่างง่ายดายพอๆ กัน ฉันไม่สามารถพูดได้ว่าฉันใช้สิ่งนี้กับคำสั่ง if บ่อยครั้ง แต่ฉันมีตัวอย่างที่ฉันใช้สิ่งนี้เมื่อเร็ว ๆ นี้
เส้นทางการดำเนินการสำรอง
คำสั่ง if ช่วยให้คุณสามารถระบุการดำเนินการได้ ไม่เพียงแต่เมื่อคำสั่งนั้นเป็น $true เท่านั้น แต่ยังรวมถึงเมื่อเป็น $false ด้วย นี่คือที่มาของคำสั่ง else
อื่น
คำสั่ง else เป็นส่วนสุดท้ายของคำสั่ง if เสมอเมื่อใช้
if ( Test-Path -Path $Path -PathType Leaf )
{
Move-Item -Path $Path -Destination $archivePath
}
else
{
Write-Warning "$path doesn't exist or isn't a file."
}
ในตัวอย่างนี้ เราจะตรวจสอบ $path เพื่อให้แน่ใจว่าเป็นไฟล์ หากเราพบไฟล์เราจะย้ายมัน ถ้าไม่เช่นนั้นเราจะเขียนคำเตือน ตรรกะการแยกสาขาประเภทนี้เป็นเรื่องธรรมดามาก
ซ้อนถ้า
คำสั่ง if และ else รับบล็อกสคริปต์ ดังนั้นเราสามารถวางคำสั่ง PowerShell ใด ๆ ไว้ข้างในได้ รวมถึงคำสั่ง if อื่นด้วย สิ่งนี้ทำให้คุณสามารถใช้ตรรกะที่ซับซ้อนมากขึ้นได้
if ( Test-Path -Path $Path -PathType Leaf )
{
Move-Item -Path $Path -Destination $archivePath
}
else
{
if ( Test-Path -Path $Path )
{
Write-Warning "A file was required but a directory was found instead."
}
else
{
Write-Warning "$path could not be found."
}
}
ในตัวอย่างนี้ เราทดสอบเส้นทางแห่งความสุขก่อน แล้วจึงดำเนินการตามนั้น หากไม่สำเร็จ เราจะตรวจสอบอีกครั้งและให้ข้อมูลรายละเอียดเพิ่มเติมแก่ผู้ใช้
อย่างอื่น
เราไม่ได้จำกัดอยู่เพียงการตรวจสอบแบบมีเงื่อนไขเพียงครั้งเดียว เราสามารถเชื่อมโยงคำสั่ง if และ else เข้าด้วยกัน แทนที่จะซ้อนกันโดยใช้คำสั่ง elseif
if ( Test-Path -Path $Path -PathType Leaf )
{
Move-Item -Path $Path -Destination $archivePath
}
elseif ( Test-Path -Path $Path )
{
Write-Warning "A file was required but a directory was found instead."
}
else
{
Write-Warning "$path could not be found."
}
การดำเนินการเกิดขึ้นจากบนลงล่าง คำสั่ง if บนสุดจะถูกประเมินก่อน หากนั่นคือ $false มันจะเลื่อนลงไปที่ elseif หรือ else ถัดไปในรายการ else สุดท้ายนั้นเป็นการกระทำเริ่มต้นที่จะดำเนินการหากไม่มีสิ่งอื่นใดส่งคืน $true
สวิตช์
ณ จุดนี้ ฉันต้องพูดถึงคำสั่ง switch มันมีไวยากรณ์ทางเลือกสำหรับการเปรียบเทียบหลายค่าด้วยค่า ด้วย สวิตช์ คุณจะระบุนิพจน์และผลลัพธ์นั้นจะถูกเปรียบเทียบกับค่าที่แตกต่างกันหลายค่า หากค่าใดค่าหนึ่งตรงกัน บล็อกโค้ดที่ตรงกันจะถูกดำเนินการ ลองดูตัวอย่างนี้:
$itemType = 'Role'
switch ( $itemType )
{
'Component'
{
'is a component'
}
'Role'
{
'is a role'
}
'Location'
{
'is a location'
}
}
มีค่าที่เป็นไปได้สามค่าที่สามารถตรงกับ $itemType ในกรณีนี้ จะจับคู่กับ Role ฉันใช้ตัวอย่างง่ายๆ เพื่อให้คุณได้เห็นตัวดำเนินการ switch ฉันพูดคุยเพิ่มเติมเกี่ยวกับทุกสิ่งที่คุณอยากรู้เกี่ยวกับคำสั่ง switch ในบทความอื่น
อาร์เรย์แบบอินไลน์
ฉันมีฟังก์ชันที่เรียกว่า Invoke-SnowSql ซึ่งเรียกใช้งานปฏิบัติการด้วยอาร์กิวเมนต์บรรทัดคำสั่งหลายรายการ นี่คือคลิปจากฟังก์ชันที่ฉันสร้างอาร์เรย์ของอาร์กิวเมนต์
$snowSqlParam = @(
'--accountname', $Endpoint
'--username', $Credential.UserName
'--option', 'exit_on_error=true'
'--option', 'output_format=csv'
'--option', 'friendly=false'
'--option', 'timing=false'
if ($Debug)
{
'--option', 'log_level=DEBUG'
}
if ($Path)
{
'--filename', $Path
}
else
{
'--query', $singleLineQuery
}
)
ตัวแปร $Debug และ $Path เป็นพารามิเตอร์ในฟังก์ชันที่จัดทำโดยผู้ใช้ปลายทาง ฉันประเมินพวกมันแบบอินไลน์ภายในการเริ่มต้นอาร์เรย์ของฉัน หาก $Debug เป็นจริง ค่าเหล่านั้นจะอยู่ใน $snowSqlParam ในตำแหน่งที่ถูกต้อง เช่นเดียวกันถือเป็นจริงสำหรับตัวแปร $Path
ลดความซับซ้อนของการดำเนินงานที่ซับซ้อน
หลีกเลี่ยงไม่ได้ที่คุณจะพบสถานการณ์ที่มีการเปรียบเทียบมากเกินไปที่จะตรวจสอบ และคำสั่ง If ของคุณเลื่อนออกไปทางด้านขวาของหน้าจอ
$user = Get-ADUser -Identity $UserName
if ( $null -ne $user -and $user.Department -eq 'Finance' -and $user.Title -match 'Senior' -and $user.HomeDrive -notlike '\\server\*' )
{
# Do Something
}
อาจอ่านยากและทำให้คุณมีแนวโน้มที่จะทำผิดพลาดมากขึ้น มีบางสิ่งที่เราสามารถทำได้เกี่ยวกับเรื่องนั้น
ต่อแถว
มีโอเปอเรเตอร์บางตัวใน PowerShell ที่ให้คุณตัดคำสั่งไปยังบรรทัดถัดไป ตัวดำเนินการเชิงตรรกะ -และ และ -or เป็นตัวดำเนินการที่ดีที่จะใช้หากคุณต้องการแบ่งนิพจน์ของคุณออกเป็นหลายบรรทัด
if ($null -ne $user -and
$user.Department -eq 'Finance' -and
$user.Title -match 'Senior' -and
$user.HomeDrive -notlike '\\server\*'
)
{
# Do Something
}
ยังมีอะไรเกิดขึ้นอีกมาก แต่การวางแต่ละชิ้นบนเส้นของตัวเองจะสร้างความแตกต่างอย่างมาก โดยทั่วไปฉันใช้สิ่งนี้เมื่อได้รับการเปรียบเทียบมากกว่าสองครั้งหรือหากต้องเลื่อนไปทางขวาเพื่ออ่านตรรกะใดๆ
ผลลัพธ์การคำนวณล่วงหน้า
เราสามารถนำคำสั่งนั้นออกจากคำสั่ง if และตรวจสอบเฉพาะผลลัพธ์เท่านั้น
$needsSecureHomeDrive = $null -ne $user -and
$user.Department -eq 'Finance' -and
$user.Title -match 'Senior' -and
$user.HomeDrive -notlike '\\server\*'
if ( $needsSecureHomeDrive )
{
# Do Something
}
นี่ให้ความรู้สึกสะอาดกว่าตัวอย่างก่อนหน้านี้มาก คุณยังได้รับโอกาสในการใช้ชื่อตัวแปรที่อธิบายว่าคุณกำลังตรวจสอบอะไรอยู่ นี่เป็นตัวอย่างของโค้ดที่จัดทำเอกสารด้วยตนเองซึ่งจะบันทึกความคิดเห็นที่ไม่จำเป็น
หลายคำสั่ง if
เราสามารถแบ่งสิ่งนี้ออกเป็นหลาย ๆ ข้อความและตรวจสอบได้ทีละรายการ ในกรณีนี้ เราใช้แฟล็กหรือตัวแปรติดตามเพื่อรวมผลลัพธ์
$skipUser = $false
if( $null -eq $user )
{
$skipUser = $true
}
if( $user.Department -ne 'Finance' )
{
Write-Verbose "isn't in Finance department"
$skipUser = $true
}
if( $user.Title -match 'Senior' )
{
Write-Verbose "Doesn't have Senior title"
$skipUser = $true
}
if( $user.HomeDrive -like '\\server\*' )
{
Write-Verbose "Home drive already configured"
$skipUser = $true
}
if ( -not $skipUser )
{
# do something
}
ฉันต้องกลับตรรกะเพื่อให้ตรรกะการตั้งค่าสถานะทำงานได้อย่างถูกต้อง การประเมินแต่ละครั้งเป็นคำสั่ง if แต่ละรายการ ข้อดีของการดำเนินการนี้คือ เมื่อคุณกำลังแก้ไขจุดบกพร่อง คุณสามารถบอกได้อย่างแน่ชัดว่าตรรกะกำลังทำอะไรอยู่ ฉันสามารถเพิ่มคำฟุ่มเฟือยที่ดีขึ้นได้มากในเวลาเดียวกัน
ข้อเสียที่ชัดเจนคือต้องเขียนโค้ดมากกว่ามาก โค้ดมีความซับซ้อนมากขึ้นเมื่อพิจารณาเนื่องจากใช้ตรรกะบรรทัดเดียวและขยายออกเป็น 25 บรรทัดขึ้นไป
การใช้ฟังก์ชั่น
นอกจากนี้เรายังสามารถย้ายตรรกะการตรวจสอบทั้งหมดนั้นไปไว้ในฟังก์ชันได้ ดูชัดๆ ว่าสะอาดแค่ไหน..
if ( Test-SecureDriveConfiguration -ADUser $user )
{
# do something
}
คุณยังคงต้องสร้างฟังก์ชันเพื่อทำการตรวจสอบ แต่มันทำให้โค้ดนี้ทำงานได้ง่ายขึ้นมาก ทำให้โค้ดนี้ง่ายต่อการทดสอบ ในการทดสอบของคุณ คุณสามารถจำลองการเรียก Test-ADDriveConfiguration และคุณต้องการการทดสอบเพียงสองครั้งสำหรับฟังก์ชันนี้ ช่องหนึ่งส่งคืน $true และอีกช่องส่งคืน $false การทดสอบฟังก์ชันอื่นนั้นง่ายกว่าเนื่องจากมีขนาดเล็กมาก
เนื้อความของฟังก์ชันนั้นอาจเป็นบรรทัดเดียวที่เราเริ่มต้นด้วยหรือตรรกะแบบกระจายที่เราใช้ในส่วนสุดท้าย วิธีนี้ใช้ได้ผลดีกับทั้งสองสถานการณ์และช่วยให้คุณเปลี่ยนการใช้งานในภายหลังได้อย่างง่ายดาย
การจัดการข้อผิดพลาด
การใช้คำสั่ง if ที่สำคัญอย่างหนึ่งคือการตรวจสอบเงื่อนไขข้อผิดพลาดก่อนที่คุณจะพบข้อผิดพลาด ตัวอย่างที่ดีคือการตรวจสอบว่ามีโฟลเดอร์อยู่แล้วก่อนที่คุณจะพยายามสร้างมันขึ้นมา
if ( -not (Test-Path -Path $folder) )
{
New-Item -Type Directory -Path $folder
}
ฉันชอบที่จะบอกว่าถ้าคุณคาดหวังว่าจะมีข้อยกเว้นเกิดขึ้น มันก็ไม่ใช่ข้อยกเว้นจริงๆ ดังนั้นให้ตรวจสอบค่าของคุณและตรวจสอบเงื่อนไขของคุณในส่วนที่คุณสามารถทำได้
หากคุณต้องการเจาะลึกเพิ่มเติมอีกเล็กน้อยเกี่ยวกับการจัดการข้อยกเว้นที่เกิดขึ้นจริง ฉันมีบทความเกี่ยวกับทุกสิ่งที่คุณต้องการทราบเกี่ยวกับข้อยกเว้น
คำพูดสุดท้าย
คำสั่ง if เป็นคำสั่งง่ายๆ แต่เป็นส่วนพื้นฐานของ PowerShell คุณจะพบว่าตัวเองใช้สิ่งนี้หลายครั้งในเกือบทุกสคริปต์ที่คุณเขียน ฉันหวังว่าคุณจะมีความเข้าใจที่ดีขึ้นกว่าเดิม