def _run_cancelable(self, ps_code): """ :type ps_code: str """ self.logger.debug('PowerShellScript:' + ps_code) bat_code = 'powershell -encodedcommand %s' % base64.b64encode(ps_code.encode('utf_16_le')).decode('ascii') shell_id = self.session.protocol.open_shell() command_id = self.session.protocol.run_command(shell_id, bat_code) async_result = self.pool.apply_async(self.session.protocol.get_command_output, kwds={'shell_id': shell_id, 'command_id': command_id}) try: while not async_result.ready(): if self.cancel_sampler.is_cancelled(): self.cancel_sampler.throw() time.sleep(1) result = winrm.Response(async_result.get()) finally: self.session.protocol.cleanup_command(shell_id, command_id) self.session.protocol.close_shell(shell_id) self.logger.debug('ReturnedCode:' + str(result.status_code)) self.logger.debug('Stdout:' + result.std_out) self.logger.debug('Stderr:' + result.std_err) result.std_err = self._try_decode_error_xml(result.std_err) self.logger.debug('Stderr(Decoded):' + result.std_err) return result
def run_cmd(self, command, args=(), env=None): shell_id = self.protocol.open_shell(env_vars=env) command_id = self.protocol.run_command(shell_id, command, args) rs = winrm.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 test_cat_on_windows(self): env = JujuData("an-env", {"type": "nonlocal"}) client = ModelClient(env, None, None) unit = "a-application/0" with patch.object(client, "get_status", autospec=True) as st: st.return_value = Status.from_text(self.win2012hvr2_status_output) response = winrm.Response(("contents of /a/file", "", 0)) remote = remote_from_unit(client, unit) with patch.object(remote.session, "run_cmd", autospec=True, return_value=response) as mock_run: output = remote.cat("/a/file") self.assertEqual(output, "contents of /a/file") st.assert_called_once_with() mock_run.assert_called_once_with("type", ["/a/file"])
def _run_cmd(self, action_result, cmd, args=None, parse_callback=pc.basic, additional_data=None, async_=False, command_id=None, shell_id=None): # The parser callback should have the function signature (ActionResult, winrm.Result) -> bool # The additional_data is a dictionary which will be passed to the parser, in which case the signature should be # (ActionResult, winrm.Result, **kwargs) -> bool # async_ will start the command and return what you need to get the results later (command_id and shell_id) # you /could/ pass a command_id and shell_id from an async powershell script run here (and vice versa), # but there is some additional data # cleanup which goes on after running a powershell script which wont happen here, so its best not to if additional_data is None: additional_data = {} resp = None try: if command_id: if shell_id is None: return action_result.set_status( phantom.APP_ERROR, "Must specify shell_id with command_id") resp = winrm.Response( self._protocol.get_command_output(shell_id, command_id)) self._protocol.close_shell(shell_id) elif async_: shell_id = self._protocol.open_shell() command_id = self._protocol.run_command(shell_id, cmd, args) summary = action_result.set_summary({}) summary['shell_id'] = shell_id summary['command_id'] = command_id return phantom.APP_SUCCESS else: resp = self._session.run_cmd(cmd, args) except Exception as e: return action_result.set_status( phantom.APP_ERROR, "Error running command: {}".format(str(e))) if resp is None: # The exception will probably catch this self.debug_print("Error: _run_cmd is missing parameters") return action_result.set_status( phantom.APP_ERROR, "Unknown error while running command") return parse_callback(action_result, resp, **additional_data)
def _run_ps(self, action_result, script, parse_callback=pc.basic, additional_data=None, async_=False, command_id=None, shell_id=None): if additional_data is None: additional_data = {} resp = None try: if command_id: if shell_id is None: return action_result.set_status( phantom.APP_ERROR, "Must specify shell_id with command_id") resp = winrm.Response( self._protocol.get_command_output(shell_id, command_id)) self._protocol.close_shell(shell_id) if len(resp.std_err): resp.std_err = self._session._clean_error_msg(resp.std_err) elif async_: encoded_ps = b64encode( script.encode('utf_16_le')).decode('ascii') shell_id = self._protocol.open_shell() command_id = self._protocol.run_command( shell_id, 'powershell -encodedcommand {0}'.format(encoded_ps)) summary = action_result.set_summary({}) summary['shell_id'] = shell_id summary['command_id'] = command_id return phantom.APP_SUCCESS else: resp = self._session.run_ps(script) except Exception as e: return action_result.set_status( phantom.APP_ERROR, "Error running PowerShell script: {}".format(str(e))) if resp is None: self.debug_print("Error: _run_ps is missing parameters") return action_result.set_status( phantom.APP_ERROR, "Unknown error while running PowerShell script") return parse_callback(action_result, resp, **additional_data)
def test_run_cmd(self): env = JujuData("an-env", {"type": "nonlocal"}) client = ModelClient(env, None, None) unit = "a-application/0" with patch.object(client, "get_status", autospec=True) as st: st.return_value = Status.from_text(self.win2012hvr2_status_output) response = winrm.Response(("some out", "some err", 0)) remote = remote_from_unit(client, unit) with patch.object(remote.session, "run_cmd", autospec=True, return_value=response) as mock_run: output = remote.run_cmd( ["C:\\Program Files\\bin.exe", "/IN", "Bob's Stuff"]) self.assertEqual(output, response) st.assert_called_once_with() mock_run.assert_called_once_with('"C:\\Program Files\\bin.exe"', ['/IN "Bob\'s Stuff"'])
def test_copy_on_windows(self): env = JujuData("an-env", {"type": "nonlocal"}) client = ModelClient(env, None, None) unit = "a-application/0" dest = "/local/path" with patch.object(client, "get_status", autospec=True) as st: st.return_value = Status.from_text(self.win2012hvr2_status_output) response = winrm.Response(("fake output", "", 0)) remote = remote_from_unit(client, unit) with patch.object(remote.session, "run_ps", autospec=True, return_value=response) as mock_run: with patch.object(remote, "_encoded_copy_to_dir", autospec=True) as mock_cpdir: remote.copy(dest, ["C:\\logs\\*", "%APPDATA%\\*.log"]) mock_cpdir.assert_called_once_with(dest, "fake output") st.assert_called_once_with() self.assertEquals(mock_run.call_count, 1) self.assertRegexpMatches(mock_run.call_args[0][0], r'.*"C:\\logs\\[*]","%APPDATA%\\[*].log".*')
def cmd(self, cmd, *args): command_id = self.protocol.run_command(self.shell_id, cmd, args) result = winrm.Response( self.protocol.get_command_output(self.shell_id, command_id)) self.protocol.cleanup_command(self.shell_id, command_id) return result