2

I have been working on executing a command on hundreds of remote systems with PsExec via Python 3.4.2. I have been having problems collecting the output in a parsable fashion. I've tried several variations using subprocess.Popenand os.system but neither seem to be working exactly how I need them.

As mentioned above, I need to run a command on a few hundred Windows systems. The executable that I need to run and throw arguments against could exist in one of several predictable places. I decided to take inspiration from this SO post and essentially use nested if/else statements to run the command via PsExec, collect output PsExec/Windows output, and parse output to determine success or failure (if "The system cannot find the path specified." in output:). If the command failed, then I would run the next command variation. I know this is bad practice and I'm certainly open to alternatives.

Here's my rat's nest code block:

def f_remove_ma():
    host = f_get_queue()
    g_psexec_location = "PsExec.exe"

    # Legacy 32-bit:
    ma_install_location = "<install location 1>"
    ma_arguments = "/arguments"
    output = subprocess.Popen([g_psexec_location, "\\\\" + host, "-accepteula", ma_install_location, ma_arguments], stdout=subprocess.PIPE).communicate()[0]

    if 'could not start' in output:
        print("Install not found in location 1")
        return
        # Standard 64-bit:
        ma_install_location = "<install location 2>"
        ma_arguments = "/arguments"
        output = subprocess.Popen([g_psexec_location, "\\\\" + host, "-accepteula", ma_install_location, ma_arguments], stdout=subprocess.PIPE).communicate()[0]

        if "The system cannot find the path specified." in output:
            # Standard 32-bit:
            ma_install_location = "<install location 3>"
            ma_arguments = "/arguments"
            output = subprocess.Popen([g_psexec_location, "\\\\" + host, "-accepteula", ma_install_location, ma_arguments], stdout=subprocess.PIPE).communicate()[0]

            if "The system cannot find the path specified." in output:
                # New 32/64-bit:
                ma_install_location = "<install location 4>"
                ma_arguments = "/arguments"
                output = subprocess.Popen([g_psexec_location, "\\\\" + host, "-accepteula", ma_install_location, ma_arguments], stdout=subprocess.PIPE).communicate()[0]

                if "The system cannot find the path specified." in output:
                    # New 32/64-bit:
                    ma_install_location = "<install location 5>"
                    ma_arguments = "/arguments"
                    output = subprocess.Popen([g_psexec_location, "\\\\" + host, "-accepteula", ma_install_location, ma_arguments], stdout=subprocess.PIPE).communicate()[0]

                    if "The system cannot find the path specified." in output:
                        print("No known versions of software found.")
                    else:
                        print(output)
                else:
                    print(output)
            else:
                print(output)
        else:
            print(output)
    else:
        print(output)

This method seems promising at first, but it is currently hanging for me right after PsExec execution. Below is the output.

PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

At one time I got it to actually output something, but since the output was in bytecode it wasn't parsable as a string. At the time, I tried doing .decode(output) which didn't help me any.

Here are some of the internet research I found on the topic that has helped so far:

Python Popen hanging with psexec - undesired results

Calling psexec from a python script doesn't show the whole output

Why does Popen.communicate() return b'hi\n' instead of 'hi'?

... and finally this one which isn't fully implemented in Python and doesn't seem to work for me anyways.

**Edit: Adding the feeder queue functions for "host"

def f_create_queue(ip_list):
    global g_queue
    g_queue
    for ip in ip_list:
        g_queue.put(ip)
    print("\nQueue has {} items ready for processing\n".format(g_queue.qsize()))


def f_get_queue():
    global g_queue
    return g_queue.get()

So with all of this, I have a few questions:

  1. Why is PsExec hanging after initial execution?
  2. How do I capture everything (including PsExec output) in Python?
  3. Is there a better way I can do the multiple nested If/Else statements?

Thanks in advance!

26
  • sounds like you need ansible.. ansible.com/home Commented Mar 19, 2015 at 20:44
  • is it hanging on the first call? I would also use check_output if you just want to capture the output Commented Mar 19, 2015 at 20:44
  • @PadraicCunningham - Yes, it does hang on the first call. Commented Mar 19, 2015 at 20:46
  • do you get any output? Also have you tried stderr to see if you get anything there? Why are you nesting all the ifs? Commented Mar 19, 2015 at 20:47
  • 1
    I would also put all the "<install location 3>" in a list and iterate over it instead of multiple ifs Commented Mar 19, 2015 at 20:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.