diff --git a/wsmancmd.py b/wsmancmd.py index 323a204..e40861d 100755 --- a/wsmancmd.py +++ b/wsmancmd.py @@ -20,52 +20,110 @@ from winrm import protocol +AUTH_BASIC = "basic" +AUTH_KERBEROS = "kerberos" +AUTH_CERTIFICATE = "certificate" + +DEFAULT_PORT_HTTP = 5985 +DEFAULT_PORT_HTTPS = 5986 + +CODEPAGE_UTF8 = 65001 def print_usage(): - print ("%s -U -u -p [cmd_args]" % - sys.argv[0]) + print ("%s [-U ] [-H ] [-P ] [-s] " + "[-a ] " + "[-u ] [-p ] " + "[-c -k ] " + " [cmd_args]" % sys.argv[0]) def parse_args(): - + args_ok = False + auth = AUTH_BASIC username = None password = None url = None + host = None + port = None + use_ssl = False cmd = None + cert_pem = None + cert_key_pem = None + server_cert_validation = 'validate' + is_powershell_cmd = False try: show_usage = False - opts, args = getopt.getopt(sys.argv[1:], "hU:u:p:c:") + opts, args = getopt.getopt(sys.argv[1:], "hsU:H:P:u:p:c:k:v:a:", + "powershell") for opt, arg in opts: if opt == "-h": show_usage = True + if opt == "-s": + use_ssl = True + if opt == "-H": + host = arg + if opt == "-P": + port = arg if opt == "-U": url = arg + elif opt == "-a": + auth = arg elif opt == "-u": username = arg elif opt == "-p": password = arg + elif opt == "-c": + cert_pem = arg + elif opt == "-k": + cert_key_pem = arg + elif opt == "-v": + server_cert_validation = arg + elif opt == "--powershell": + is_powershell_cmd = True cmd = args - if show_usage or not (url and username and password and cmd): + if (show_usage or not + (cmd and + (url and not host and not port and not use_ssl) or + host and ((bool(port) ^ bool(use_ssl) or + not port and not use_ssl)) and + (auth == AUTH_BASIC and username and password or + auth == AUTH_CERTIFICATE and cert_pem and cert_key_pem or + auth == AUTH_KERBEROS))): print_usage() + else: + args_ok = True except getopt.GetoptError: print_usage() - return (url, username, password, cmd) + return (args_ok, url, host, use_ssl, port, auth, username, password, + cert_pem, cert_key_pem, server_cert_validation, + cmd, is_powershell_cmd) -def run_wsman_cmd(url, username, password, cmd): +def run_wsman_cmd(url, auth, username, password, cert_pem, cert_key_pem, + server_cert_validation, cmd): protocol.Protocol.DEFAULT_TIMEOUT = "PT3600S" + if not auth: + auth = AUTH_BASIC + + auth_transport_map = {AUTH_BASIC: 'plaintext', + AUTH_KERBEROS: 'kerberos', + AUTH_CERTIFICATE: 'ssl'} + p = protocol.Protocol(endpoint=url, - transport='plaintext', + transport=auth_transport_map[auth], username=username, - password=password) + password=password, + cert_pem=cert_pem, + cert_key_pem=cert_key_pem, + server_cert_validation=server_cert_validation) - shell_id = p.open_shell() + shell_id = p.open_shell(codepage=CODEPAGE_UTF8) command_id = p.run_command(shell_id, cmd[0], cmd[1:]) std_out, std_err, status_code = p.get_command_output(shell_id, command_id) @@ -76,14 +134,41 @@ def run_wsman_cmd(url, username, password, cmd): return (std_out, std_err, status_code) -def main(): - exit_code = 0 - - url, username, password, cmd = parse_args() - if not (url and username and password and cmd): - exit_code = 1 +def get_url(url, host, use_ssl, port): + if url: + return url else: - std_out, std_err, exit_code = run_wsman_cmd(url, username, password, + if not port: + if use_ssl: + port = DEFAULT_PORT_HTTPS + else: + port = DEFAULT_PORT_HTTP + + if use_ssl: + protocol = "https" + else: + protocol = "http" + + return ("%(protocol)s://%(host)s:%(port)s/wsman" % locals()) + + +def main(): + exit_code = 1 + + (args_ok, url, host, use_ssl, port, auth, username, password, + cert_pem, cert_key_pem, server_cert_validation, + cmd, is_powershell_cmd) = parse_args() + if args_ok: + url = get_url(url, host, use_ssl, port) + + if is_powershell_cmd: + cmd = ["powershell.exe", "-ExecutionPolicy", "RemoteSigned", + "-NonInteractive", "-Command"] + cmd + + std_out, std_err, exit_code = run_wsman_cmd(url, auth, username, + password, cert_pem, + cert_key_pem, + server_cert_validation, cmd) sys.stdout.write(std_out) sys.stderr.write(std_err)