Powershell: Hataların bir komut dosyasında görüntülenmesini nasıl durdurabilirim?


94

Örneğin, PowerShell betiğim, var olmayan bir sunucu için bir SQL Server nesnesi oluşturmaya çalıştığında (benim durumumda "bla"), PowerShell birçok PowerShell hatasını kırmızı olarak görüntüler.

Komut dosyam bu $?tür aramalardan sonra değerini kontrol ettiğinden ve hataları görüntüleyip günlüğe kaydettiğinden, PowerShell hatalarının birkaç satırının da görüntülenmesini tercih ederim.

Komut dosyam için görüntülenenleri nasıl devre dışı bırakabilirim?

Yanıtlar:


140

Birkaç seçeneğin var. En kolayı ErrorActionayarları kullanmayı içerir .

-Erroractiontüm cmdlet'ler için evrensel bir parametredir. Göz ardı etmek istediğiniz özel komutlar varsa -erroraction 'silentlycontinue', bu komut tarafından oluşturulan tüm hata mesajlarını temelde yok sayacak olan kullanabilirsiniz . IgnoreDeğeri de kullanabilirsiniz (PowerShell 3+ sürümünde):

SilentlyContinue'dan farklı olarak, Yoksay hata mesajını $ Error otomatik değişkenine eklemez.

Bir komut dosyasındaki tüm hataları yok saymak istiyorsanız, sistem değişkenini kullanabilir $ErrorActionPreferenceve aynı şeyi yapabilirsiniz:$ErrorActionPreference= 'silentlycontinue'

-ErrorAction hakkında daha fazla bilgi için about_CommonParameters konusuna bakın . $ ErrorActionPreference hakkında daha fazla bilgi için about_preference_variables'a bakın .


'sessizce devam' hatasında tek alıntıya ihtiyacınız var mı? Intellisese seçenekleri gösteriyor ve tek teklif eklemiyor.
PAS

1
Yukarıdaki biçim sizin için uygun değilse, yukarıda verilen bağlantıya bakın. -ErrorAction:SilentlyContinuePS 5.1'deki gibi formatlamam gerekiyordu . Cmdlet'imi toplu işten çağırıyordum, bu yüzden bunun bir fark yaratıp yaratmadığını bilmiyorum. Ancak kabul edilebilir bir hata olduğunu bildiğiniz zaman iyi bilgi atılabilir.
David

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

18

Tek için mekanizma: Windows PowerShell hataları bildirmek için iki mekanizma sağlar sonlandırma hataları ve için başka bir mekanizma olmayan sonlandırma hatalarının .

Dahili CmdLets kodu ThrowTerminatingError, cmdlet'in girdi nesnelerini işlemeye devam etmesine izin vermeyen veya vermemesi gereken bir hata oluştuğunda bir yöntemi çağırabilir . Komut dosyası yazarı, bu hatayı yakalamak için istisna kullanabilir.

EX:

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

İç CmdLets kodu WriteError, cmdlet giriş nesnelerini işlemeye devam ettiğinde sonlandırmayan hataları bildirmek için bir yöntem çağırabilir . Komut dosyası yazıcısı daha sonra mesajları gizlemek için -ErrorAction seçeneğini kullanabilir veya $ErrorActionPreferencetüm komut dosyası davranışını ayarlamak için kullanabilir .


8

Kullanarak ana bilgisayar adlarını çözmeye çalışırken benzer bir sorun yaşadım [system.net.dns]. IP çözülmediyse .Net bir sonlandırma hatası attı. Sonlandırma hatasını önlemek ve çıktının kontrolünü sürdürmek için kullanarak bir işlev oluşturdum TRAP.

ÖRNEĞİN

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

3

Burada yoldan sapmışsın.

Zaten güzel, büyük bir hata mesajınız var. Neden her bir komuttan$? sonra açıkça kontrol eden bir kod yazmak istersiniz ? Bu son derece zahmetli ve hataya açık. Doğru çözüm, kontrolü durdurmaktır .$?

Bunun yerine, sizin için havaya uçmak için PowerShell'in yerleşik mekanizmasını kullanın. Hata tercihini en yüksek seviyeye ayarlayarak etkinleştirirsiniz :

$ErrorActionPreference = 'Stop'

Bunu yazdığım her senaryonun en üstüne koyuyorum ve şimdi kontrol etmem gerekmiyor $?. Bu, kodumu çok daha basit ve daha güvenilir hale getiriyor.

Bu davranışı gerçekten devre dışı bırakmanız gereken durumlarla karşılaşırsanız catch, hata yapabilir veya ortak olanı kullanarak belirli bir işleve bir ayar iletebilirsiniz -ErrorAction. Sizin durumunuzda, muhtemelen işleminizin ilk hatada durmasını, hatayı yakalamasını ve ardından günlüğe kaydetmesini istiyorsunuz.

Bunun, harici yürütülebilir dosyalar başarısız olduğunda (geleneksel olarak sıfırdan farklı çıkış kodu) durumu ele almadığını unutmayın; bu nedenle, $LASTEXITCODEherhangi birini çağırıp çalıştırmadığınızı yine de kontrol etmeniz gerekir . Bu sınırlamaya rağmen, ayar hala çok fazla kod ve çaba tasarrufu sağlıyor.

Ek güvenilirlik

Ayrıca katı modu kullanmayı da düşünebilirsiniz :

Set-StrictMode -Version Latest

Bu, var olmayan bir değişken kullandığınızda ve diğer garip durumlarda PowerShell'in sessizce ilerlemesini engeller. ( -VersionNeyi kısıtladığı hakkında ayrıntılar için parametreye bakın .)

Bu iki ayarı birleştirmek, PowerShell'i çok daha hızlı bir dil haline getirir ve bu da içindeki programlamayı büyük ölçüde kolaylaştırır.



2

Bazı durumlarda, Out-Null komutundan sonra boru

command | Out-Null

-1

Bir cmdlet için powershell hata mesajının bastırılmasını ama yine de hatayı yakalamak istiyorsanız, "-erroraction 'silentlyStop'" kullanın.


Böyle bir eylem yok. Bir Durdurma eylemi olmasına rağmen.
Marvin Dickhaus

Ancak, kırmızı hata mesajını bastırmaya ve New-Item -ItemType directory(PowerShell v2.0) kullanırken hala catch komutunu / bölümünü kullanmaya izin veriyor
Milan Kerslager

@MilanKerslager, bir kod örneği gösterebilir misiniz - çünkü ben ve diğer herkes, 'SilentlyStop' diye bir ActionPreference olmadığına inanıyorum
FSCKur

Mikkel'in sessizce Durmak yerine Sessizce Devam Et demek istediğine makul ölçüde eminim, çünkü bu, yapmasını istediğiniz şeyin içeriği açısından çok daha anlamlı.
John
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.