0
# Response Objects
1
2
Response containers that encapsulate command execution results including output streams and exit codes. Response objects provide a standardized interface for accessing command results from both Session and Protocol operations.
3
4
## Capabilities
5
6
### Response Structure
7
8
Container for command execution results with decoded output streams and status information.
9
10
```python { .api }
11
class Response:
12
std_out: bytes
13
std_err: bytes
14
status_code: int
15
16
def __init__(self, args: tuple[bytes, bytes, int]) -> None:
17
"""
18
Initialize Response with command execution results.
19
20
Parameters:
21
- args: tuple of (stdout, stderr, status_code)
22
- stdout: command standard output as bytes
23
- stderr: command standard error as bytes
24
- status_code: command exit code (0 for success, non-zero for error)
25
"""
26
27
def __repr__(self) -> str:
28
"""
29
String representation showing status code and truncated output.
30
31
Returns:
32
Formatted string with response details for debugging
33
"""
34
```
35
36
### Response Attributes
37
38
Direct access to command execution results for processing and analysis.
39
40
**Standard Output (`std_out`)**
41
- Raw bytes from command's stdout stream
42
- Contains primary command output and results
43
- Decode with appropriate encoding (typically 'utf-8' or 'cp1252')
44
45
**Standard Error (`std_err`)**
46
- Raw bytes from command's stderr stream
47
- Contains error messages and diagnostic information
48
- For PowerShell scripts, CLIXML errors are automatically cleaned by Session
49
50
**Status Code (`status_code`)**
51
- Integer exit code from command execution
52
- 0 indicates successful completion
53
- Non-zero values indicate error conditions
54
- Matches standard Windows/DOS exit codes
55
56
## Usage Examples
57
58
### Basic Response Processing
59
60
```python
61
import winrm
62
63
s = winrm.Session('windows-host', auth=('user', 'password'))
64
65
# Execute command and process response
66
r = s.run_cmd('ipconfig', ['/all'])
67
68
# Check execution success
69
if r.status_code == 0:
70
output = r.std_out.decode('utf-8')
71
print("Network configuration:")
72
print(output)
73
else:
74
error = r.std_err.decode('utf-8')
75
print(f"Command failed with code {r.status_code}: {error}")
76
77
# Response representation
78
print(repr(r)) # <Response code 0, out b'Windows IP Configuration...', err b''>
79
```
80
81
### PowerShell Response Processing
82
83
```python
84
# PowerShell script with structured output
85
ps_script = """
86
Get-Service | Where-Object {$_.Status -eq 'Running'} |
87
Select-Object Name, Status, StartType |
88
ConvertTo-Json -Depth 2
89
"""
90
91
r = s.run_ps(ps_script)
92
93
if r.status_code == 0:
94
import json
95
services = json.loads(r.std_out.decode('utf-8'))
96
print(f"Found {len(services)} running services")
97
for service in services[:5]: # Show first 5
98
print(f"- {service['Name']}: {service['Status']}")
99
else:
100
# PowerShell errors are cleaned by Session.run_ps()
101
print("PowerShell error:", r.std_err.decode('utf-8'))
102
```
103
104
### Error Handling Patterns
105
106
```python
107
def execute_with_retry(session, command, args=None, max_retries=3):
108
"""Execute command with retry logic based on response status."""
109
args = args or []
110
111
for attempt in range(max_retries):
112
r = session.run_cmd(command, args)
113
114
if r.status_code == 0:
115
return r.std_out.decode('utf-8')
116
117
print(f"Attempt {attempt + 1} failed (code {r.status_code})")
118
if attempt < max_retries - 1:
119
time.sleep(2 ** attempt) # Exponential backoff
120
121
# Final failure
122
error_msg = r.std_err.decode('utf-8') if r.std_err else "Unknown error"
123
raise Exception(f"Command failed after {max_retries} attempts: {error_msg}")
124
125
# Usage
126
try:
127
result = execute_with_retry(s, 'net', ['user', 'testuser'])
128
print("User info:", result)
129
except Exception as e:
130
print("Command execution failed:", e)
131
```
132
133
### Binary Output Handling
134
135
```python
136
# Command that produces binary output
137
r = s.run_cmd('type', ['C:\\Windows\\System32\\calc.exe'])
138
139
if r.status_code == 0:
140
# Handle binary data
141
binary_data = r.std_out
142
print(f"Binary file size: {len(binary_data)} bytes")
143
144
# Save to file
145
with open('downloaded_calc.exe', 'wb') as f:
146
f.write(binary_data)
147
else:
148
print("Failed to read binary file")
149
```
150
151
### Text Encoding Considerations
152
153
```python
154
# Handle different text encodings
155
r = s.run_cmd('chcp') # Check current code page
156
157
if r.status_code == 0:
158
# Windows often uses CP1252 or other code pages
159
try:
160
output = r.std_out.decode('utf-8')
161
except UnicodeDecodeError:
162
# Fallback to common Windows encoding
163
output = r.std_out.decode('cp1252', errors='replace')
164
165
print("Code page info:", output.strip())
166
167
# Force UTF-8 output in PowerShell
168
ps_script = """
169
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
170
Get-Date -Format "yyyy-MM-dd HH:mm:ss"
171
"""
172
173
r = s.run_ps(ps_script)
174
if r.status_code == 0:
175
timestamp = r.std_out.decode('utf-8').strip()
176
print(f"Server time: {timestamp}")
177
```
178
179
## Response Analysis Utilities
180
181
```python
182
def analyze_response(response):
183
"""Analyze response object and provide summary information."""
184
analysis = {
185
'success': response.status_code == 0,
186
'status_code': response.status_code,
187
'stdout_size': len(response.std_out),
188
'stderr_size': len(response.std_err),
189
'has_output': len(response.std_out) > 0,
190
'has_errors': len(response.std_err) > 0
191
}
192
193
# Try to decode output for content analysis
194
try:
195
stdout_text = response.std_out.decode('utf-8')
196
analysis['stdout_lines'] = len(stdout_text.splitlines())
197
analysis['stdout_preview'] = stdout_text[:100] + '...' if len(stdout_text) > 100 else stdout_text
198
except UnicodeDecodeError:
199
analysis['stdout_encoding'] = 'binary_or_unknown'
200
201
try:
202
stderr_text = response.std_err.decode('utf-8')
203
analysis['stderr_lines'] = len(stderr_text.splitlines())
204
analysis['stderr_preview'] = stderr_text[:100] + '...' if len(stderr_text) > 100 else stderr_text
205
except UnicodeDecodeError:
206
analysis['stderr_encoding'] = 'binary_or_unknown'
207
208
return analysis
209
210
# Usage
211
r = s.run_cmd('systeminfo')
212
analysis = analyze_response(r)
213
print(f"Command {'succeeded' if analysis['success'] else 'failed'}")
214
print(f"Output: {analysis['stdout_lines']} lines, {analysis['stdout_size']} bytes")
215
if analysis.get('stdout_preview'):
216
print(f"Preview: {analysis['stdout_preview']}")
217
```