Powershell: ฉันจะหยุดข้อผิดพลาดไม่ให้แสดงในสคริปต์ได้อย่างไร


94

ตัวอย่างเช่นเมื่อสคริปต์ PowerShell ของฉันพยายามสร้างอ็อบเจ็กต์ SQL Server สำหรับเซิร์ฟเวอร์ที่ไม่มีอยู่ ("bla" ในกรณีของฉัน) PowerShell จะแสดงข้อผิดพลาด PowerShell จำนวนมากเป็นสีแดง

เนื่องจากสคริปต์ของฉันตรวจสอบค่า$?หลังจากการโทรดังกล่าวและแสดงและบันทึกข้อผิดพลาดฉันจึงไม่ต้องการให้แสดงข้อผิดพลาด PowerShell หลายบรรทัดด้วย

ฉันจะปิดใช้งานสิ่งที่แสดงสำหรับสคริปต์ของฉันได้อย่างไร

คำตอบ:


140

คุณมีสองตัวเลือก วิธีที่ง่ายที่สุดคือการใช้การErrorActionตั้งค่า

-Erroractionเป็นพารามิเตอร์สากลสำหรับ cmdlets ทั้งหมด หากมีคำสั่งพิเศษที่คุณต้องการละเว้นคุณสามารถใช้ได้-erroraction 'silentlycontinue'ซึ่งโดยพื้นฐานแล้วจะละเว้นข้อความแสดงข้อผิดพลาดทั้งหมดที่สร้างโดยคำสั่งนั้น คุณยังสามารถใช้Ignoreค่า (ใน PowerShell 3+):

ไม่เหมือนกับ SilentlyContinue, Ignore ไม่ได้เพิ่มข้อความแสดงข้อผิดพลาดในตัวแปรอัตโนมัติ $ Error

หากคุณต้องการละเว้นข้อผิดพลาดทั้งหมดในสคริปต์คุณสามารถใช้ตัวแปรระบบ$ErrorActionPreferenceและทำสิ่งเดียวกัน:$ErrorActionPreference= 'silentlycontinue'

ดูabout_CommonParametersสำหรับข้อมูลเพิ่มเติมเกี่ยวกับ -ErrorAction ดูabout_preference_variablesสำหรับข้อมูลเพิ่มเติมเกี่ยวกับ $ ErrorActionPreference


คุณต้องการคำพูดเดี่ยวใน -erroraction 'silentlycontinue' หรือไม่? Intellisese กำลังแสดงตัวเลือกและไม่ได้เพิ่มใบเสนอราคาเดียว
PAS

1
หากรูปแบบด้านบนใช้ไม่ได้กับคุณให้อ้างอิงลิงก์ที่ให้ไว้ด้านบน ฉันต้องจัดรูปแบบตาม-ErrorAction:SilentlyContinueใน PS 5.1 ฉันเรียก cmdlet จากแบทช์ดังนั้นฉันไม่รู้ว่ามันสร้างความแตกต่างหรือไม่ แต่ข้อมูลที่ดีเมื่อคุณทราบว่าอาจมีข้อผิดพลาดที่ยอมรับได้
เดวิด

--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys

18

Windows PowerShell มีสองกลไกสำหรับข้อผิดพลาดการรายงานทางกลไกหนึ่งสำหรับข้อผิดพลาดการยกเลิกและกลไกอีกข้อผิดพลาดที่ไม่ยุติ

โค้ด CmdLets ภายในสามารถเรียกใช้ThrowTerminatingErrorเมธอดเมื่อมีข้อผิดพลาดเกิดขึ้นซึ่งไม่หรือไม่ควรอนุญาตให้ cmdlet ประมวลผลออบเจ็กต์อินพุตต่อไป ผู้เขียนสคริปต์สามารถใช้ข้อยกเว้นเพื่อตรวจจับข้อผิดพลาดเหล่านี้

EX:

try
{
  Your database code
}
catch
{
  Error reporting/logging
}

โค้ด CmdLets ภายในสามารถเรียกWriteErrorเมธอดเพื่อรายงานข้อผิดพลาดที่ไม่สิ้นสุดเมื่อ cmdlet สามารถประมวลผลออบเจ็กต์อินพุตต่อไปได้ จากนั้นผู้เขียนสคริปต์สามารถใช้ตัวเลือก -ErrorAction เพื่อซ่อนข้อความหรือใช้$ErrorActionPreferenceเพื่อตั้งค่าลักษณะการทำงานของสคริปต์ทั้งหมด


8

ฉันมีปัญหาที่คล้ายกันเมื่อพยายามแก้ไขชื่อโฮสต์โดยใช้[system.net.dns]. หาก IP ไม่ได้รับการแก้ไข Net แสดงข้อผิดพลาดในการยุติ เพื่อป้องกันข้อผิดพลาดในการยุติและยังคงควบคุมเอาต์พุตได้ฉันจึงสร้างฟังก์ชันโดยใช้TRAP.

เช่น

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}

3

คุณออกนอกเส้นทางที่นี่

คุณมีข้อความแสดงข้อผิดพลาดที่ดีอยู่แล้ว ทำไมบนโลกที่คุณต้องการจะเขียนโค้ดที่การตรวจสอบ$?อย่างชัดเจนหลังจากที่ทุกคำสั่งเดียว ? สิ่งนี้ยุ่งยากอย่างมากและเกิดข้อผิดพลาดได้ง่าย วิธีการแก้ปัญหาที่ถูกต้องคือการตรวจสอบหยุด$?

ให้ใช้กลไกในตัวของ PowerShell เพื่อระเบิดให้คุณแทน คุณเปิดใช้งานโดยตั้งค่าการกำหนดลักษณะข้อผิดพลาดเป็นระดับสูงสุด:

$ErrorActionPreference = 'Stop'

$?ฉันใส่นี้ที่ด้านบนของทุกสคริปต์เดียวที่ผมเคยเขียนและตอนนี้ฉันไม่ได้มีการตรวจสอบ สิ่งนี้ทำให้โค้ดของฉันง่ายขึ้นและน่าเชื่อถือมากขึ้น

หากคุณเจอสถานการณ์ที่คุณจริงๆต้องปิดการทำงานนี้คุณสามารถมีข้อผิดพลาดหรือผ่านการตั้งค่าเพื่อฟังก์ชั่นเฉพาะการใช้ร่วมกันcatch -ErrorActionในกรณีของคุณคุณอาจต้องการให้กระบวนการของคุณหยุดลงเมื่อเกิดข้อผิดพลาดแรกตรวจจับข้อผิดพลาดแล้วบันทึก

โปรดทราบว่าสิ่งนี้ไม่ได้จัดการกับกรณีที่ไฟล์ปฏิบัติการภายนอกล้มเหลว (รหัสออกไม่ใช่ศูนย์ตามอัตภาพ) ดังนั้นคุณยังคงต้องตรวจสอบ$LASTEXITCODEว่าคุณเรียกใช้หรือไม่ แม้จะมีข้อ จำกัด นี้ แต่การตั้งค่านี้ยังช่วยประหยัดโค้ดและความพยายามได้มาก

ความน่าเชื่อถือเพิ่มเติม

คุณอาจต้องการพิจารณาใช้โหมดเข้มงวด :

Set-StrictMode -Version Latest

ซึ่งจะป้องกันไม่ให้ PowerShell ดำเนินการโดยไม่โต้ตอบเมื่อคุณใช้ตัวแปรที่ไม่มีอยู่จริงและในสถานการณ์แปลก ๆ อื่น ๆ (ดู-Versionพารามิเตอร์สำหรับรายละเอียดเกี่ยวกับสิ่งที่ จำกัด )

การรวมการตั้งค่าทั้งสองนี้ทำให้ PowerShell มีภาษาที่ไม่เร็วมากขึ้นซึ่งทำให้การเขียนโปรแกรมง่ายขึ้นอย่างมาก




-1

หากคุณต้องการให้ข้อผิดพลาด powershell สำหรับ cmdlet ถูกระงับ แต่ยังคงต้องการตรวจจับข้อผิดพลาดให้ใช้ "-erroraction 'silentlyStop'"


ไม่มีการกระทำดังกล่าว แม้ว่าจะมีการหยุดทำงาน
Marvin Dickhaus

แต่อนุญาตให้ระงับข้อความแสดงข้อผิดพลาดสีแดงและยังคงใช้คำสั่ง / ส่วน catch เมื่อใช้New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager

@MilanKerslager คุณช่วยแสดงตัวอย่างโค้ดได้ไหม - เนื่องจากฉันและคนอื่น ๆ เชื่อว่าไม่มี ActionPreference เช่น 'SilentlyStop'
FSCKur

ฉันมั่นใจพอสมควรว่า Mikkel หมายถึง SilentlyContinue แทนที่จะเป็น SilentlyStop เพราะนั่นทำให้เข้าใจได้มากขึ้นในเนื้อหาของสิ่งที่คุณต้องการให้ทำ
John
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.