Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyWinrm Persistent PowerShell Sessions

Is anyone aware if there is a way to open a persistent PowerShell session with PyWinrm that maintains state and can be called multiple times? I'm trying to do something like the following:

#!/bin/python

import winrm

# Initialize some COM object and call a method storing the results
# in $Results and then print $Results to stdout
ps_script = """
$SomeObject = New-Object -ComObject Some.Com.Object
$Results = SomeObject.DoThing
$Results
"""

# Create winrm connection
s = winrm.Session('https://server.domain.local', auth=('username', 'password'), transport='kerberos')

# Call the ps_script - contents of $Results is returned as a string
r = s.run_ps(ps_script)

# Parse the contents of $Results returned from the $Results variable
# in the ps script
parse_stdout_from_script(r.stdout)

# Based on results from parsing previous stdout, connect back to the
# same powershell session to manipulate the $Results variable some more
r = s.run_ps(new_ps_script_to_manipulate_existing_objects)

Based on the contents of the stdout I want to connect back to the same powershell session and work with the $Results variable/object some more. However, when I do another s.run_ps() I get a completely new powershell session with none of the objects or variables that were created in the previous session.

Does anyone have any ideas how I can connect back to a persistent powershell session? I'm wondering if this is even possible...

The reason I can't just recreate everything in a new powershell session is:

1) The COM object method that I'm calling takes a few minutes to run and if I need to parse multiple times, this could easily stack up to 30 minutes or more.

2) The COM object returns results in an array and it doesn't always return them in the same order. So, I can't count on array items being in the same place again when I rerun the COM object method and go to manipulate them.

It would be great if I could somehow get stdout from the powershell session, do the parsing (and other library calls) that need to be done in the Python script, and then call back to the same PowerShell session where all of the variables and objects are preserved from the first call.

like image 279
Austin Eyler Avatar asked Dec 02 '16 05:12

Austin Eyler


1 Answers

You should use pypsrp, which uses PowerShell remoting natively.

The examples in the GitHub repo will show you how, and you can continually use .add_script() or add_cmdlet() to make multiple calls within your session.

WinRM (and by extension pywinrm) is not strictly related to PowerShell, so that call you're doing likely just opens powershell.exe with whatever you send it.

PSRP is a separate protocol, which runs over WinRM as its transport, so you'll be connecting to a hosted PowerShell session.

like image 159
briantist Avatar answered Nov 01 '22 19:11

briantist