jborean93 / pypsrp

PowerShell Remoting Protocol for Python
MIT License
328 stars 49 forks source link

Command execution timeout #145

Open AndyPigPenDoran opened 2 years ago

AndyPigPenDoran commented 2 years ago

This is more of a dumb question than an issue. I want to be able to set a maximum timeout for a PS command to execute in. For example, if the command I execute is "Start-Sleep 900" I want to say "wait a maximum of 60 seconds".

I was able to do this with pyWinRM by sub-classing Protocol. So the problem in replacing pyWinRM is making sure pypsrp does everything I could do before... This (command execution timeout) and setting IdleTimeout are the only things I am missing.

This very basic code works fine:

class powershell_pypsrp_transport():
    def __init__(self, server):
        self.server=server
        self.client=None
        self.had_errors=False
        self.stderr=None
        self.stdout=None

    def connect(self, cred_details):
        self.client = Client(
            server=self.server,
            ssl=cred_details["ssl"],
            port=cred_details["port"],
            auth=cred_details["auth"],
            negotiate_service=cred_details["negotiate_service"],
        )

    def run_powershell(self, cmd):
        try:
            result = self.client.execute_ps(cmd)
            self.stdout = result[0]
            self.had_errors = result[2]
            if self.had_errors:
                self.stderr = str(result[1].error[0])
        except Exception as err:
            self.stderr = "Error invoking command with error: {}".format(err)
            self.had_errors = True

Using:

    transport = powershell_pypsrp_transport(PARAMS["server"])
    transport.connect(PARAMS)

    start_time = time.time()
    print("Executing command with command length: {}...".format(len(PARAMS["cmd"])))
    transport.run_powershell(PARAMS["cmd"])
    end_time = time.time()

    if transport.had_errors:
        print("Errors returned from command: {}".format(transport.stderr))
    else:
        print("Results:\n\n{0}\n".format(transport.stdout))
        print("Command executed in {} seconds\n".format(int(end_time - start_time)))

But whilst I see that for Shell thre is idle_time_out and lifetime (would lifetime do what I want???) I cannot see how to actually use them in the above code.