def _put_file_old(self, in_path, out_path): script = u'''begin { $ErrorActionPreference = "Stop" $ProgressPreference = 'SilentlyContinue' $path = '%s' $fd = [System.IO.File]::Create($path) $algo = [System.Security.Cryptography.SHA1CryptoServiceProvider]::Create() $bytes = @() } process { $bytes = [System.Convert]::FromBase64String($input) $algo.TransformBlock($bytes, 0, $bytes.Length, $bytes, 0) > $null $fd.Write($bytes, 0, $bytes.Length) } end { $fd.Close() $algo.TransformFinalBlock($bytes, 0, 0) > $null $hash = [System.BitConverter]::ToString($algo.Hash) $hash = $hash.Replace("-", "").ToLowerInvariant() Write-Output -InputObject "{`"sha1`":`"$hash`"}" }''' % out_path cmd_parts = self._shell._encode_script(script, as_list=True, strict_mode=False, preserve_rc=False) b_in_path = to_bytes(in_path, errors='surrogate_or_strict') if not os.path.exists(b_in_path): raise AnsibleFileNotFound('file or module does not exist: "%s"' % to_native(in_path)) in_size = os.path.getsize(b_in_path) buffer_size = int(self.runspace.connection.max_payload_size / 4 * 3) sha1_hash = sha1() # copying files is faster when using the raw WinRM shell and not PSRP # we will create a WinRS shell just for this process # TODO: speed this up as there is overhead creating a shell for this with WinRS(self.runspace.connection, codepage=65001) as shell: process = Process(shell, cmd_parts[0], cmd_parts[1:]) process.begin_invoke() offset = 0 with open(b_in_path, 'rb') as src_file: for data in iter((lambda: src_file.read(buffer_size)), b""): offset += len(data) display.vvvvv("PSRP PUT %s to %s (offset=%d, size=%d" % (in_path, out_path, offset, len(data)), host=self._psrp_host) b64_data = base64.b64encode(data) + b"\r\n" process.send(b64_data, end=(src_file.tell() == in_size)) sha1_hash.update(data) # the file was empty, return empty buffer if offset == 0: process.send(b"", end=True) process.end_invoke() process.signal(SignalCode.CTRL_C) return process.rc, process.stdout, process.stderr, sha1_hash.hexdigest()
def execute_cmd(self, command, encoding='437', environment=None): """ Executes a command in a cmd shell and returns the stdout/stderr/rc of that process. This uses the raw WinRS layer and can be used to execute a traditional process. :param command: The command to execute :param encoding: The encoding of the output std buffers, this correlates to the codepage of the host and traditionally en-US is 437. This probably doesn't need to be modified unless you are running a different codepage on your host :param environment: A dictionary containing environment keys and values to set on the executing process. :return: A tuple of stdout: A unicode string of the stdout stderr: A unicode string of the stderr rc: The return code of the process Both stdout and stderr are returned from the server as a byte string, they are converted to a unicode string based on the encoding variable set """ log.info("Executing cmd process '%s'" % command) with WinRS(self.wsman, environment=environment) as shell: process = Process(shell, command) process.invoke() process.signal(SignalCode.CTRL_C) return to_unicode(process.stdout, encoding), \ to_unicode(process.stderr, encoding), process.rc
def test_winrs_unicode(self, wsman_conn): with WinRS(wsman_conn, codepage=65001) as shell: process = Process(shell, "powershell.exe", [u"Write-Host こんにちは"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout.decode('utf-8') == u"こんにちは\n" assert process.stderr == b""
def test_winrs_standard(self, wsman_conn): with WinRS(wsman_conn) as shell: process = Process(shell, "cmd.exe", ["/c", "echo", "hi"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"hi\r\n" assert process.stderr == b""
def test_winrs_noprofile(self, wsman_conn): with WinRS(wsman_conn, no_profile=True) as shell: process = Process(shell, "cmd.exe", ["/c", "set"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert "USERPROFILE=C:\\Users\\Default" in \ process.stdout.decode('utf-8').splitlines() assert process.stderr == b""
def test_winrs_stderr_rc(self, wsman_conn): with WinRS(wsman_conn) as shell: process = Process(shell, "cmd.exe", ["/c echo out && echo err>&2 && exit 1"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 1 assert process.stdout == b"out \r\n" assert process.stderr == b"err \r\n"
def test_winrs(self, functional_transports): for wsman in functional_transports: with wsman, WinRS(wsman) as shell: process = Process(shell, "echo", ["hi"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"hi\r\n" assert process.stderr == b""
def test_winrs_send(self, wsman_conn): with WinRS(wsman_conn) as shell: process = Process(shell, "powershell.exe", ["-"]) process.begin_invoke() process.send(b"Write-Host \"output 1\";", end=False) process.send(b"Write-Host \"output 2\";") process.end_invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"output 1\noutput 2\n" assert process.stderr == b""
def test_winrs_operation_timeout(self, wsman_conn): wsman_conn.operation_timeout = 10 with WinRS(wsman_conn) as shell: process = Process( shell, "powershell.exe", ["Write-Host hi; Start-Sleep 30; Write-Host hi again"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"hi\nhi again\n" assert process.stderr == b""
def test_winrs_extra_opts(self, wsman_conn): with WinRS(wsman_conn, name="shell 1", lifetime=60, idle_time_out=60, working_directory="C:\\Windows") as shell: assert shell.name == "shell 1" assert shell.lifetime == 60 assert shell.idle_time_out == "PT60.000S" assert shell.working_directory == "C:\\Windows" process = Process(shell, "powershell.exe", ["(pwd).Path"]) process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"C:\\Windows\r\n" assert process.stderr == b""
def test_winrs_environment(self, wsman_conn): complex_chars = r'_-(){}[]<>*+-/\?"' '!@#$^&|;:i,.`~0' env_block = OrderedDict([ ('env1', 'var1'), (1234, 5678), (complex_chars, complex_chars), ]) with WinRS(wsman_conn, environment=env_block) as shell: process = Process(shell, "cmd.exe", ["/c", "set"]) process.invoke() process.signal(SignalCode.CTRL_C) env_list = process.stdout.decode('utf-8').splitlines() assert process.rc == 0 assert "env1=var1" in env_list assert "1234=5678" in env_list assert "%s=%s" % (complex_chars, complex_chars) in env_list assert process.stderr == b""
def test_winrs_no_cmd_shell(self, wsman_conn): with WinRS(wsman_conn) as shell: process = Process(shell, "powershell.exe", ["Write-Host", "hi"], no_shell=True) # this will fail as you need to provide the full path when not # running in cmd shell with pytest.raises(WSManFaultError) as exc: process.invoke() assert exc.value.provider_fault == "The system cannot find the file specified." assert exc.value.code == 2147942402 # fix the execute path and invoke again process.executable = r"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" process.invoke() process.signal(SignalCode.CTRL_C) assert process.rc == 0 assert process.stdout == b"hi\n" assert process.stderr == b""
def arg_check(): if len(sys.argv) < 2: print('Warning: Need to provide ip for windows instance.') sys.exit(1) if __name__ == '__main__': arg_check() server = sys.argv[1] ps = sys.argv[2] # creates a http connection with no encryption and basic auth wsman = WSMan(server, ssl=False, auth="basic", encryption="never", username="******", password="******") with WinRS(wsman) as shell: # execute a process with arguments in the background process = Process(shell, ps) process.begin_invoke() # start the invocation and return immediately process.poll_invoke() # update the output stream process.end_invoke() # finally wait until the process is finished process.signal(SignalCode.CTRL_C) print('stdout', process.stdout) print('stderr', process.stderr) print('rc', process.rc)