by turbomcp at 2012-09-21 11:14:22
Hiby DonJ at 2012-09-21 11:31:45
i apologize in advance since i had a diffrent post regrading this script
i am more interested to know how to debug these scripts then actually the script itself.
it works in my lab but on production it seems to fail randomly
script below:#requires -version 2.0
<#
date: 10/09/2012
purpose: Retrieve event id’s from multiple machines and add to a CSV file.
#>
$VerbosePreference='Continue'
Try
{
$servers=Get-ExchangeServer server23*
$date=(Get-Date).AddDays(-1)
Write-Verbose "Starting loop"
foreach ($server in $servers){
Write-Verbose "Now on server $server"
if (test-connection $server -quiet)
{Write-Verbose "Test-Connection successful, getting event log from $server"
$get1+=get-eventlog -logname application -cn $server -after $date | ?{$.eventid -eq "902" -and $.entrytype -eq "error"} | select MachineName,EventID,EntryType,Message
Write-Verbose "Finished getting event log on server $server"
}
if ($get1)
{$get1 | export-csv r:\scripts\app.csv -notypeinformation}
else
{"No matching system log events found…"}
}
}
Catch
{
"An error occurred"
}
its supposed to go over the list of exchange servers and get specific event if it exists.
i see it going server by server(up to server 6)
connectivity test passes and servers that dont have event like that i get the right output which is "no matching system log events found"
but after getting events from server #6 i get "an error occured"
Great question! Here’s what I’d do:by turbomcp at 2012-09-21 11:50:17#requires -version 2.0
<#
date: 10/09/2012
purpose: Retrieve event id’s from multiple machines and add to a CSV file.
#>
$VerbosePreference='Continue'
$date=(Get-Date).AddDays(-1)
Try {
$servers=Get-ExchangeServer server23* -ErrorAction Stop -ErrorVariable ExError
} Catch {
Write-Warning "Error querying Exchange; quitting"
Write-Warning "Error was $ExError"
break
}
Write-Verbose "Starting loop"
foreach ($server in $servers){
Write-Verbose "Now on server $server"
if (test-connection $server -quiet) {
Write-Verbose "Test-Connection successful, getting event log from $server"
Try {
$get1+= get-eventlog -logname application -cn $server -after $date -ErrorAction Stop -ErrorVariable my err |
Where {$.eventid -eq "902" -and $.entrytype -eq "error"} |
select MachineName,EventID,EntryType,Message
} Catch {
Write-Warning "An error occurred"
Write-Warning "The error was $myerr"
Write-Warning "The current server was $server"
}
Write-Verbose "Finished getting event log on server $server"
}
if ($get1.count -gt 0) {
$get1 | export-csv r:\scripts\app.csv -notypeinformation
} else {
Write-Output "No matching system log events found…"
}
}
}
Some of what I did here:
I used -ErrorAction on the command that I expect is causing the error. This makes Try…Catch function. I also used -ErrorVariable to capture the error. You can see in the Catch block where I displayed that information.
I also tightened in the Try…Catch block. You want to put one of those around as few commands as possible. That way, the Catch block has to deal with a smaller potential range of errors. I added a second Try…Catch block around another, earlier command that might also cause an error. You want the Try section to include as few commands as possible, so then when something breaks, you have a narrower range of commands to troubleshoot.
I also spelled out commands like Where, instead of using cryptic aliases like ?. That makes the script easier to read, and easier to read means easier to troubleshoot. I also explicitly added Write-Output where you were implicitly using it, and changed the error messages to use Write-Warning, which I personally prefer from a visual perspective.
The idea is just to get as much insight as possible into what your script is doing, and to have it do just one thing at a time, if possible. That way you’ve got fewer possibilities when things break.
wowby DonJ at 2012-09-21 11:54:57
thanks a lot(for debugging this and quick reply),
i changed to this cause it complained about }#requires -version 2.0
<#
date: 10/09/2012
purpose: Retrieve event id’s from multiple machines and add to a CSV file.
#>
$VerbosePreference='Continue'
$date=(Get-Date).AddDays(-1)
Try {
$servers=Get-ExchangeServer server23* -ErrorAction Stop -ErrorVariable ExError
} Catch {
Write-Warning "Error querying Exchange; quitting"
Write-Warning "Error was $ExError"
break
}
Write-Verbose "Starting loop"
foreach ($server in $servers){
Write-Verbose "Now on server $server"
if (test-connection $server -quiet) {
Write-Verbose "Test-Connection successful, getting event log from $server"
Try {
$get1+= get-eventlog -logname application -cn $server -after $date -ErrorAction Stop -ErrorVariable my err |
Where {$.eventid -eq "902" -and $.entrytype -eq "error"} |
select MachineName,EventID,EntryType,Message
} Catch {
Write-Warning "An error occurred"
Write-Warning "The error was $myerr"
Write-Warning "The current server was $server"
}
Write-Verbose "Finished getting event log on server $server"
}
if ($get1.count -gt 0) {
$get1 | export-csv r:\scripts\app.csv -notypeinformation
} else {
Write-Output "No matching system log events found…"
}
}
weird thing is
it works fine and much much faster now
now i really dont know what to think:)
so i checked and no events at all(even when i change it to -7 days) where i know there are events there from yesterday.
all servers return "no matching system log events found…"
My if() clause might be a bit off - I’m working without a copy of PowerShell to test with. You might try changing it back to just if ($get1) like you had it.