Asked by:
Monitor based on PowerShell occasionally show ExitCode -1 when Launch a Process

Question
-
good dat every one.
I have encounter some problem.
i need to monitor status of a programm (HP OM Agent). i write a ps script wich launch a process ovc.exe, then i parse output.
in ISE all is ok. bhut when i use this script in monitor(s) i occasionally got ExitCode -1 (but monitored program is fine).
here is my code
## <![CDATA[ # functions chapter function KillChildProcs { $CProcId = ([System.Diagnostics.Process]::GetCurrentProcess()).Id $ChProcs = Get-WmiObject -Class Win32_Process -Filter "ParentProcessID=$CProcId" if ($ChProcs){ foreach ($ChProc in $ChProcs ){ "Child Process PID is " + $ChProc.ProcessId + " and its name is " + $ChProc.path "Killing this proc" kill $ChProc.ProcessId -Force } }else { "No child process" } } # init SCOM vars $Result = 0 $Description = $null $msgaError = $null $agtPath = $null $strLBinDir=$null $ProcessInfo=$null $Process=$null $msgaSts=$null $api=$null $bag=$null $api = New-Object -comObject 'MOM.ScriptAPI' $api.LogScriptEvent('ChkOMAgtBuffState.ps1', 47, 4, "chk OMAgtBuff started") # run opcmsga.exe - status and check it output try{ # getting agent path try{ $agtPath = (Get-Item 'Registry::HKLM\SOFTWARE\Hewlett-Packard\HP OpenView').GetValue('InstallDir') }catch{ $ErrorMessage = $_.Exception.Message $FailedItem = $_.Exception.ItemName $api.LogScriptEvent('chkOMAgt.ps1',48,4,"Cant get HP Agent Path from regestry, fallback to default "+$ErrorMessage) $Description = $Description + "ERROR getting Agent Path from Regestry : "+$ErrorMessage + "`r`n" }finally{ if (!$agtPath){ $agtPath = "DefPath"} } #try to launch opcmsga.exe try{ $strLBinDir = $agtPath + "lbin\eaagt" $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo $ProcessInfo.FileName = $strLBinDir + "\opcmsga.exe" $ProcessInfo.RedirectStandardError = $true $ProcessInfo.RedirectStandardOutput = $true $ProcessInfo.UseShellExecute = $false $ProcessInfo.Arguments = "-status" $Process = New-Object System.Diagnostics.Process $Process.StartInfo = $ProcessInfo $Process.Start() | Out-Null if ($Process.WaitForExit(12000)){ "ExitCode = " + $Process.ExitCode if ($Process.ExitCode -eq 0){ $msgaSts = $Process.StandardOutput.ReadToEnd() if ($msgaSts -like '*Message Agent is not buffering*'){ $Result=0 $Description = $Description +$msgaSts +"`r`n" }else{ $Result=1 $Description = $Description + $msgaSts +"`r`n" } }else{ $Result=1 $Description = $Description + "ERROR : opcmsga.exe return error Exit Code is "+$Process.ExitCode+ "Error Output is " + $Process.StandardError.ReadToEnd() + "`r`n" } } else{ $Result=1 $Description = $Description + "ERROR : opcmsga.exe Timeout" + $Process.StandardError.ReadToEnd() + "`r`n" } $Process.close() }catch{ $ErrorMessage = $_.Exception.Message $FailedItem = $_.Exception.ItemName $Result=1 $Description = $Description + "ERROR launching opcmsga.exe " + $ErrorMessage + "`r`n" }finally{ $api.LogScriptEvent('ChkOMAgtBuffState.ps1', 47, 4, "COM object created") $bag = $api.CreatePropertyBag() $api.LogScriptEvent('ChkOMAgtBuffState.ps1', 47, 4, "Bag created") $bag.addvalue("Result", $Result) $bag.addvalue("Description", $Description) $api.LogScriptEvent('ChkOMAgtBuffState.ps1', 47, 4, "Bag set " + $bag) $bag } }catch{ }finally{ $Result $Description #clearing Varibles KillChildProcs Remove-variable Result Remove-variable Description Remove-variable msgaError Remove-variable agtPath Remove-variable strLBinDir Remove-variable ProcessInfo Remove-variable Process Remove-variable msgaSts Remove-variable api Remove-variable bag } ## ]]>
and another one
##<![CDATA[ #function declaration function KillChildProcs { $CProcId = ([System.Diagnostics.Process]::GetCurrentProcess()).Id $ChProcs = Get-WmiObject -Class Win32_Process -Filter "ParentProcessID=$CProcId" if ($ChProcs){ foreach ($ChProc in $ChProcs ){ "Child Process PID is " + $ChProc.ProcessId + " and its name is " + $ChProc.path "Killing this proc" kill $ChProc.ProcessId -Force } }else { "No child process" } } $Process=$null $matches=$null $bag=$null $Description=$null $regexp = "(?<Process>^\w+)(?:\s+)(?<Description>(?:\w+)(?:(?:\s\w+){1,}))(?:\s+)(?<Type>\w\S+)(?:\s+)(?<PID>\S+)(?:\s+)(?<Status>\w+$)" $ErrorMessage=$null $FailedItem=$null $agtPath =$null $isRegexped=$null $ovcError=$null $api = New-Object -comObject 'MOM.ScriptAPI' $api.LogScriptEvent('chkOMAgt.ps1',48,4,"Script Started") try{ $agtPath = (Get-Item 'Registry::HKLM\SOFTWARE\Hewlett-Packard\HP OpenView').GetValue('InstallDir') }catch{ $ErrorMessage = $_.Exception.Message $FailedItem = $_.Exception.ItemName $api.LogScriptEvent('chkOMAgt.ps1',48,4,"Cant get HP Agent Path from regestry, fallback to default "+$ErrorMessage) $Description = $Description + "ERROR getting Agent Path from Regestry : "+$ErrorMessage + "`r`n" $agtPath = "DefPath" } $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo $ProcessInfo.FileName = "ovc.exe" $ProcessInfo.RedirectStandardError = $true $ProcessInfo.RedirectStandardOutput = $true $ProcessInfo.StandardOutputEncoding=[System.Text.Encoding]::GetEncoding("windows-1252") $ProcessInfo.UseShellExecute = $false $ProcessInfo.Arguments = "-status" $Process = New-Object System.Diagnostics.Process $Process.StartInfo = $ProcessInfo # Creating string builders to store stdout and stderr. $StdOutBuilder = New-Object System.Text.StringBuilder $StdErrBuilder = New-Object System.Text.StringBuilder # Adding event handers for stdout and stderr. $action = { if (! [String]::IsNullOrEmpty($EventArgs.Data)) { $Event.MessageData.AppendLine($EventArgs.Data) } } #declare stdErr and stdOut Events $StdOutEvent = Register-ObjectEvent -InputObject $Process -Action $action -EventName 'OutputDataReceived' -MessageData $StdOutBuilder $StdErrEvent = Register-ObjectEvent -InputObject $Process -Action $action -EventName 'ErrorDataReceived' -MessageData $StdErrBuilder try{ $Process.Start() | Out-Null $api.LogScriptEvent('chkOMAgt.ps1',48,4,"ovc started ") $Process.BeginOutputReadLine() $Process.BeginErrorReadLine() $Process.WaitForExit() # Removing and unregistering events to retieve process output. Remove-Event -SourceIdentifier $StdOutEvent.Name -EA SilentlyContinue Remove-Event -SourceIdentifier $StdErrEvent.Name -EA SilentlyContinue Unregister-Event -SourceIdentifier $StdOutEvent.Name Unregister-Event -SourceIdentifier $StdErrEvent.Name $api.LogScriptEvent('chkOMAgt.ps1',48,4,"StdOut is " +$StdOutBuilder.ToString()) $api.LogScriptEvent('chkOMAgt.ps1',48,4,"ErrOut " +$StdErrBuilde.ToString()) $api.LogScriptEvent('chkOMAgt.ps1',48,4,"ExitCode is " +$Process.ExitCode) $StdOut = $StdOutBuilder.ToString().split("`r`n"); $StdErr = $StdErrBuilder.ToString().split("`r`n"); $ExitCode = $Process.ExitCode if($ExitCode -eq 0){ foreach ($ab in $StdOut){ $isRegexped = $ab -match $regexp if($isRegexped){ $api.LogScriptEvent('chkOMAgt.ps1',48,4,"got output line" +$line) if ($matches['Status'] -ne "Running") {$Result=1} $Description = $Description + $matches['Process']+"`t"+$matches['Status'] + "`r`n" $matches=$null } } }else{ $api.LogScriptEvent('chkOMAgt.ps1',88,4,"ExitCode is" +$ExitCode) $api.LogScriptEvent('chkOMAgt.ps1',88,4,"StdOut is" +$StdOut) $Description = $Description + 'ovc exited with errors'+ "`r`n" + $StdErr $api.LogScriptEvent('chkOMAgt.ps1',48,4,"ovc exited with errors") $Result=1 } }catch{ $ErrorMessage = $_.Exception.Message $FailedItem = $_.Exception.ItemName $Result=1 $Description = $Description + "ERROR parsing ovc.exe " + $ErrorMessage + "`r`n" } "---------------------------------" $Process.close() if ($Result -ne 1){$Result=0} $Description $Result $bag = $api.CreatePropertyBag() $bag.addvalue("Result" , $Result) $bag.addvalue("Description" , $Description) $bag $api.LogScriptEvent('chkOMAgt.ps1',48,4,"Script Finished `r`nResult ="+$Result+"`r`nDescription is `r`n"+$Description) #"cleaning child process and remove varibles" KillChildProcs Remove-Variable regexp Remove-Variable Result Remove-Variable Description Remove-Variable ovcError Remove-Variable isRegexped Remove-Variable ProcessInfo Remove-Variable Process Remove-Variable matches Remove-Variable bag ## ]]>
- Edited by scorpio the dark Tuesday, July 8, 2014 8:23 AM
Monday, July 7, 2014 10:06 AM
All replies
-
Hi,
As far as I can see in the script, you write a command to return the $Process.ExitCode
It seems like that the script works but with error message, would you please share the full error message here for further analysis.
If the script works in Powershell ISE and also works in Powershell Console, I think this is not scripting error, but we need to know what the whole script is doing(I have to say that I am not a developer), would you please tell more about the script.
And please also compare the conditions when you run the script manully and in the monitor, such as whether the process is stared each time, what account is used to run the script. If you run it in the monitor, then the account used should be the action account for the monitor.
Hope this may help.
Regards,
Yan Li
Regards, Yan Li
- Edited by Yan Li_ Tuesday, July 8, 2014 1:20 PM edit
Tuesday, July 8, 2014 1:20 PM -
I have no data in stdOut nor in ErrOut.
when i simulate error i got ExitCode greater than 0 and error description
but in real life some times script work fine and ovc put in stdout some data but sometime inside the monitor this script throw ExitCode -1 and no output at all.
in that time i call ovc in RDP session and it was work ok.
i tried to change $ProcessInfo.FileName = "ovc.exe" to cmd /c ovc.exe but all in vain
Tuesday, July 8, 2014 1:48 PM -
Hi,
Please refer to the following link:
Best Regards,
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
Tuesday, July 15, 2014 9:43 AM -
Hi,
Is there any update?
Best Regards,
Vincent Wu
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
Thursday, July 17, 2014 9:25 AM -
i will reply you later on monday 21, when i can reach test eviromentThursday, July 17, 2014 2:00 PM
-
i saw this video but do not find any mention about Process.ExitCode
my script works fine if i call it from PowerShell but if it run in SCOM ExitCode turn to -1.
i insert in my script recursion and find that it takes 2-3 times to get ExitCode >= 0
why it can be so?
Monday, July 21, 2014 7:15 AM -
Hi,
Please refer to the following link:
http://technet.microsoft.com/en-us/sqlserver/system.diagnostics.process.exitcode(v=vs.108).aspx
Best Regards,
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
Thursday, August 7, 2014 2:09 AM -
Hi,
Any update?
Best Regards,
Vincent Wu
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
Monday, August 11, 2014 2:09 AM -
i have read this topic but cant find any reference to -1 value for exit code.
even more i have some document for ovc programm, HP provide.
there are NO exit codes less than 0. so it might be a OS value?
now we have encounter 100% CPU load by monitoringhost.exe
http://support.microsoft.com/kb/968967
provide some hotfixes but OS where i encount this issue is windows 2008 R2
is this hotfix applicatable for 2008 R2
Monday, September 1, 2014 12:18 PM