winrm.py
82 lines
| 1.9 KiB
| text/x-python
|
PythonLexer
Gregory Szorc
|
r42191 | # winrm.py - Interact with Windows Remote Management (WinRM) | ||
# | ||||
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
# no-check-code because Python 3 native. | ||||
import logging | ||||
import pprint | ||||
import time | ||||
from pypsrp.client import ( | ||||
Client, | ||||
) | ||||
from pypsrp.powershell import ( | ||||
PowerShell, | ||||
PSInvocationState, | ||||
RunspacePool, | ||||
) | ||||
import requests.exceptions | ||||
logger = logging.getLogger(__name__) | ||||
def wait_for_winrm(host, username, password, timeout=120, ssl=False): | ||||
"""Wait for the Windows Remoting (WinRM) service to become available. | ||||
Returns a ``psrpclient.Client`` instance. | ||||
""" | ||||
end_time = time.time() + timeout | ||||
while True: | ||||
try: | ||||
client = Client(host, username=username, password=password, | ||||
ssl=ssl, connection_timeout=5) | ||||
client.execute_cmd('echo "hello world"') | ||||
return client | ||||
except requests.exceptions.ConnectionError: | ||||
if time.time() >= end_time: | ||||
raise | ||||
time.sleep(1) | ||||
def format_object(o): | ||||
if isinstance(o, str): | ||||
return o | ||||
try: | ||||
o = str(o) | ||||
except TypeError: | ||||
o = pprint.pformat(o.extended_properties) | ||||
return o | ||||
def run_powershell(client, script): | ||||
with RunspacePool(client.wsman) as pool: | ||||
ps = PowerShell(pool) | ||||
ps.add_script(script) | ||||
ps.begin_invoke() | ||||
while ps.state == PSInvocationState.RUNNING: | ||||
ps.poll_invoke() | ||||
for o in ps.output: | ||||
print(format_object(o)) | ||||
ps.output[:] = [] | ||||
ps.end_invoke() | ||||
for o in ps.output: | ||||
print(format_object(o)) | ||||
if ps.state == PSInvocationState.FAILED: | ||||
raise Exception('PowerShell execution failed: %s' % | ||||
' '.join(map(format_object, ps.streams.error))) | ||||