Sign in to follow this  
Followers 0
nitro322

WMI error

6 posts in this topic

#1 ·  Posted (edited)

I've run into an odd error that I'm having trouble resolving. I could really use some help from the gurus on this one.

I'm using WMI to pull a list of processes running on a system (code snippit below), and give me the process Name, PID, Owner, and full command line (if >=XP). This works great on 99% of the systems I've tried it on, all of which are running 2000, XP, and 2003.

I just ran it on a 2003 server, and it crashed with this error:

Line 0 (File "C:\sysinfo_40.exe"):

$objItem.GetOwner($process[$i-1][2])

$objItem.GetOwner($process[$i-1][2])^ ERROR

Error: The requested action with this object has failed.

Not a particularly helpful message, but obviously it's failing when trying to get the Owner of the process. I did some more investigating, and found that it is actually getting the Owner just fine for a great many processes on the system. It isn't until it enounters one specific process, pdmweb2.exe, that it crashes. I looked up this program in Task Manager, found it, and see that it's running as a local account in the Guest group.

So, I have two questions. 1) Any idea why this is crashing? I'm more curious than anything else about this. 2) How can I make it not crash? Obviously, this one's the kicker. ;) What I'd like to do is just simply skip that line when the lookup fails, not crash and abort the entire program. This shouldn't be difficult to do, really no different than NOT crashing when an external run command is not found; however, I cannot find an option equivilent to RunErrorsFatal.

Any ideas here? This script (of which this section is only a small portion) is of particular importance in my environment, and I really need to make sure it'll run reliably on any system. Even if one part of the script fails, which is OK, I need the whole script to run until completion. Any help would be greatly appreciated.

Here's the full section of code dealing with WMI, in case it helps. Thanks!

; get list of process through WMI interface
dim $colItems
$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x10 + 0x20)

; convert WMI object to array, lookup owner, and analyze
$i = 1
$maxproclen = 12
$maxownerlen = 5
dim $owner, $process[$i][5]
if IsObj($colItems) then
    for $objItem in $colItems
        redim $process[$i][5]
        $process[$i-1][0] = $objItem.Name
        $process[$i-1][1] = $objItem.ProcessId
        $objItem.GetOwner($process[$i-1][2]); <-- Where it's failing
        if @OSVersion = "Win_XP" then
            $process[$i-1][3] = $objItem.CommandLine
        else
            $process[$i-1][3] = ""
        endif
        $i += 1
    next
endif
Edited by nitro322

Share this post


Link to post
Share on other sites



It isn't until it enounters one specific process, pdmweb2.exe, that it crashes.

1. It looks like pdmweb2.exe belongs to TouchBase, who specialize in "Global Enterprise Communications" solutions. They may be able to shed some light. They may also have written a "bad" program!

2. Does it crash on every machine that has pdmweb2.exe, or just some of them?

3. Are there any commonalities between the crashing machines other than the OS=Server 2003?

4. Can you "get" any other WMI properties from "Win32_Process" on that machine? You can use Scriptomatic 2.0 or AutoIT Scriptomatic to check this out. Try getting, for example, the PageFileUseage, or CSName, or ProcessID, etc.

5. If all of those WMI requests crash the script, perhaps 2003 Server has another layer of intrusion protection?

It sounds as though Server 2003 does not like you snooping around that process. Do you have Bill Gates phone number? I think he's on an IPv6 VoIP phone... ;)


...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format

Share this post


Link to post
Share on other sites

pdmweb2.exe is part of the web engine used by USD, a ticket request system by CA. It is, in fact, a "bad" program, but my script must still be able to handle it gracefully. So far, this script has only crashed on this one process (on the one OS, etc.), but it consistently crashes everytime.

To answer #4, I'm not 100% sure what you mean, but for testing I'm using the following code:

$process[$i-1][0] = $objItem.Name
$process[$i-1][1] = $objItem.ProcessId
msgbox(0,'',$objItem.Name & @CRLF & $objItem.ProcessId)
$objItem.GetOwner($process[$i-1][2])

It'll grab the Name and ProcessId and then display it for pdmweb2.exe without any problem, but after clicking OK it immediately crashes on the next line. So yeah, it seems to be just this one attribute that's failing.

To be honest, I'm ok with it failing to get the process Owner for this one process. What I'd really like to do is make AutoIt recognize that the value it's trying to get is invalid, and then just move along. Return a 0 or a NULL or whatever for that particular value, but continue running the script.

How can I do this? Thanks.

Share this post


Link to post
Share on other sites

pdmweb2.exe is part of the web engine used by USD, a ticket request system by CA. It is, in fact, a "bad" program, but my script must still be able to handle it gracefully. So far, this script has only crashed on this one process (on the one OS, etc.), but it consistently crashes everytime.

To answer #4, I'm not 100% sure what you mean, but for testing I'm using the following code:

$process[$i-1][0] = $objItem.Name
$process[$i-1][1] = $objItem.ProcessId
msgbox(0,'',$objItem.Name & @CRLF & $objItem.ProcessId)
$objItem.GetOwner($process[$i-1][2])

It'll grab the Name and ProcessId and then display it for pdmweb2.exe without any problem, but after clicking OK it immediately crashes on the next line. So yeah, it seems to be just this one attribute that's failing.

To be honest, I'm ok with it failing to get the process Owner for this one process. What I'd really like to do is make AutoIt recognize that the value it's trying to get is invalid, and then just move along. Return a 0 or a NULL or whatever for that particular value, but continue running the script.

How can I do this? Thanks.

is @error being set by the failed call? you may also try using OnAutoItExit() func to output values at the time of the crash. also a workaround you may try, if it's going to fail every time it hits that process, why not just add a condition that checks the process name first? if you're able to get the process name, and it's the bad one, just skip the checks that fail for that process...technically it'll slow your script a little to have that condition checked for every process, but the difference should be negligible and it will make your script complete successfully...

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

Well, I couldn't get OnAutoItExit() to give me any information (it doesn't seem to run properly when the program crashes), but your suggestion of checking for and skipping the process name works fine. Of course, the better solution would be to somehow trap the error and continue, as this will still fail if it encounters a similar process with a different now, but it at least solves my immediate problem.

Thanks for the suggestions. If anyone has any other ideas, though, don't hesitate to speak up. :-)

Share this post


Link to post
Share on other sites

Can you put a msgbox in front of this line to see if it's actually returning what you think it is:

$objItem.GetOwner($process[$i-1][2]); <-- Where it's failing

Also, by question 4 above, what I meant was, how many of the following items are returned for pdmweb2.exe?:

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
      $Output = $Output & "CommandLine: " & $objItem.CommandLine & @CRLF
      $Output = $Output & "CreationClassName: " & $objItem.CreationClassName & @CRLF
      $Output = $Output & "CreationDate: " & WMIDateStringToDate($objItem.CreationDate) & @CRLF
      $Output = $Output & "CSCreationClassName: " & $objItem.CSCreationClassName & @CRLF
      $Output = $Output & "CSName: " & $objItem.CSName & @CRLF
      $Output = $Output & "Description: " & $objItem.Description & @CRLF
      $Output = $Output & "ExecutablePath: " & $objItem.ExecutablePath & @CRLF
      $Output = $Output & "ExecutionState: " & $objItem.ExecutionState & @CRLF
      $Output = $Output & "Handle: " & $objItem.Handle & @CRLF
      $Output = $Output & "HandleCount: " & $objItem.HandleCount & @CRLF
      $Output = $Output & "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
      $Output = $Output & "KernelModeTime: " & $objItem.KernelModeTime & @CRLF
      $Output = $Output & "MaximumWorkingSetSize: " & $objItem.MaximumWorkingSetSize & @CRLF
      $Output = $Output & "MinimumWorkingSetSize: " & $objItem.MinimumWorkingSetSize & @CRLF
      $Output = $Output & "Name: " & $objItem.Name & @CRLF
      $Output = $Output & "OSCreationClassName: " & $objItem.OSCreationClassName & @CRLF
      $Output = $Output & "OSName: " & $objItem.OSName & @CRLF
      $Output = $Output & "OtherOperationCount: " & $objItem.OtherOperationCount & @CRLF
      $Output = $Output & "OtherTransferCount: " & $objItem.OtherTransferCount & @CRLF
      $Output = $Output & "PageFaults: " & $objItem.PageFaults & @CRLF
      $Output = $Output & "PageFileUsage: " & $objItem.PageFileUsage & @CRLF
      $Output = $Output & "ParentProcessId: " & $objItem.ParentProcessId & @CRLF
      $Output = $Output & "PeakPageFileUsage: " & $objItem.PeakPageFileUsage & @CRLF
      $Output = $Output & "PeakVirtualSize: " & $objItem.PeakVirtualSize & @CRLF
      $Output = $Output & "PeakWorkingSetSize: " & $objItem.PeakWorkingSetSize & @CRLF
      $Output = $Output & "Priority: " & $objItem.Priority & @CRLF
      $Output = $Output & "PrivatePageCount: " & $objItem.PrivatePageCount & @CRLF
      $Output = $Output & "ProcessId: " & $objItem.ProcessId & @CRLF
      $Output = $Output & "QuotaNonPagedPoolUsage: " & $objItem.QuotaNonPagedPoolUsage & @CRLF
      $Output = $Output & "QuotaPagedPoolUsage: " & $objItem.QuotaPagedPoolUsage & @CRLF
      $Output = $Output & "QuotaPeakNonPagedPoolUsage: " & $objItem.QuotaPeakNonPagedPoolUsage & @CRLF
      $Output = $Output & "QuotaPeakPagedPoolUsage: " & $objItem.QuotaPeakPagedPoolUsage & @CRLF
      $Output = $Output & "ReadOperationCount: " & $objItem.ReadOperationCount & @CRLF
      $Output = $Output & "ReadTransferCount: " & $objItem.ReadTransferCount & @CRLF
      $Output = $Output & "SessionId: " & $objItem.SessionId & @CRLF
      $Output = $Output & "Status: " & $objItem.Status & @CRLF
      $Output = $Output & "TerminationDate: " & WMIDateStringToDate($objItem.TerminationDate) & @CRLF
      $Output = $Output & "ThreadCount: " & $objItem.ThreadCount & @CRLF
      $Output = $Output & "UserModeTime: " & $objItem.UserModeTime & @CRLF
      $Output = $Output & "VirtualSize: " & $objItem.VirtualSize & @CRLF
      $Output = $Output & "WindowsVersion: " & $objItem.WindowsVersion & @CRLF
      $Output = $Output & "WorkingSetSize: " & $objItem.WorkingSetSize & @CRLF
      $Output = $Output & "WriteOperationCount: " & $objItem.WriteOperationCount & @CRLF
      $Output = $Output & "WriteTransferCount: " & $objItem.WriteTransferCount & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Process" )
Endif


Func WMIDateStringToDate($dtmDate)

    Return (StringMid($dtmDate, 5, 2) & "/" & _
    StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc

You can run this as an AutoIT script and see what comes out for pdmweb2.exe...


...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0