This seemed like easy one, but it wasn't. I have the following function that stops processes and write in eventlog:
$PiEventlog = "Company Name"
$PiEventlogSource = "Source Name"
# For Testing purpose, i use this PIDs.
$gpid = 45852,5264
function Terminate-Processs {
# if $pid is empty, give this msg.
if(!$gpid){
Write-Host "Nth here"
}
else{
for ($i = 0; $i -lt ($gpid).Count; $i ) {
$PIDForEventLog = $gpid
try{
Stop-Process -Id $gpid[$i] -force -ErrorAction SilentlyContinue -ErrorVariable $ResultStopProcess
Write-EventLog -logname $PiEventlog -source $PiEventlogSource -eventID 1021 -entrytype Information -message "$env:USERNAME killed the following PID $PIDForEventLog from the instance $Global:SelectedInstance"
}
catch{
Write-EventLog -logname $PiEventlog -source $PiEventlogSource -eventID 1021 -entrytype Error -message "$env:USERNAME could not kill the following PID $PIDForEventLog from the instance $Global:SelectedInstance `n$ResultStopProcess `nPlease check manually whether the process is still available."
}
}
}
}
in the Catch loop, i am trying to give the errorvariable $resultstopprcess to the eventlog entry. That means, if an error occur while stoping an process, the error should be saved into that variable and it should be given to eventlog. the variable should contain sth like this, if error occurs:
Stop-Process : Es kann kein Prozess mit der Prozess-ID 34234 gefunden werden. In Zeile:1 Zeichen:1
- Stop-Process -id 34234
CategoryInfo : ObjectNotFound: (34234:Int32) [Stop-Process], ProcessCommandException FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Commands.StopProcessCommand
But the variable is somehow always empty. How can i do this? How can i save the error to a variable. so that i can use it later?
CodePudding user response:
Error Analysis
-ErrorVariable $ResultStopProcess
The parameter ErrorVariabe expects the name of the variable without $ prefix.
try {} catch {}
With -ErrorAction SilentlyContinue, the catch block will never be entered.
Possible solutions:
- Pass
-ErrorAction Stopto throw an exception in case of any error - Keep
-ErrorAction SilentlyContinueand check the automatic execution status variable$?for success.
Write-EventLog -message ".... $ResultStopProcess ..."
This only outputs the exception message ("Es kann kein Prozess mit der Prozess-ID 34234 gefunden werden.").
To include everything you normally see on the console, pass $ResultStopProcess to the Out-String command.
Fixed code
Stop-Process -Id $gpid[$i] -force -ErrorAction SilentlyContinue -ErrorVariable ResultStopProcess
if( $? ) {
Write-EventLog -logname $PiEventlog -source $PiEventlogSource -eventID 1021 -entrytype Information -message "$env:USERNAME killed the following PID $PIDForEventLog from the instance $Global:SelectedInstance"
}
else {
$ErrorView = 'NormalView' # PS 7.2 defaults to 'ConciseView'
$fullErrorMessage = $ResultStopProcess | Out-String
Write-EventLog -logname $PiEventlog -source $PiEventlogSource -eventID 1021 -entrytype Error -message "$env:USERNAME could not kill the following PID $PIDForEventLog from the instance $Global:SelectedInstance `n$fullErrorMessage `nPlease check manually whether the process is still available."
}
Remarks
- Make sure to check
$?immediately after the command that could possibly fail, else it could be overwritten by another command. - As of PowerShell 7.2, you don't get the full error message, even when using
Out-String, as the default formatting mode is nowConciseView. Therefore I've set the preference variable$ErrorView = 'NormalView'to get the same output as in previous PS versions.
