A stateful PowerShell runspace backed by the .NET PowerShell SDK (``System.Management.Automation``), loaded via ``pythonnet``. Unlike :func:`run_dict`, which shells out to a ``powershell.exe`` subprocess, this class opens an **in-process** runspace and keeps it alive across mul
| 79 | |
| 80 | |
| 81 | class PowerShellSession: |
| 82 | """ |
| 83 | A stateful PowerShell runspace backed by the .NET PowerShell SDK |
| 84 | (``System.Management.Automation``), loaded via ``pythonnet``. |
| 85 | |
| 86 | Unlike :func:`run_dict`, which shells out to a ``powershell.exe`` |
| 87 | subprocess, this class opens an **in-process** runspace and keeps it alive |
| 88 | across multiple calls. The same runspace is reused for every ``run*`` |
| 89 | invocation, so imported modules, loaded functions, and session variables |
| 90 | persist for the lifetime of the object. |
| 91 | |
| 92 | **Requirements:** both :data:`HAS_CLR` and :data:`HAS_PWSH_SDK` must be |
| 93 | ``True`` before instantiating this class. |
| 94 | |
| 95 | **Usage — always use as a context manager** so the underlying runspace is |
| 96 | disposed of deterministically:: |
| 97 | |
| 98 | with PowerShellSession() as session: |
| 99 | result = session.run_json("Get-NetAdapter | Select-Object Name, Status") |
| 100 | |
| 101 | **Methods:** |
| 102 | |
| 103 | * :meth:`run` — run a script and return raw Python scalars/lists. |
| 104 | * :meth:`run_json` — run a script and return a parsed Python object via |
| 105 | ``ConvertTo-Json``. |
| 106 | * :meth:`run_strict` — like :meth:`run` but raises |
| 107 | :exc:`~salt.exceptions.CommandExecutionError` if the script did not run |
| 108 | to completion (i.e., an uncaught error occurred). |
| 109 | |
| 110 | **Session defaults** set in :meth:`__init__`: |
| 111 | |
| 112 | * ``$ErrorActionPreference = 'Stop'`` — all non-terminating cmdlet errors |
| 113 | are promoted to terminating exceptions so they cannot be silently ignored. |
| 114 | * ``$ProgressPreference = 'SilentlyContinue'`` — suppresses progress bars |
| 115 | that would otherwise pollute the output stream. |
| 116 | * ``$WarningPreference = 'SilentlyContinue'`` — suppresses advisory |
| 117 | warnings that are not actionable in an automation context. |
| 118 | """ |
| 119 | |
| 120 | def __init__(self): |
| 121 | """ |
| 122 | Create the PowerShell runspace and apply session-wide preferences. |
| 123 | |
| 124 | Sets ``$ErrorActionPreference = 'Stop'`` so every cmdlet uses |
| 125 | terminating-error semantics by default. Individual commands that are |
| 126 | expected to return nothing (e.g., ``Get-NetRoute`` when no route |
| 127 | exists) must use ``-ErrorAction SilentlyContinue`` or be wrapped in a |
| 128 | PowerShell ``try/catch`` block. |
| 129 | """ |
| 130 | # Create PowerShell instance |
| 131 | self.ps = PowerShell.Create() |
| 132 | |
| 133 | # Suppress anything that might be displayed |
| 134 | self.ps.AddScript("$ProgressPreference = 'SilentlyContinue'").AddStatement() |
| 135 | self.ps.AddScript("$ErrorActionPreference = 'Stop'").AddStatement() |
| 136 | self.ps.AddScript("$WarningPreference = 'SilentlyContinue'").AddStatement() |
| 137 | self.ps.Invoke() |
| 138 |