Exemplo n.º 1
0
def run_command(command, target):

    p = Protocol(endpoint='https://' + target + ':5986/wsman',
                 transport='kerberos')

    # We do not want printed info about kerberos ticket
    stdout_orig = sys.stdout
    f = open('/dev/null', 'w')
    sys.stdout = f

    try:
        shell_id = p.open_shell()
        command_id = p.run_command(shell_id, 'powershell', [command])
        std_out, std_err, status_code = p.get_command_output(
            shell_id, command_id)
        p.cleanup_command(shell_id, command_id)
        p.close_shell(shell_id)

        sys.stdout = stdout_orig

        print std_out

        if std_err:
            sys.exit(std_err)

    except kerberos.GSSError as e:
        print >> sys.stderr, "kerberos GSSError:", e
        sys.exit(2)
    except:
        print >> sys.stderr, (
            "Unexpected error during remote ps command execution :",
            sys.exc_info()[0], sys.exc_info()[1])
        sys.exit(2)
Exemplo n.º 2
0
class Session(object):
    #TODO implement context manager methods
    def __init__(self, target, auth, transport='plaintext'):
        username, password = auth
        self.url = self._build_url(target, transport)
        self.protocol = Protocol(self.url, transport=transport, username=username, password=password)

    def run_cmd(self, command, args=()):
        #TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    @staticmethod
    def _build_url(target, transport):
        match = re.match(
            '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?', target)
        scheme = match.group('scheme')
        if not scheme:
            scheme = 'https' if transport == 'ssl' else 'http'  # TODO do we have anything other than HTTP/HTTPS
        host = match.group('host')
        port = match.group('port')
        if not port:
            port = 5986 if transport == 'ssl' else 5985
        path = match.group('path')
        if not path:
            path = 'wsman'
        return '{0}://{1}:{2}/{3}'.format(scheme, host, port, path.lstrip('/'))
Exemplo n.º 3
0
    def run(self):
        # use win remote management to run powershell script

        # set command text, tell windows which module to import and run in this case
        script = "Import-Module -Name 'C:\\Users\\trota\\Source\\PowerShell\\Modules\\yo.psm1'; &WriteYo(' with var')"

        # must use utf16 little endian on windows
        # see run_ps in pywinrm __init__.py https://github.com/diyan/pywinrm/blob/master/winrm/__init__.py
        encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
        encoded_ps_command = 'powershell -encodedcommand {0}'.format(
            encoded_ps)

        print("")
        print("encoded ps command: ", encoded_ps_command)
        print("")

        # connect
        p = Protocol(
            endpoint='https://CCWL-2909.chsamerica.com:5986/wsman',
            transport='ntlm',
            username=r'chs\trota',
            password='******',
            # secure connection validation - see http://www.hurryupandwait.io/blog/understanding-and-troubleshooting-winrm-connection-and-authentication-a-thrill-seekers-guide-to-adventure
            # TODO: configure SSL properly for production/public spaces
            server_cert_validation='ignore'
            #server_cert_validation='validate'
        )
        shell_id = p.open_shell()
        command_id = p.run_command(shell_id, encoded_ps_command)
        std_out, std_err, status_code = p.get_command_output(
            shell_id, command_id)
        p.cleanup_command(shell_id, command_id)
        p.close_shell(shell_id)
Exemplo n.º 4
0
    def getLastTaskResult(self, taskname):
        script = """
$task = Get-ScheduledTaskInfo -TaskName %s
$task.LastTaskResult
""" % taskname

        shell_id = None
        command_id = None
        p = None
        error = False
        try:
            p = Protocol(endpoint='https://' + self.hostname + ':5986/wsman',
                         transport='ntlm',
                         username=self.username,
                         password=self.password,
                         server_cert_validation='ignore')
            shell_id = p.open_shell()
            encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
            command_id = p.run_command(shell_id, 'powershell', [
                '-encodedcommand {0}'.format(encoded_ps),
            ])
            std_out, std_err, status_code = p.get_command_output(
                shell_id, command_id)
            lasttaskresult = std_out.rstrip()
        except Exception as e:
            print("UNKNOWN - Unable to get data from server (%s) %s." %
                  (str(e), type(e).__name__))
            error = True
        finally:
            p.cleanup_command(shell_id, command_id)
            p.close_shell(shell_id)
        if error: exit(3)
        return lasttaskresult
Exemplo n.º 5
0
    def run(self,
            host,
            password,
            command,
            params,
            username='******',
            port=5732,
            secure=True):
        proto = 'https' if secure else 'http'
        p = Protocol(
            endpoint='%s://%s:%i/wsman' % (proto, host, port),  # RFC 2732?
            transport='ntlm',
            username=username,
            password=password,
            server_cert_validation='ignore')
        shell_id = p.open_shell()

        # run the command
        command_id = p.run_command(shell_id, command, params)
        std_out, std_err, status_code = p.get_command_output(
            shell_id, command_id)
        p.cleanup_command(shell_id, command_id)

        p.close_shell(shell_id)
        return {'stdout': std_out, 'stderr': std_err}
Exemplo n.º 6
0
class ConnWinCls(object):
    def __init__(self):
        self.conn = self.connectWindows()

    def connectWindows(self):
        try:
            self.hostIP = "https://"+self.host_ip + ":5986/wsman"
            self.pro = Protocol(
                endpoint = self.hostIP,
                transport = "ntlm",
                username = self.u_name,
                password = self.pwd,
                server_cert_validation ="ignore")
            logger.info("Connecting Windows ...")
            script = """diskpart /s C:\Users\Administrator\Desktop\script1.txt > C:\Users\Administrator\Desktop\log1.txt"""
            shell_id = self.pro.open_shell()
            logger.info("Connected")
            command_id = self.pro.run_command(shell_id, script)

            std_out, std_err, status_code = self.pro.get_command_output(shell_id, command_id)
            logger.info("Executed Cmd status_code is : {}".format(status_code))
            logger.info("Executed Command Output is : {}".format(std_out))
            logger.info("Executed Command Error is : {}".format(std_err))
            self.pro.cleanup_command(shell_id, command_id)
            self.pro.close_shell(shell_id)
        except Exception, e:
            logger.info( "Exception : {}".format(e))
Exemplo n.º 7
0
def main():
    args = parse_args()
    endpoint = '{}://{}:{}/{}'.format(
        'http' if args.use_http else 'https',
        args.host,
        args.port,
        args.endpoint
    )
    username = args.user
    if '\\' not in username or '@' not in username:
        username = '******'.format(args.host.split('.')[0], username)

    if args.shell:
        command = args.command[0]
        arguments = args.command[1:]
    else:
        command = 'powershell'
        encoded_command = ' '.join(args.command)
        encoded_command = base64.b64encode(encoded_command.encode('utf-16-le'))
        arguments = ['-EncodedCommand', encoded_command]

    proto = Protocol(endpoint, 'ntlm', username, args.password, server_cert_validation='ignore')
    shell_id = proto.open_shell()
    command_id = proto.run_command(shell_id, command, arguments)
    std_out, std_err, status_code = proto.get_command_output(shell_id, command_id)
    sys.stdout.write(std_out.decode('utf-8'))
    # sys.stderr.write(std_err.decode('utf-8'))
    proto.cleanup_command(shell_id, command_id)
    proto.close_shell(shell_id)
    return status_code
Exemplo n.º 8
0
    def run(self, scripturl, scriptarguments):
        scriptpath = "c:\\samanamon"
        #scripturl="http://%s/%s" % (self.nagiosaddress, scriptname)
        scriptname = scripturl.split('/')[-1]
        if self.cleanup:
            script = '''
 if (-Not (Test-Path %(scriptpath)s)) { mkdir %(scriptpath)s | Out-Null}
 "Environment prepared." | Out-Host
 Invoke-WebRequest -Uri %(scripturl)s -OutFile "%(scriptpath)s\\%(scriptname)s"
 if (-Not (Test-Path %(scriptpath)s\\%(scriptname)s)) { 
   "File not downloaded" | Out-Host; 
   Remove-Item -Recurse -Force %(scriptpath)s
   exit 1 
 }
 "Downloaded Script." | Out-Host
 %(scriptpath)s\\%(scriptname)s %(scriptarguments)s| Out-Host
 "Done executing script" | Out-Host
 del %(scriptpath)s\\%(scriptname)s
 Remove-Item -Recurse -Force %(scriptpath)s
 "Done cleanup" | Out-Host''' % { 'scripturl': scripturl, 
      'scriptpath': scriptpath, 
      'scriptname': scriptname,
      'scriptarguments': scriptarguments,
      'hostaddress': self.hostaddress
      }
        else:
            script = '''
 %(scriptpath)s\\%(scriptname)s %(scriptarguments)s| Out-Host
 "Done executing script" | Out-Host''' % {
            'scriptpath': scriptpath, 
            'scriptname': scriptname,
            'scriptarguments': scriptarguments
            }

        shell_id = None
        command_id = None
        p = None
        error = 0
        std_out = ''
        std_err = ''
        try:
            p = Protocol(
                endpoint='http://%s:5985/wsman' % self.hostaddress,
                transport='ntlm',
                username=self.username,
                password=self.password)
            shell_id = p.open_shell()
            encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
            command_id = p.run_command(shell_id, 'powershell', ['-encodedcommand {0}'.format(encoded_ps), ])
            std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
            self.check_error(std_err)
            p.cleanup_command(shell_id, command_id)
            p.close_shell(shell_id)

        except Exception as e:
          raise CheckWinRMExceptionUNKNOWN("Unable to get data from Server (%s) %s." % (type(e).__name__, str(e)))

        if status_code != 0:
            raise CheckWinRMExceptionUNKNOWN(std_err)
        return "%s\n%s" % (std_out, "")
Exemplo n.º 9
0
class SessionLinux(Session):
    def connect(self, output, server):
        self.output = output
        self.datastore = os.path.join(self.output, server['server'])
        os.makedirs(self.datastore)
        # session = winrm.Session(server['url'],
        #                         auth=(server['user'], server['password']),
        #                         transport='ntlm')
        self.protocol = Protocol(endpoint='http://{}:5985/wsman'.format(
            server['url']),
                                 transport='ntlm',
                                 username=server['user'],
                                 password=server['password'])

    def run_cmd(self, command, args=()):
        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell(codepage=65001)
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    def run_ps(self, script):
        """base64 encodes a Powershell script and executes the powershell
        encoded script command
        """
        # must use utf16 little endian on windows
        encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
        rs = self.run_cmd('powershell -encodedcommand {0}'.format(encoded_ps))
        # if len(rs.std_err):
        #     # if there was an error message, clean it it up and make it human
        #     # readable
        #     rs.std_err = self._clean_error_msg(rs.std_err)
        return rs

    # def execute(self, err_file, session, id, type, text):
    def execute(self, err_file, id, type, text):
        text = text.strip()
        # print("run:{},{},{}".format(id, type, text))
        if type == "Cmdlet":
            result = self.run_ps(text)
        else:
            result = self.run_cmd(text)

        if result.status_code != 0:
            err_msg = "id:{},rc:{}\n".format(id, result.status_code)
            err_file.write(err_msg.encode())
            err_file.write(result.std_err)

        # print(result.std_out.decode('utf-8'))

        with open(os.path.join(self.datastore, id), 'wb') as out_file:
            out_file.write(result.std_out)

    def finish(self):
        pass
def run_powershell_with_codepage_936(target, username, password, script):
    """
    run remote command with WinRM

    [Chinese characters are not displayed properly #288](https://github.com/diyan/pywinrm/issues/288)
    [Code Page Identifiers](https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers)

    codepage use 936, gb2312, ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)

    :param target: hostname or ip address
    :type target: str
    :param username:
    :type username: str
    :param password:
    :type password: str
    :param script: powershell commands or scripts
    :type script: str | unicode
    :return: status_code, std_out
    :rtype: tuple
    """
    script = to_unicode_or_bust(script)
    encoded_ps = b64encode(script.encode('utf_16_le')).decode("ascii")

    p = Protocol(
        endpoint='http://{}:5985/wsman'.format(target),
        transport='ntlm',
        username=username,
        password=password,
        read_timeout_sec=10,
        operation_timeout_sec=5,
    )

    try:
        shell_id = p.open_shell(codepage=936)
    except requests.exceptions.ConnectionError as e:
        return 1, "requests failed.", str(e)

    try:
        command_id = p.run_command(shell_id, 'powershell.exe',
                                   ['-EncodedCommand', encoded_ps])
        try:
            std_out, std_err, status_code = p.get_command_output(
                shell_id, command_id)
        finally:
            p.cleanup_command(shell_id, command_id)
    finally:
        p.close_shell(shell_id)

    # print(std_out.decode('utf-8'))
    # print(std_err.decode('utf-8'))
    # print(status_code)

    return status_code, std_out, std_err
Exemplo n.º 11
0
def auto_ss():
    from winrm.protocol import Protocol

    p = Protocol(endpoint='http://172.30.200.149:5985/wsman',
                 transport='basic',
                 username=r'chry',
                 password='******',
                 server_cert_validation='ignore')
    shell_id = p.open_shell()
    command_id = p.run_command(shell_id, 'ipconfig', ['/all'])
    std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
    p.cleanup_command(shell_id, command_id)
    p.close_shell(shell_id)
Exemplo n.º 12
0
def main(computer, username, password, command):
    p = Protocol(endpoint='https://{}:5986/wsman'.format(computer),
                 transport='ntlm',
                 username=username,
                 password=password,
                 server_cert_validation='ignore')

    shell_id = p.open_shell()
    #command_id = p.run_command(shell_id, 'query', ['user'])
    command_id = p.run_command(shell_id, command, [])
    std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
    p.cleanup_command(shell_id, command_id)
    p.close_shell(shell_id)
Exemplo n.º 13
0
class Session(object):
    #TODO implement context manager methods
    def __init__(self, url, auth, transport = "plaintext"):
        #TODO convert short urls into well-formed endpoint
        self.protocol = Protocol(url, auth, transport)

    def run_cmd(self, command, args=()):
        #TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs
Exemplo n.º 14
0
def run_vncApplyAttribute_winrm_command(attribute_name, attribute_value,
                                        idrac_ip, idrac_userName,
                                        idrac_password, windows_ip,
                                        windows_username, windows_password):
    """
    This function is used for getting output of enumeration class as speciified

    Function Owner : Nithya_V

    Date created : 6/9/2016

    @param attribute_name : VNC attribute name which needs to be changed
    @param attribute_value : VNC attribute value which needs to be applied
    @param idrac_ip : (string) idrac ip of system
    @param idrac_userName : (string) idrac user name
    @param idrac_password : (string) idrac password
    @param windows_ip : (string) windows system ip from which query will be executed
    @param windows_userName : (string) windows system user name
    @param windows_password : (string) windows system password
    @param instance_id : (string) instance id for fetching data specific to an instance. Optional

    @return command_output : (string) Command Output, None in case of any error
    @return no_of_instances : (string) number of instances returned 
    """
    try:
        'establish connection with windows system'
        p = Protocol(endpoint='http://' + windows_ip + ':5985/wsman',
                     transport='plaintext',
                     username=windows_username,
                     password=windows_password)
        shell_id = p.open_shell()

        'execute winrm command on idrac ip'
        winrm_command = global_vars.winrm_apply_vnc_attributes_command + ' -u:' + idrac_userName + ' -p:' + idrac_password + \
                         ' -r:https://' + idrac_ip + '/wsman -SkipCNcheck -SkipCAcheck -encoding:utf-8 -a:basic @{Target="iDRAC.Embedded.1";AttributeName=%s;AttributeValue=%s}' % (attribute_name, attribute_value)
        print "Winrm Command %s \n" % (winrm_command)
        command_id = p.run_command(shell_id, 'ls')

        'get command output'
        command_output, command_error, command_status = p.get_command_output(
            shell_id, command_id)

        print 'Command Output:' + str(command_output)
        p.cleanup_command(shell_id, command_id)
        p.close_shell(shell_id)

        return command_output, 0
    except:
        traceback.print_exc()
        return None, '0'
Exemplo n.º 15
0
 def _try_winrm(self, node):
     ip = node.private_ips[0]
     p = Protocol(
             endpoint='http://%s:5985/wsman' % ip,  # RFC 2732
             transport='ntlm',
             username=self.username,
             password=self.secret,
             server_cert_validation='ignore')
     shell_id = p.open_shell()
     command_id = p.run_command(shell_id, 'ipconfig', ['/all'])
     std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
     p.cleanup_command(shell_id, command_id)
     p.close_shell(shell_id)
     return std_out
Exemplo n.º 16
0
def winrm_cmd(cmd):

    p = Protocol(endpoint='https://192.168.183.186:5986/wsman',
                 transport='basic',
                 username=r'Administrator',
                 password='******',
                 server_cert_validation='ignore')
    shell_id = p.open_shell()
    command_id = p.run_command(shell_id, cmd)
    std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
    p.cleanup_command(shell_id, command_id)
    p.close_shell(shell_id)

    return std_out
Exemplo n.º 17
0
def run_powerstate_change_winrm_command(power_state, idrac_ip, idrac_userName,
                                        idrac_password, windows_ip,
                                        windows_username, windows_password):
    """
    This function is used for getting output of enumeration class as speciified

    Function Owner : Pooja_Rundwal

    Date created : 9/5/2016

    @param powerstate : 2 - Power On , 8 - Graceful shutdown
    @param idrac_ip : (string) idrac ip of system
    @param idrac_userName : (string) idrac user name
    @param idrac_password : (string) idrac password
    @param windows_ip : (string) windows system ip from which query will be executed
    @param windows_userName : (string) windows system user name
    @param windows_password : (string) windows system password
    @param instance_id : (string) instance id for fetching data specific to an instance. Optional

    @return command_output : (string) Command Output, None in case of any error
    @return no_of_instances : (string) number of instances returned 
    """
    try:
        'establish connection with windows system'
        p = Protocol(endpoint='http://' + windows_ip + ':5985/wsman',
                     transport='plaintext',
                     username=windows_username,
                     password=windows_password)
        shell_id = p.open_shell()

        'execute winrm command on idrac ip'
        winrm_command = global_vars.winrm_invoke_powerstate_command + ' @{PowerState="' + power_state + '"}' \
                         + ' -u:' + idrac_userName + ' -p:' + idrac_password + \
                        ' -r:https://' + idrac_ip + '/wsman -SkipCNcheck -SkipCAcheck -encoding:utf-8 -a:basic'
        print "Winrm Command %s \n" % (winrm_command)
        command_id = p.run_command(shell_id, winrm_command)

        'get command output'
        command_output, command_error, command_status = p.get_command_output(
            shell_id, command_id)

        print 'Command Output:' + str(command_output)
        p.cleanup_command(shell_id, command_id)
        p.close_shell(shell_id)

        return command_output
    except:
        traceback.print_exc()
        return None, '0'
Exemplo n.º 18
0
def win(host, cmd, usern, userp):
    p = Protocol(endpoint="https://{}:5986/wsman".format(host),
                 transport='ntlm',
                 username=usern,
                 password=userp,
                 server_cert_validation='ignore')
    shell_id = p.open_shell()
    command_id = p.run_command(shell_id, cmd)
    std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
    outlines = std_out.decode("utf-8")
    res = "".join(outlines)
    resp = [x.strip() for x in res.split('\n')]
    p.cleanup_command(shell_id, command_id)
    p.close_shell(shell_id)
    return resp
Exemplo n.º 19
0
class Session(object):
    #TODO implement context manager methods
    def __init__(self, url, auth):
        #TODO convert short urls into well-formed endpoint
        username, password = auth
        self.protocol = Protocol(url, username=username, password=password)

    def run_cmd(self, command, args=()):
        #TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs
Exemplo n.º 20
0
    def connectWin(self, host_ip, u_name, p_word, softwares, tc_name):
        """
        Connects to Windows Host and checks for software existence

            - **parameters**, **types**, **return** and **return types**::

            :param host_ip: windows host ip
            :param u_name: windows host username
            :param p_word: windows host password
            :param softwares: list of softwares to be checked
            :type host_ip: string
            :type u_name: string
            :type p_word: string
            :type softwares: list
        """
        hostIP = "http://" + host_ip + ":5985/wsman"
        try:
            pro = Protocol(endpoint=hostIP,
                           transport='ntlm',
                           username=u_name,
                           password=p_word,
                           server_cert_validation='ignore')
            logger.info("\n***Connecting  to Windows Host...")
            shell_id = pro.open_shell()
            for software in softwares:
                logger.info("Checking for software {} in "\
                            "windows" .format(software))
                command_id = pro.run_command(
                    shell_id, self.getSoftwareCmd(software, "Windows"))
                std_out, std_err, status_code = pro.get_command_output(
                    shell_id, command_id)
                msg = "Software {} does not exist in the C drive.."\
                    "Hence Skipping"\
                      "the test case {}..." .format(software, tc_name)
                if std_out == "":
                    notify.message(msg)
                    raise Exception(msg)
                msg = 'Found software on host %s at ' % host_ip + std_out
                logger.info(msg)
                pro.cleanup_command(shell_id, command_id)
            pro.close_shell(shell_id)
        except Exception as e:
            text = "Requirements pre check failed.. "\
                "Hence Skipping the test case "\
               "{} ..." .format(tc_name)
            logger.error(text)
            notify.message(text)
            raise Exception(text)
Exemplo n.º 21
0
 def run(self, host, password, username='******',
         port=5732, secure=True):
     proto = 'https' if secure else 'http'
     p = Protocol(
         endpoint='%s://%s:%i/wsman' % (proto, host, port),  # RFC 2732?
         transport='ntlm',
         username=username,
         password=password,
         server_cert_validation='ignore')
     shell_id = p.open_shell()
     command_id = p.run_command(shell_id, 'ipconfig', ['/all'])
     std_out, std_err, status_code = p.get_command_output(shell_id,
                                                          command_id)
     p.cleanup_command(shell_id, command_id)
     p.close_shell(shell_id)
     return {'stdout': std_out, 'stderr': std_err}
Exemplo n.º 22
0
def run_to_delete(server_name, remote_path):
    """
      Delete file from remote Windows host.
      Remark: No handing of any kind of exeception. Kerberos ticket should be intiated.
      Args:
        server_name(string): Name of the host to connect.
        remote_path(string): Absolute path to remote file.
      Returns:
  """
    host_name = "http://" + server_name + ":5985/wsman"
    conn = Protocol(endpoint=host_name, transport='kerberos')
    shell_id = conn.open_shell()

    command_id = conn.run_command(shell_id, "del " + remote_path)
    stdout, stderr, return_code = conn.get_command_output(shell_id, command_id)
    conn.cleanup_command(shell_id, command_id)
    conn.close_shell(shell_id)
Exemplo n.º 23
0
def do_winrm(lport, windows_user, windows_password, winrm_cmd):
    # if used with Terraform, there is an issue with backslashes so use the #BACKSLASH# placeholder instead
    winrm_cmd = winrm_cmd.replace("#BACKSLASH#", "\\\\")
    p = Protocol(
        endpoint='http://127.0.0.1:' + str(lport) + '/wsman',
        transport='basic',
        message_encryption='never',
        username=windows_user,
        password=windows_password,
        server_cert_validation='ignore')

    shell_id = p.open_shell()
    command_id = p.run_command(shell_id, 'powershell.exe', [winrm_cmd])
    cmd_output = p.get_command_output(shell_id, command_id)
    for l in cmd_output:
        print (str(l).replace("\r\n", "\n"))
    p.cleanup_command(shell_id, command_id)
    p.close_shell(shell_id)
def run_command_with_codepage(server, script, codepage=936):
    """
    [Chinese characters are not displayed properly #288](https://github.com/diyan/pywinrm/issues/288)
    [Code Page Identifiers](https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers)

    codepage use 936, gb2312, ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)

    :param server:
    :type server:
    :param script:
    :type script:
    :param codepage:
    :type codepage:
    :return:
    :rtype:
    """
    ip, user, psw = get_acc_psw_with_ends(server)

    script = to_unicode_or_bust(script)
    encoded_ps = b64encode(script.encode('utf_16_le')).decode("ascii")

    p = Protocol(endpoint='http://{}:5985/wsman'.format(ip),
                 transport='ntlm',
                 username=user,
                 password=psw)

    shell_id = p.open_shell(codepage=codepage)
    try:
        command_id = p.run_command(shell_id, 'powershell.exe',
                                   ['-EncodedCommand', encoded_ps])
        try:
            std_out, std_err, status_code = p.get_command_output(
                shell_id, command_id)
        finally:
            p.cleanup_command(shell_id, command_id)
    finally:
        p.close_shell(shell_id)

    print(std_out.decode('utf-8'))
    print(std_err.decode('utf-8'))
    print(status_code)

    return status_code, std_out, std_err
Exemplo n.º 25
0
def run_from_copy(server_name, local_path, remote_path):
    """
      Transfer text file from remote Windows host to local Unix host.
      Remark: No handing of any kind of exeception. Kerberos ticket should be intiated.
      Args:
        server_name(string): Name of the host to connect.
        local_path(string): Absolute path to local file.
        remote_path(string): Absolute path to remote file.
      Returns:
        
  """
    host_name = "http://" + server_name + ":5985/wsman"
    conn = Protocol(endpoint=host_name, transport='kerberos')
    shell_id = conn.open_shell()

    command_id = conn.run_command(shell_id, "type " + remote_path)
    stdout, stderr, return_code = conn.get_command_output(shell_id, command_id)
    conn.cleanup_command(shell_id, command_id)
    file = open(local_path, 'w')
    file.write(stdout.decode('ascii'))
    file.close()
    conn.close_shell(shell_id)
Exemplo n.º 26
0
    def _winrm_commands(self, node, commands):
        ip = node.private_ips[0]
        p = Protocol(
                endpoint='http://%s:5985/wsman' % ip,  # RFC 2732
                transport='ntlm',
                username=self.username,
                password=self.secret,
                server_cert_validation='ignore')
        shell_id = p.open_shell()
        std_out_logs = []
        std_err_logs = []

        # run the commands in sequence.
        for command, params in commands:
            command_id = p.run_command(shell_id, command, params)
            std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
            std_out_logs.append(std_out)
            std_err_logs.append(std_err)
            p.cleanup_command(shell_id, command_id)

        p.close_shell(shell_id)
        return std_out_logs, std_err_logs
Exemplo n.º 27
0
    def getCitrix(self):
        script = """
Add-PSSnapin Citrix.*
$m = Get-BrokerMachine -MaxRecordCount 5000
$json = ConvertTo-JSON -compress $m
$json
"""

        shell_id = None
        command_id = None
        p = None
        error = False
        try:
            from winrm.protocol import Protocol
            p = Protocol(endpoint='http://' + self.ddc + ':5985/wsman',
                         transport='ntlm',
                         username=self.username,
                         password=self.password,
                         server_cert_validation='ignore')
            shell_id = p.open_shell()
            encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
            command_id = p.run_command(shell_id, 'powershell', [
                '-encodedcommand {0}'.format(encoded_ps),
            ])
            std_out, std_err, status_code = p.get_command_output(
                shell_id, command_id)
            citrix = json.loads(std_out, 'latin-1')
            if not isinstance(citrix, list):
                citrix = [citrix]
        except Exception as e:
            print("UNKNOWN - Unable to get data from Citrix DDC (%s) %s." %
                  (str(e), type(e).__name__))
            error = True
        finally:
            p.cleanup_command(shell_id, command_id)
            p.close_shell(shell_id)
        if error: exit(3)
        return citrix
Exemplo n.º 28
0
def run_to_copy(server_name, local_path, remote_path):
    """
      Transfer text file to remote Windows host.
      Remark: No handing of any kind of exeception. Kerberos ticket should be intiated.
      Args:
        server_name(string): Name of the host to connect.
        local_path(string): Absolute path to local file.
        remote_path(string): Absolute path to remote file.
      Returns:
        
  """
    host_name = "http://" + server_name + ":5985/wsman"
    conn = Protocol(endpoint=host_name, transport='kerberos')
    shell_id = conn.open_shell()

    file = open(local_path, 'r')
    text_file = file.read()
    file.close()

    remote_path_str = '"' + remote_path + '"'
    part_1 = """$stream = [System.IO.StreamWriter] """ + remote_path_str + """
$s = @"
"""

    part_2 = """
"@ | %{ $_.Replace("`n","`r`n") }
$stream.WriteLine($s)
$stream.close()"""

    script = part_1 + text_file + part_2
    encoded_script = base64.b64encode(
        script.encode('utf_16_le')).decode('ascii')
    command_id = conn.run_command(
        shell_id, "powershell -encodedcommand %s" % (encoded_script))
    stdout, stderr, return_code = conn.get_command_output(shell_id, command_id)
    conn.cleanup_command(shell_id, command_id)
    conn.close_shell(shell_id)
Exemplo n.º 29
0
class ManageSiteCentralServices:
    ssh = None
    winrm = None
    default_xml_file = None
    paramiko_log_file = None
    version = None

    def __init__(self):
        # self.default_xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "server_config.xml")
        self.paramiko_log_file = os.path.join(os.path.dirname(__file__),
                                              "paramiko.log")
        self.set_paramiko_log_file()
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
        self.version = "version 0.3"

    def set_xml_file(self, path):
        self.default_xml_file = path

    def set_paramiko_log_file(self):
        paramiko.util.log_to_file(self.paramiko_log_file)

    def get_version(self):
        return self.version

    def init_ssh_connection(self, host, port, login, password):
        try:
            self.ssh.connect(hostname=host,
                             port=int(port),
                             username=login,
                             password=password,
                             timeout=60)
            return True
        except Exception as ex:
            print "\t=> SSH : Authentication failed on server: %s cause: %s" % (
                host, str(ex))
            return False

    def close_ssh_connection(self):
        self.ssh.close()

    def execute_ssh_shell_cmd(self, cmd):
        try:
            stdin, stdout, stderr = self.ssh.exec_command(cmd)
            while not stdout.channel.recv_exit_status():
                sleep(1)
                break
            while not stderr.channel.recv_exit_status():
                sleep(1)
                break
            return stdout.readlines(), stderr.readlines()
        except Exception as ex:
            print "\t=> Problem when executing command: %s, cause: %s " % (cmd,
                                                                           ex)

    def init_winrm_connection(self, host, port, username, password):
        endpoint = 'https://%s:%s/wsman' % (host, port)
        try:
            self.winrm = Protocol(endpoint=endpoint,
                                  transport='ntlm',
                                  username=username,
                                  password=password,
                                  server_cert_validation='ignore')
            return True
        except Exception as ex:
            print "\t=> WinRM : Authentication failed on server: %s cause: %s" % (
                host, str(ex))
            return False

    def execute_winrm_shell_cmd(self, cmd):
        stdout = list()
        stderr = list()
        try:
            pars_cmd = cmd.strip().split(' ')
            # print pars_cmd
            command_cmd = pars_cmd[0]
            # print command_cmd
            # param_cmd = pars_cmd.remove(command_cmd) # return None !!!
            param_cmd = pars_cmd[1:]
            # print param_cmd
            shell_id = self.winrm.open_shell()
            command_id = self.winrm.run_command(shell_id, command_cmd,
                                                param_cmd)
            stdout, stderr, status_code = self.winrm.get_command_output(
                shell_id, command_id)
            # print stdout
            # print stderr
            # print status_code
            self.winrm.cleanup_command(shell_id, command_id)
            self.winrm.close_shell(shell_id)
            return stdout, stderr
        except Exception as ex:
            print "\t=> WinRM : Authentication failed, cause: %s" % (str(ex))
            return stdout, stderr

    def get_service_status(self, service, os="linux"):
        # stdout, stderr = self.execute_ssh_shell_cmd("/etc/init.d/" + service + " status")
        # stdout, stderr = self.execute_ssh_shell_cmd("ps -ef | grep -v grep | grep " + service + " | wc -l")
        if os == "linux":
            stdout, stderr = self.execute_ssh_shell_cmd("service " + service +
                                                        " status")
        elif os == "windows":
            cmd = "sc query %s" % service
            stdout, stderr = self.execute_winrm_shell_cmd(cmd)
            list_tmp = list()
            stdout = r'%s' % stdout
            stdout = stdout.replace(" ", "").replace("\r",
                                                     "").replace("\n", " ")
            # print stdout
            list_tmp.append(str(stdout))
            stdout = list_tmp
            list_tmp = list()
            stderr = r'%s' % stderr
            stderr = stderr.replace(" ", "").replace("\r",
                                                     "").replace("\n", " ")
            list_tmp.append(str(stderr))
            stderr = list_tmp

        if len(stdout) != 0:
            status = ""
            for resp in stdout:
                if resp.strip().lower().find('running') != -1:
                    status = "running"
                    break
                elif resp.strip().lower().find('stopped') != -1:
                    status = "stopped"
                    break
                elif resp.strip().lower().find('en cours') != -1:
                    status = "running"
                    break
                elif resp.strip().lower().find('arrêté') != -1:
                    status = "stopped"
                    break
                else:
                    status = "unknown"
            return status
        else:
            data = ""
            for chaine in stderr:
                data = data + chaine.replace("\n", ' ')
            return data

    def manage_service(self, service, action, os):
        service_status = self.get_service_status(service, os)
        if action == "start":
            if service_status == "stopped":
                # self.execute_ssh_shell_cmd("/etc/init.d/" + service + " " + action)
                self.execute_ssh_shell_cmd("service " + service + " " + action)
                return "Service: %s -> started" % service
            elif service_status == "running":
                return "Service: %s -> already running, not need to start it!" % service
            elif service_status == "unknown":
                return "Service: %s -> unknown" % service
            else:
                return service_status
                # pass
                # return "error !! 11"
        elif action == "stop":
            if service_status == "running":
                # self.execute_ssh_shell_cmd("/etc/init.d/" + service + " " + action)
                self.execute_ssh_shell_cmd("service " + service + " " + action)
                return "Service: %s -> stopped" % service
            elif service_status == "stopped":
                return "Service: %s -> already stopped, not need to stop it!" % service
            elif service_status == "unknown":
                return "Service: %s -> unknown" % service
            else:
                return service_status
                # pass
                # return "error !! 22"

    # Parse All xml file and return list of information
    def get_xml_info(self):
        list_serv = list()
        xmldict = dict()
        if not os.path.exists(self.default_xml_file):
            print "File: ' %s ' not found !" % self.default_xml_file
            # raise Exception("File: ' %s ' not found !" % self.default_xml_file)
            sys.exit(-2)
        with open(self.default_xml_file) as file:
            try:
                xmldict = xmltodict.parse(file.read())
            except Exception as ex:
                print "\t\t\t=> Problem on parsing xml file, cause: %s" % str(
                    ex)
                sys.exit(-1)
        if len(xmldict) != 0:
            for server in xmldict['config']['pop']['server']:
                dict_serv = dict()
                list_action_serv = list()
                dict_serv['order'] = server['@order']
                dict_serv['name'] = server['@name']
                dict_serv['os'] = server['@os']
                dict_serv['model'] = server['@model']
                dict_serv['login'] = server['connection']['@login']
                dict_serv['password'] = server['connection']['@password']
                dict_serv['ip'] = server['address']['@ip']
                dict_serv['port'] = server['address']['@port']
                for action in server['actions']['action']:
                    dict_action_serv = dict()
                    dict_action_serv['order'] = action['@order']
                    dict_action_serv['type'] = action['@type']
                    if dict_action_serv['type'] == "service":
                        dict_action_serv['name'] = action['@name']
                    elif dict_action_serv['type'] == "command":
                        dict_action_serv['src'] = action['@src']
                        dict_action_serv['name'] = action['@name']
                        dict_action_serv['use'] = action['@use']
                        dict_action_serv['param'] = action['@param']
                    list_action_serv.append(dict_action_serv)
                    # sort list by order dictionary
                    dict_serv['actions'] = sorted(
                        list_action_serv, key=lambda k: int(k['order']))
                # print sorted(list_action_serv, key=lambda k: k['order'])
                list_serv.append(dict_serv)
        else:
            print "Emty xml file: %s " % self.default_xml_file
            sys.exit(-1)
        return sorted(list_serv, key=lambda k: int(k['order']))

    def display_services_status(self, list_server):
        for server in list_server:
            server_name = server.get('name')
            server_order = server.get('order')
            server_os = server.get('os')
            # print "start connexion to: %s server" % server_name
            print "\n\t[Server: %s] [OS: %s] [Order: %s]" % (
                server_name, server_os, server_order)
            print "\t|----------------------------------------------------------------------------------------------------"
            print "\t|Type:\t\t|\tName:\t\t|\tOrder:\t|\tCurrent status:\t|\tcount process"
            print "\t|----------------------------------------------------------------------------------------------------"
            if server.get('os').strip().lower() == "windows":
                if self.init_winrm_connection(server.get('ip'),
                                              server.get('port'),
                                              server.get('login'),
                                              server.get('password')):
                    for action in server.get('actions'):
                        action_type = action.get('type')
                        action_name = action.get(
                            'name')  # if action_type == "service" else "----"
                        action_order = action.get('order')
                        # action_current_status = self.get_win_service_status(action_name)
                        action_current_status = self.get_service_status(
                            action_name, os="windows")
                        count_process = "x"
                        if len(action_name) >= 8:
                            print "\t|%s\t|\t%s\t|\t%s\t|\t%s\t\t|\t%s" % (
                                action_type, action_name, action_order,
                                action_current_status, count_process)
                        else:
                            print "\t|%s\t|\t%s\t\t|\t%s\t|\t%s\t\t|\t%s" % (
                                action_type, action_name, action_order,
                                action_current_status, count_process)
                else:
                    print "\t=> WinRM : Connection or Authentication failed"

            elif server.get('os').strip().lower() == "linux":
                if self.init_ssh_connection(server.get('ip'),
                                            server.get('port'),
                                            server.get('login'),
                                            server.get('password')):
                    for action in server.get('actions'):
                        action_type = action.get('type')
                        action_name = action.get(
                            'name')  # if action_type == "service" else "----"
                        action_order = action.get('order')
                        # action_command = "/etc/init.d/" + action_name + " stop" if action_type == "service" else action.get('src')
                        if action_name == "distribHTTPcgm":
                            stdout, stderr = self.execute_ssh_shell_cmd(
                                "ps -ef | grep -v grep | grep centralGetMAI | wc -l"
                            )
                        elif action_name == "distribHTTPmmc":
                            stdout, stderr = self.execute_ssh_shell_cmd(
                                "ps -ef | grep -v grep | grep maintenanceMissionC | wc -l"
                            )
                        elif action_name == "scenvoitrap":
                            stdout, stderr = self.execute_ssh_shell_cmd(
                                "ps -ef | grep -v grep | grep scEnvoiTrap | wc -l"
                            )
                        elif action_name == "ipldist":
                            stdout, stderr = self.execute_ssh_shell_cmd(
                                "ps -ef | grep -v grep | grep -e -gen.pl | wc -l"
                            )
                        else:
                            stdout, stderr = self.execute_ssh_shell_cmd(
                                "ps -ef | grep -v grep | grep " + action_name +
                                " | wc -l")
                        count_process = stdout[0].replace("\n", "")
                        if action_name == "crontab":
                            count_process = "x"
                        if action_type == "service":
                            action_current_status = self.get_service_status(
                                action_name, os="linux")
                        elif action_type == "command" and action.get(
                                'use') == "like_service":
                            if int(count_process) > 0:
                                action_current_status = "running"
                            else:
                                action_current_status = "stopped"
                        else:
                            action_current_status = "-------"
                        # action_cmd_name =
                        # print "\t%s\t|\t%s\t|\t%s\t\t|\t%s" % (action_type, action_name, action_order, action_command)
                        if len(action_name) >= 8:
                            print "\t|%s\t|\t%s\t|\t%s\t|\t%s\t\t|\t%s" % (
                                action_type, action_name, action_order,
                                action_current_status, count_process)
                        else:
                            print "\t|%s\t|\t%s\t\t|\t%s\t|\t%s\t\t|\t%s" % (
                                action_type, action_name, action_order,
                                action_current_status, count_process)

                    self.close_ssh_connection()
                else:
                    print "\t=> SSH : Connection or Authentication failed"
            else:
                print "\t=> server_config.xml: error type os not managed use (linux or windows)"
            print "\t|----------------------------------------------------------------------------------------------------\n"
Exemplo n.º 30
0
class Session(object):
    # TODO implement context manager methods
    def __init__(self, target, auth, **kwargs):
        username, password = auth
        self.url = self._build_url(target, kwargs.get('transport',
                                                      'plaintext'))
        self.protocol = Protocol(self.url,
                                 username=username,
                                 password=password,
                                 **kwargs)

    def run_cmd(self, command, args=()):
        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    def run_ps(self, script):
        """base64 encodes a Powershell script and executes the powershell
        encoded script command
        """
        # must use utf16 little endian on windows
        encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
        rs = self.run_cmd('powershell -encodedcommand {0}'.format(encoded_ps))
        if len(rs.std_err):
            # if there was an error message, clean it it up and make it human
            # readable
            rs.std_err = self._clean_error_msg(rs.std_err)
        return rs

    def _clean_error_msg(self, msg):
        """converts a Powershell CLIXML message to a more human readable string
        """
        # TODO prepare unit test, beautify code
        # if the msg does not start with this, return it as is
        if msg.startswith(b"#< CLIXML\r\n"):
            # for proper xml, we need to remove the CLIXML part
            # (the first line)
            msg_xml = msg[11:]
            try:
                # remove the namespaces from the xml for easier processing
                msg_xml = self._strip_namespace(msg_xml)
                root = ET.fromstring(msg_xml)
                # the S node is the error message, find all S nodes
                nodes = root.findall("./S")
                new_msg = ""
                for s in nodes:
                    # append error msg string to result, also
                    # the hex chars represent CRLF so we replace with newline
                    new_msg += s.text.replace("_x000D__x000A_", "\n")
            except Exception as e:
                # if any of the above fails, the msg was not true xml
                # print a warning and return the orignal string
                # TODO do not print, raise user defined error instead
                print("Warning: there was a problem converting the Powershell"
                      " error message: %s" % (e))
            else:
                # if new_msg was populated, that's our error message
                # otherwise the original error message will be used
                if len(new_msg):
                    # remove leading and trailing whitespace while we are here
                    return new_msg.strip().encode('utf-8')

        # either failed to decode CLIXML or there was nothing to decode
        # just return the original message
        return msg

    def _strip_namespace(self, xml):
        """strips any namespaces from an xml string"""
        p = re.compile(b"xmlns=*[\"\"][^\"\"]*[\"\"]")
        allmatches = p.finditer(xml)
        for match in allmatches:
            xml = xml.replace(match.group(), b"")
        return xml

    @staticmethod
    def _build_url(target, transport):
        match = re.match(
            '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?',
            target)  # NOQA
        scheme = match.group('scheme')
        if not scheme:
            # TODO do we have anything other than HTTP/HTTPS
            scheme = 'https' if transport == 'ssl' else 'http'
        host = match.group('host')
        port = match.group('port')
        if not port:
            port = 5986 if transport == 'ssl' else 5985
        path = match.group('path')
        if not path:
            path = 'wsman'
        return '{0}://{1}:{2}/{3}'.format(scheme, host, port, path.lstrip('/'))
Exemplo n.º 31
0
class Session(object):
    # TODO implement context manager methods
    def __init__(self, target, auth, **kwargs):
        username, password = auth
        self.url = self._build_url(target, kwargs.get('transport',
                                                      'plaintext'))
        self.protocol = Protocol(self.url,
                                 username=username,
                                 password=password,
                                 **kwargs)

    def run_cmd(self, command, args=()):
        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell(codepage=65001)  # utf-8
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    def run_ps(self, script):
        """base64 encodes a Powershell script and executes the powershell
        encoded script command
        """

        script_bytes = script.encode('utf-8')
        packed_expression = b64encode(script_bytes).decode('ascii')

        # Use a custom strategy that encodes the script as UTF-8 instead of the
        # UTF-16-LE encoding employed by PowerShell's "-EncodedCommand". This
        # improves performance and increases the maximum script size by
        # reducing the size of the payload.
        expression_template = (
            'Invoke-Expression '
            '$([System.Text.Encoding]::UTF8.GetString('
            "[Convert]::FromBase64String('{0}'))"  # NOQA
            ')')
        command = expression_template.format(packed_expression)

        rs = self.run_cmd('powershell -command "{0}"'.format(command))
        if len(rs.std_err):
            # if there was an error message, clean it it up and make it human
            # readable
            rs.std_err = self._clean_error_msg(rs.std_err)

        return rs

    def _clean_error_msg(self, msg):
        """converts a Powershell CLIXML message to a more human readable string
        """
        # TODO prepare unit test, beautify code
        if sys.version_info[:2] == (3, 7) and not isinstance(msg, text_type):
            msg = msg.decode('utf-8')
        # if the msg does not start with this, return it as is
        if msg.startswith("b#< CLIXML"):
            # for proper xml, we need to remove the CLIXML part
            # (the first line)
            msg_xml = msg[11:]
            try:
                # remove the namespaces from the xml for easier processing
                msg_xml = self._strip_namespace(msg_xml)
                root = ET.fromstring(msg_xml)
                # the S node is the error message, find all S nodes
                nodes = root.findall("./S")
                new_msg = ""
                for s in nodes:
                    # append error msg string to result, also
                    # the hex chars represent CRLF so we replace with newline
                    new_msg += s.text.replace("_x000D__x000A_", "\n")
            except Exception as e:
                # if any of the above fails, the msg was not true xml
                # print a warning and return the orignal string
                # TODO do not print, raise user defined error instead
                print("Warning: there was a problem converting the Powershell"
                      " error message: %s" % (e))
            else:
                # if new_msg was populated, that's our error message
                # otherwise the original error message will be used
                if len(new_msg):
                    # remove leading and trailing whitespace while we are here
                    msg = new_msg.strip().encode('utf-8')
        return msg

    def _strip_namespace(self, xml):
        """strips any namespaces from an xml string"""
        p = re.compile(b"xmlns=*[\"\"][^\"\"]*[\"\"]")
        allmatches = p.finditer(xml)
        for match in allmatches:
            xml = xml.replace(match.group(), b"")
        return xml

    @staticmethod
    def _build_url(target, transport):
        match = re.match(
            '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?',
            target)  # NOQA
        scheme = match.group('scheme')
        if not scheme:
            # TODO do we have anything other than HTTP/HTTPS
            scheme = 'https' if transport == 'ssl' else 'http'
        host = match.group('host')
        port = match.group('port')
        if not port:
            port = 5986 if transport == 'ssl' else 5985
        path = match.group('path')
        if not path:
            path = 'wsman'
        return '{0}://{1}:{2}/{3}'.format(scheme, host, port, path.lstrip('/'))
Exemplo n.º 32
0
            cds = rin[3:]
            cds.strip()
            if cds != None and cds != '':
                p.close_shell(sh)
                sh = p.open_shell(working_directory=cds)
            rin = 'cd'

        try:
            cmd = p.run_command(sh, rin, [])
            rout, rerr, stat = p.get_command_output(sh, cmd)
            if rout != None and rerr != '':
                t = rout.decode('utf-8')
                if t != None:
                    print("%s" % t.strip())
            if rerr != None and rerr != '':
                t = rerr.decode('utf-8')
                if t != None:
                    print("%s" % t.strip())
            p.cleanup_command(sh, cmd)
        except:
            print("Unexpected error happened!")
    rin = input("> ")
    if rin != None:
        rin.strip()

try:
    p.close_shell(sh)
except:
    pass

Exemplo n.º 33
0
class Session(object):
    # TODO implement context manager methods
    def __init__(self, target, auth, transport='plaintext',
                 timeout=None):
        username, password = auth
        self.url = self._build_url(target, transport)
        self.protocol = Protocol(self.url, transport=transport,
                                 username=username, password=password,
                                 timeout=timeout)

    def run_cmd(self, command, args=()):
        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    def run_ps(self, script):
        """base64 encodes a Powershell script and executes the powershell
        encoded script command
        """
        # must use utf16 little endian on windows
        encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
        rs = self.run_cmd('powershell -encodedcommand {0}'.format(encoded_ps))
        if len(rs.std_err):
            # if there was an error message, clean it it up and make it human
            # readable
            rs.std_err = self._clean_error_msg(rs.std_err)
        return rs

    def _clean_error_msg(self, msg):
        """converts a Powershell CLIXML message to a more human readable string
        """
        # TODO prepare unit test, beautify code
        # if the msg does not start with this, return it as is
        if msg.startswith("#< CLIXML\r\n"):
            # for proper xml, we need to remove the CLIXML part
            # (the first line)
            msg_xml = msg[11:]
            try:
                # remove the namespaces from the xml for easier processing
                msg_xml = self._strip_namespace(msg_xml)
                root = ET.fromstring(msg_xml)
                # the S node is the error message, find all S nodes
                nodes = root.findall("./S")
                new_msg = ""
                for s in nodes:
                    # append error msg string to result, also
                    # the hex chars represent CRLF so we replace with newline
                    new_msg += s.text.replace("_x000D__x000A_", "\n")
            except Exception as e:
                # if any of the above fails, the msg was not true xml
                # print a warning and return the orignal string
                # TODO do not print, raise user defined error instead
                print("Warning: there was a problem converting the Powershell"
                      " error message: %s" % (e))
            else:
                # if new_msg was populated, that's our error message
                # otherwise the original error message will be used
                if len(new_msg):
                    # remove leading and trailing whitespace while we are here
                    msg = new_msg.strip()
        return msg

    def _strip_namespace(self, xml):
        """strips any namespaces from an xml string"""
        try:
            p = re.compile("xmlns=*[\"\"][^\"\"]*[\"\"]")
            allmatches = p.finditer(xml)
            for match in allmatches:
                xml = xml.replace(match.group(), "")
            return xml
        except Exception as e:
            raise Exception(e)

    @staticmethod
    def _build_url(target, transport):
        match = re.match(
            '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?', target)  # NOQA
        scheme = match.group('scheme')
        if not scheme:
            # TODO do we have anything other than HTTP/HTTPS
            scheme = 'https' if transport == 'ssl' else 'http'
        host = match.group('host')
        port = match.group('port')
        if not port:
            port = 5986 if transport == 'ssl' else 5985
        path = match.group('path')
        if not path:
            path = 'wsman'
        return '{0}://{1}:{2}/{3}'.format(scheme, host, port, path.lstrip('/'))
Exemplo n.º 34
0
class Session(object):
    # TODO implement context manager methods
    def __init__(self, target, auth, transport='plaintext'):
        username, password = auth
        self.url = self._build_url(target, transport)
        self.protocol = Protocol(self.url, transport=transport,
                                 username=username, password=password)

    def run_cmd(self, command, args=()):
        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()
        command_id = self.protocol.run_command(shell_id, command, args)
        rs = Response(self.protocol.get_command_output(shell_id, command_id))
        self.protocol.cleanup_command(shell_id, command_id)
        self.protocol.close_shell(shell_id)
        return rs

    def run_ps_long(self, script):
        """base64 encodes a Powershell script and executes the powershell
        encoded script command
        """

        shell_id = self.protocol.open_shell()

        def run_command(command):
            command_id = self.protocol.run_command(shell_id, command)
            rs = Response(self.protocol.get_command_output(shell_id, command_id))
            self.protocol.cleanup_command(shell_id, command_id)

            # Powershell errors are returned in XML, clean them up
            if len(rs.std_err):
                rs.std_err = self.clean_error_msg(rs.std_err)
            return rs

        def make_ps_command(ps_script):
            return ("powershell -encodedcommand %s"
                        % base64.b64encode(ps_script.encode("utf_16_le")))

        def run_and_check_ps(command, stage_message):
            rs = run_command(command)
            if len(rs.std_err) or rs.status_code != 0:
                self.protocol.close_shell(shell_id)
                raise Exception("%s\n%s" % (stage_message, rs.std_err))
            return rs.std_out

        # Get the name of a temp file
        cmd = ("$script_file = [IO.Path]::GetTempFileName() | "
                    " Rename-Item -NewName { $_ -replace 'tmp$', 'tmp.ps1' } -PassThru\n"
               '"$script_file"')
        script_file = run_and_check_ps(make_ps_command(cmd), "Creating temp script file")
        script_file = script_file.strip()

        # Append the data to the file
        base64_script = base64.b64encode(script)
        chunk_size = 2000
        for chunk_index in range(0, len(base64_script), chunk_size):
            chunk = base64_script[chunk_index:chunk_index + chunk_size]
            cmd ='ECHO %s %s "%s" ' % (chunk,
                                    ('>>' if chunk_index else '>'),
                                    script_file)
            run_and_check_ps(cmd, "writing chunk %s to temp script file" % chunk_index)

        # Execute the powershell script
        cmd = '''
            # Convert it from b64 encoded
            $b64 = get-content "%(script_file)s"
            [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($b64)) |
                out-file -Encoding Default "%(script_file)s"
        ''' % {'script_file':script_file}
        run_and_check_ps(make_ps_command(cmd),
                         "Converting temp script file back from b64 encoding")

        cmd = ("""PowerShell.exe -ExecutionPolicy Bypass -Command "& '%s' " """
                    % script_file)
        rs = run_command(cmd)

        # Finally, cleanup the temp file
        cmd = "remove-item '%s' " % script_file
        run_and_check_ps(make_ps_command(cmd), "Deleting temp script file")

        self.protocol.close_shell(shell_id)

        return rs


    def run_ps(self, script):
        # Get a temp powershell file name

        # TODO optimize perf. Do not call open/close shell every time
        shell_id = self.protocol.open_shell()

        base64_script = base64.b64encode(script.encode("utf_16_le"))

        # There is an issue with powershell scripts over 2k or 8k (platform dependent)
        # You can not have a command line + argument longer than this
        if len(base64_script) > 2000:
            return self.run_ps_long(script)

        # must use utf16 little endian on windows
        rs = self.run_cmd("powershell -encodedcommand %s" % (base64_script))
        if len(rs.std_err):
            # Clean it it up and make it human readable
            rs.std_err = self.clean_error_msg(rs.std_err)
        return rs


    def clean_error_msg(self, msg):
        """converts a Powershell CLIXML message to a more human readable string
        """

        # if the msg does not start with this, return it as is
        if msg.startswith("#< CLIXML\r\n"):
            # for proper xml, we need to remove the CLIXML part
            # (the first line)
            msg_xml = msg[11:]
            try:
                # remove the namespaces from the xml for easier processing
                msg_xml = self.strip_namespace(msg_xml)
                root = ET.fromstring(msg_xml)
                # the S node is the error message, find all S nodes
                nodes = root.findall("./S")
                new_msg = ""
                for s in nodes:
                    # append error msg string to result, also
                    # the hex chars represent CRLF so we replace with newline
                    new_msg += s.text.replace("_x000D__x000A_", "\n")
            except Exception as e:
                # if any of the above fails, the msg was not true xml
                # print a warning and return the orignal string
                print("Warning: there was a problem converting the Powershell"
                      " error message: %s" % (e))
            else:
                # if new_msg was populated, that's our error message
                # otherwise the original error message will be used
                if len(new_msg):
                    # remove leading and trailing whitespace while we are here
                    msg = new_msg.strip()
        return msg

    def strip_namespace(self, xml):
        """strips any namespaces from an xml string"""
        try:
            p = re.compile("xmlns=*[\"\"][^\"\"]*[\"\"]")
            allmatches = p.finditer(xml)
            for match in allmatches:
                xml = xml.replace(match.group(), "")
            return xml
        except Exception as e:
            raise Exception(e)

    @staticmethod
    def _build_url(target, transport):
        match = re.match(
            '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?', target)  # NOQA
        scheme = match.group('scheme')
        if not scheme:
            # TODO do we have anything other than HTTP/HTTPS
            scheme = 'https' if transport == 'ssl' else 'http'
        host = match.group('host')
        port = match.group('port')
        if not port:
            port = 5986 if transport == 'ssl' else 5985
        path = match.group('path')
        if not path:
            path = 'wsman'
        return '{0}://{1}:{2}/{3}'.format(scheme, host, port, path.lstrip('/'))
Exemplo n.º 35
0
from winrm.protocol import Protocol

p = Protocol(endpoint='http://<host fqdn>:5985/wsman',
             transport='ntlm',
             username='',
             password='',
             server_cert_validation='ignore')
shell_id = p.open_shell()
#command_id = p.run_command(shell_id, 'ipconfig', ['/all'])
command_id = p.run_command(shell_id, 'powershell', ['$PSVersionTable'])
std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
print(std_out)
p.cleanup_command(shell_id, command_id)
p.close_shell(shell_id)
# Run a process on a remote host
s = winrm.Session('windows-host.example.com', auth=('john.smith', 'secret'))
r = s.run_cmd('ipconfig', ['/all'])
print r.status_code, r.std_out,

# Run Powershell script on remote host
ps_script = """$strComputer = $Host
Clear
$RAM = WmiObject Win32_ComputerSystem
$MB = 1048576

"Installed Memory: " + [int]($RAM.TotalPhysicalMemory /$MB) + " MB" """
r = s.run_ps(ps_script)
print r.status_code, r.std_out,

# Run process with low-level API with domain user, disabling HTTPS cert validation
from winrm.protocol import Protocol

p = Protocol(
    endpoint='https://windows-host:5986/wsman',
    transport='ntlm',
    username=r'somedomain\someuser',
    password='******',
    server_cert_validation='ignore')
shell_id = p.open_shell()
command_id = p.run_command(shell_id, 'ipconfig', ['/all'])
std_out, std_err, status_code = p.get_command_output(shell_id, command_id)
p.cleanup_command(shell_id, command_id)
p.close_shell(shell_id)