Monday, June 16, 2008

Start a process remotely

I'm back with another script fresh from the oven.  This time we're going to create a function that will connect to a machine and create a process.  Before you say "why would I want to create a process, we've got too many processes around here", think of it like this:  Say you have a computer somewhere that you want to run a command like ipconfig /flushdns on.  Well, ipconfig doesn't have a way of doing it remotely.  Now you are stuck with writing out some code to do it via WMI.   While that's great, sometimes it's just easier to type in "ipconfig /flushdns" and you wish you could just tell the dang computer to run it.

Well you can and it turns out, it's pretty simple too.   First, we'll connect to the computer.  Next, we'll create a new process (in this case, ipconfig.exe).  Then we'll pass some switches to it ("/flushdns").  Lastly, we'll run the command and capture the return code to try and determine if the process started successfully.

Before you plop this code into your script, here's a tip.  The function returns a boolean value based on the return code from the OS.  I did my best job trying to interpret the codes into a True/False return code but you may need to modify it for your script.  Also, the function stores the return type (string) so you can get a nice status of the return code.  To use this, declare startExeStatus globally (in the main part of your script).  Then call the function.  It will set the variable to the status.

So here's the code:

Function startExe(sstrComputer,sstrEXE)
'Starts a process on a machine
'Input: sstrComputer = machine name (use "." for local)
'Input: sstrExe = Exe or command to execute (can pass full command line)
'Output: boolean
'Optional: Declare startExeStatus as a global variable to get status text
    startExe = False 
    Set sobjWMIService = GetObject("winmgmts:\\" & sstrComputer & "\root\cimv2:Win32_Process")
    sintReturn = sobjWMIService.Create(sstrEXE, null, null, sintProcessID)
    Select Case sintReturn
        Case 0 'Successful Completion
            startExe = True
            startExeStatus = "Successful Completion"
        Case 2 'Access Denied
            startExe = False
            startExeStatus = "Access Denied"
        Case 3 'Insufficient Privilege
            startExe = False
            startExeStatus = "Insufficient Privilege"
        Case 8 'Unknown Failure
            startExe = False
            startExeStatus = "Unknown Failure"
        Case 9 'Path not found
            startExe = False
            startExeStatus = "Path not found"
        Case 21 'Invalid Parameter
            startExe = False
            startExeStatus = "Invalid Parameter"
        Case Else 
            startExe = False
            startExeStatus = "Error code " & sintReturn & " not found"
    End Select 
End Function 


Here's the background on why I created this function.  We have a need to create a scheduled task on a lot (and I mean a LOT) of machines.  We were using schtasks.exe and for the most part it worked fine.  However, one day we found several hundreds of machines that weren't scheduling the tasks.  After some investigation, the machines were returning back as not being NT or higher even though they were on XP SP2.  The need to create the task was great so we worked around it.

I found that creating the task locally worked like a charm.  So the function was born.  It's been used for all kinds of stuff since like ipconfig /flushdns.  Use wisely.  :)

As always, these scripts are free to use and at your own caution.  So don't hold me responsible for any crashes or other bad things you do with it.


No comments: