Search code examples
batch-filevbscriptprocesswmi

VBScript to check for open process by user


I need a VBScript that will check if a process is in use by a specific user:

Agent clicks program icon --> batch file calls for progcheck.vbs -->

progcheck.vbs looks to see is "whatever.exe" is running under that user only -->

if program is running under that user then MsgBox "Program running" --> wscript.quit (this needs to terminate out of the batch file)

else --> return to batch file.

I have tried this with tasklist in a batch file and the script works, but takes forever to run for a domain user. Want to do this in vbscript anyway.

*** UPDATED SCRIPT WITH MODS 10/12 *****

OPTION EXPLICIT

    DIM strComputer,strProcess, strUserName,wshShell

    Set wshShell = WScript.CreateObject( "WScript.Shell" )
    strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )

    strComputer = "." ' 
    strProcess = "notepad.exe"


    IF isProcessRunning(strComputer,strProcess,strUserName) THEN
            If MsgBox ("Notepad needs to be closed.", 1) = 1 then
                wscript.Quit(1)
            End If
    END IF

FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName,BYVAL strUserName)

    DIM objWMIService, strWMIQuery

    strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "' AND owner like '" &strUserName& "'" 

    SET objWMIService = GETOBJECT("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" _ 
            & strComputer & "\root\cimv2") 


    IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
        isProcessRunning = TRUE
    ELSE
        isProcessRunning = FALSE
    END If

End Function

Let me know what you think and where I have it wrong. Thanks in advance.


Solution

  • UPDATED CODE v3: review comments for help

    OPTION EXPLICIT
    
        DIM strComputer, strProcess, strUserName, wshShell
    
        Set wshShell = WScript.CreateObject( "WScript.Shell" )
        strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )
        strComputer = "."
        strProcess = "notepad.exe" 'change this to whatever you are trying to detect
    
        IF isProcessRunning(strComputer, strProcess, strUserName) THEN
            If MsgBox ("Notepad needs to be closed.", 1) = 1 then
                wscript.Quit(1) 'you need to terminate the process if that's your intention before quitting
            End If
        Else
            msgbox ("Process is not running") 'optional for debug, you can remove this
        END IF
    
    FUNCTION isProcessRunning(ByRef strComputer, ByRef strProcess, ByRef strUserName)
    
        DIM objWMIService, strWMIQuery, objProcess, strOwner, Response
    
        strWMIQuery = "SELECT * FROM Win32_Process WHERE NAME = '" & strProcess & "'"
    
        SET objWMIService = GETOBJECT("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery(strWMIQuery)
    
        IF objWMIService.Count > 0 THEN
            msgbox "We have at least ONE instance of Notepad"
            For Each objProcess in objWMIService
                Response = objProcess.GetOwner(strOwner)
                If Response <> 0 Then
                    'we didn't get any owner information - maybe not permitted by current user to ask for it
                    Wscript.Echo "Could not get owner info for process [" & objProcess.Name & "]" & VBNewLine & "Error: " & Return
                Else 
                    Wscript.Echo "Process [" & objProcess.Name & "] is owned by [" & strOwner & "]" 'for debug you can remove it
                    if strUserName = strOwner Then
                        msgbox "we have the user who is running notepad"
                        isProcessRunning = TRUE
                    Else
                        'do nothing as you only want to detect the current user running it
                        isProcessRunning = FALSE
                    End If
                End If
            Next
        ELSE
            msgbox "We have NO instance of Notepad - Username is Irrelevant"
            isProcessRunning = FALSE
        END If
    
    End Function
    

    You can use the following function:

    FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName)
    
        DIM objWMIService, strWMIQuery
    
        strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "'"
    
        SET objWMIService = GETOBJECT("winmgmts:" _
            & "{impersonationLevel=impersonate}!\\" _ 
                & strComputer & "\root\cimv2") 
    
    
        IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
            isProcessRunning = TRUE
        ELSE
            isProcessRunning = FALSE
        END IF
    
    END FUNCTION
    

    For local computer you would use "."

    For the process name, you would use the executable "notepad.exe"

    For the rest of the code, you could can use something simple:

    OPTION EXPLICIT
    DIM strComputer,strProcess
    
    strComputer = "." ' local computer
    strProcess = "notepad.exe" 'whatever is the executable
    
    IF isProcessRunning(strComputer,strProcess) THEN
        'do something
    ELSE
        'do something else or nothing
        wscript.echo strProcess & " is NOT running on computer '" & strComputer & "'"
    END IF
    

    That should do it.

    EXTRA

    To show every process running, then just run:

    Option Explicit
    Dim objWMIService, objProcess, colProcess
    Dim strComputer, strList
    
    strComputer = "."
    
    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _ 
    & strComputer & "\root\cimv2") 
    
    Set colProcess = objWMIService.ExecQuery _
    ("Select * from Win32_Process")
    
    For Each objProcess in colProcess
        strList = strList & vbCr & _
        objProcess.Name
    Next
    
    WSCript.Echo strList
    WScript.Quit