Powershell: Bagaimana cara menghentikan kesalahan agar tidak ditampilkan dalam skrip?

94

Ketika skrip PowerShell saya mencoba, misalnya, untuk membuat objek SQL Server untuk server yang tidak ada ("bla" dalam kasus saya), PowerShell menampilkan banyak kesalahan PowerShell dengan warna merah.

Karena skrip saya memeriksa nilai $?setelah panggilan seperti itu, dan menampilkan serta mencatat kesalahan, saya lebih suka tidak menampilkan beberapa baris kesalahan PowerShell juga.

Bagaimana saya bisa menonaktifkan yang ditampilkan untuk skrip saya?

Andrew J. Brehm
sumber

Jawaban:

140

Anda memiliki dua pilihan. Yang termudah melibatkan penggunaan ErrorActionpengaturan.

-Erroractionadalah parameter universal untuk semua cmdlet. Jika ada perintah khusus yang ingin Anda abaikan, Anda dapat menggunakan -erroraction 'silentlycontinue'yang pada dasarnya akan mengabaikan semua pesan kesalahan yang dihasilkan oleh perintah itu. Anda juga dapat menggunakan Ignorenilai (di PowerShell 3+):

Tidak seperti SilentlyContinue, Ignore tidak menambahkan pesan kesalahan ke variabel otomatis $ Error.

Jika Anda ingin mengabaikan semua kesalahan dalam skrip, Anda dapat menggunakan variabel sistem $ErrorActionPreferencedan melakukan hal yang sama:$ErrorActionPreference= 'silentlycontinue'

Lihat about_CommonParameters untuk info selengkapnya tentang -ErrorAction. Lihat about_preference_variables untuk info lebih lanjut tentang $ ErrorActionPreference.

JNK
sumber
apakah Anda perlu kutipan tunggal dalam -erroraction 'silentlycontinue'? Intellisese menunjukkan opsi dan tidak menambahkan kutipan tunggal.
PAS
1
Jika format di atas tidak berhasil untuk Anda, lihat tautan yang disediakan di atas. Saya harus memformat seperti -ErrorAction:SilentlyContinuepada PS 5.1. Saya memanggil cmdlet saya dari batch jadi saya tidak tahu apakah itu membuat perbedaan. Tapi info bagus bila Anda tahu kesalahan yang dapat diterima mungkin terlempar.
David
--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys
18

Windows PowerShell menyediakan dua mekanisme untuk melaporkan kesalahan: satu mekanisme untuk menghentikan kesalahan dan mekanisme lain untuk kesalahan non-terminating .

Kode CmdLets internal dapat memanggil ThrowTerminatingErrormetode ketika terjadi kesalahan yang tidak atau seharusnya tidak memungkinkan cmdlet untuk terus memproses objek masukannya. Penulis skrip dapat menggunakan pengecualian untuk menangkap kesalahan ini.

EX:

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

Kode CmdLets internal dapat memanggil WriteErrormetode untuk melaporkan kesalahan non-penghentian ketika cmdlet dapat melanjutkan pemrosesan objek masukan. Penulis skrip kemudian dapat menggunakan opsi -ErrorAction untuk menyembunyikan pesan, atau menggunakan $ErrorActionPreferenceuntuk menyiapkan seluruh perilaku skrip.

JPBlanc
sumber
8

Saya mengalami masalah serupa saat mencoba menyelesaikan nama host menggunakan [system.net.dns]. Jika IP tidak terselesaikan, Net melemparkan kesalahan penghentian. Untuk mencegah kesalahan penghentian dan masih mempertahankan kontrol output, saya membuat fungsi menggunakan TRAP.

MISALNYA

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

Anda keluar jalur di sini.

Anda sudah mendapatkan pesan kesalahan besar yang bagus. Mengapa Anda ingin menulis kode yang memeriksa $?secara eksplisit setelah setiap perintah ? Ini sangat rumit dan rawan kesalahan. Solusi yang tepat adalah berhenti mengecek$? .

Sebagai gantinya, gunakan mekanisme bawaan PowerShell untuk meledakkannya untuk Anda. Anda mengaktifkannya dengan mengatur preferensi kesalahan ke level tertinggi:

$ErrorActionPreference = 'Stop'

Saya meletakkan ini di bagian atas setiap skrip yang pernah saya tulis, dan sekarang saya tidak perlu memeriksanya $?. Ini membuat kode saya jauh lebih sederhana dan lebih dapat diandalkan.

Jika Anda mengalami situasi di mana Anda benar - benar perlu menonaktifkan perilaku ini, Anda dapat melakukan catchkesalahan atau meneruskan pengaturan ke fungsi tertentu menggunakan common -ErrorAction. Dalam kasus Anda, Anda mungkin ingin proses Anda berhenti pada kesalahan pertama, menangkap kesalahan, dan kemudian mencatatnya.

Perhatikan bahwa ini tidak menangani kasus ketika executable eksternal gagal (kode keluar bukan nol, secara konvensional), jadi Anda masih perlu memeriksa $LASTEXITCODEapakah Anda memanggil. Terlepas dari batasan ini, pengaturannya masih menyimpan banyak kode dan upaya.

Keandalan tambahan

Anda mungkin juga ingin mempertimbangkan untuk menggunakan mode ketat :

Set-StrictMode -Version Latest

Ini mencegah PowerShell melanjutkan secara diam-diam saat Anda menggunakan variabel yang tidak ada dan dalam situasi aneh lainnya. (Lihat -Versionparameter untuk detail tentang apa yang dibatasi.)

Menggabungkan dua pengaturan ini membuat PowerShell lebih dari bahasa gagal-cepat, yang membuat pemrograman di dalamnya jauh lebih mudah.

jpmc26.dll
sumber
2

Tambahkan -ErrorAction SilentlyContinueke skrip Anda dan Anda akan baik-baik saja.

Jayant Rajwani
sumber
2

Dalam beberapa kasus, Anda dapat menyalurkan setelah perintah a Out-Null

command | Out-Null
Berry
sumber
-1

Jika Anda ingin errormessage powershell untuk cmdlet disembunyikan, tetapi masih ingin mengetahui kesalahannya, gunakan "-erroraction 'silentlyStop'"

Mikkel Vejlby
sumber
Tidak ada tindakan seperti itu. Meskipun ada tindakan Berhenti.
Marvin Dickhaus
Tapi itu memungkinkan untuk menekan pesan kesalahan merah dan masih menggunakan perintah / bagian tangkap saat menggunakan New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager
@MilanKerslager Bisakah Anda menunjukkan contoh kode - karena saya, dan semua orang, percaya bahwa tidak ada ActionPreference seperti 'SilentlyStop'
FSCKur
Saya cukup yakin bahwa Mikkel memaksudkan SilentlyContinue daripada silentlyStop, karena itu lebih masuk akal dalam isi dari apa yang Anda ingin lakukan.
John