CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pywinrm

Python library for Windows Remote Management (WinRM) service enabling remote command execution and PowerShell scripts on Windows machines.

Pending
Overview
Eval results
Files

response.mddocs/

Response Objects

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.

Capabilities

Response Structure

Container for command execution results with decoded output streams and status information.

class Response:
    std_out: bytes
    std_err: bytes
    status_code: int
    
    def __init__(self, args: tuple[bytes, bytes, int]) -> None:
        """
        Initialize Response with command execution results.
        
        Parameters:
        - args: tuple of (stdout, stderr, status_code)
          - stdout: command standard output as bytes
          - stderr: command standard error as bytes  
          - status_code: command exit code (0 for success, non-zero for error)
        """
    
    def __repr__(self) -> str:
        """
        String representation showing status code and truncated output.
        
        Returns:
        Formatted string with response details for debugging
        """

Response Attributes

Direct access to command execution results for processing and analysis.

Standard Output (std_out)

  • Raw bytes from command's stdout stream
  • Contains primary command output and results
  • Decode with appropriate encoding (typically 'utf-8' or 'cp1252')

Standard Error (std_err)

  • Raw bytes from command's stderr stream
  • Contains error messages and diagnostic information
  • For PowerShell scripts, CLIXML errors are automatically cleaned by Session

Status Code (status_code)

  • Integer exit code from command execution
  • 0 indicates successful completion
  • Non-zero values indicate error conditions
  • Matches standard Windows/DOS exit codes

Usage Examples

Basic Response Processing

import winrm

s = winrm.Session('windows-host', auth=('user', 'password'))

# Execute command and process response
r = s.run_cmd('ipconfig', ['/all'])

# Check execution success
if r.status_code == 0:
    output = r.std_out.decode('utf-8')
    print("Network configuration:")
    print(output)
else:
    error = r.std_err.decode('utf-8')
    print(f"Command failed with code {r.status_code}: {error}")

# Response representation
print(repr(r))  # <Response code 0, out b'Windows IP Configuration...', err b''>

PowerShell Response Processing

# PowerShell script with structured output
ps_script = """
Get-Service | Where-Object {$_.Status -eq 'Running'} |
Select-Object Name, Status, StartType |
ConvertTo-Json -Depth 2
"""

r = s.run_ps(ps_script)

if r.status_code == 0:
    import json
    services = json.loads(r.std_out.decode('utf-8'))
    print(f"Found {len(services)} running services")
    for service in services[:5]:  # Show first 5
        print(f"- {service['Name']}: {service['Status']}")
else:
    # PowerShell errors are cleaned by Session.run_ps()
    print("PowerShell error:", r.std_err.decode('utf-8'))

Error Handling Patterns

def execute_with_retry(session, command, args=None, max_retries=3):
    """Execute command with retry logic based on response status."""
    args = args or []
    
    for attempt in range(max_retries):
        r = session.run_cmd(command, args)
        
        if r.status_code == 0:
            return r.std_out.decode('utf-8')
        
        print(f"Attempt {attempt + 1} failed (code {r.status_code})")
        if attempt < max_retries - 1:
            time.sleep(2 ** attempt)  # Exponential backoff
    
    # Final failure
    error_msg = r.std_err.decode('utf-8') if r.std_err else "Unknown error"
    raise Exception(f"Command failed after {max_retries} attempts: {error_msg}")

# Usage
try:
    result = execute_with_retry(s, 'net', ['user', 'testuser'])
    print("User info:", result)
except Exception as e:
    print("Command execution failed:", e)

Binary Output Handling

# Command that produces binary output
r = s.run_cmd('type', ['C:\\Windows\\System32\\calc.exe'])

if r.status_code == 0:
    # Handle binary data
    binary_data = r.std_out
    print(f"Binary file size: {len(binary_data)} bytes")
    
    # Save to file
    with open('downloaded_calc.exe', 'wb') as f:
        f.write(binary_data)
else:
    print("Failed to read binary file")

Text Encoding Considerations

# Handle different text encodings
r = s.run_cmd('chcp')  # Check current code page

if r.status_code == 0:
    # Windows often uses CP1252 or other code pages
    try:
        output = r.std_out.decode('utf-8')
    except UnicodeDecodeError:
        # Fallback to common Windows encoding
        output = r.std_out.decode('cp1252', errors='replace')
    
    print("Code page info:", output.strip())

# Force UTF-8 output in PowerShell
ps_script = """
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"""

r = s.run_ps(ps_script)
if r.status_code == 0:
    timestamp = r.std_out.decode('utf-8').strip()
    print(f"Server time: {timestamp}")

Response Analysis Utilities

def analyze_response(response):
    """Analyze response object and provide summary information."""
    analysis = {
        'success': response.status_code == 0,
        'status_code': response.status_code,
        'stdout_size': len(response.std_out),
        'stderr_size': len(response.std_err),
        'has_output': len(response.std_out) > 0,
        'has_errors': len(response.std_err) > 0
    }
    
    # Try to decode output for content analysis
    try:
        stdout_text = response.std_out.decode('utf-8')
        analysis['stdout_lines'] = len(stdout_text.splitlines())
        analysis['stdout_preview'] = stdout_text[:100] + '...' if len(stdout_text) > 100 else stdout_text
    except UnicodeDecodeError:
        analysis['stdout_encoding'] = 'binary_or_unknown'
    
    try:
        stderr_text = response.std_err.decode('utf-8')
        analysis['stderr_lines'] = len(stderr_text.splitlines())
        analysis['stderr_preview'] = stderr_text[:100] + '...' if len(stderr_text) > 100 else stderr_text
    except UnicodeDecodeError:
        analysis['stderr_encoding'] = 'binary_or_unknown'
    
    return analysis

# Usage
r = s.run_cmd('systeminfo')
analysis = analyze_response(r)
print(f"Command {'succeeded' if analysis['success'] else 'failed'}")
print(f"Output: {analysis['stdout_lines']} lines, {analysis['stdout_size']} bytes")
if analysis.get('stdout_preview'):
    print(f"Preview: {analysis['stdout_preview']}")

Install with Tessl CLI

npx tessl i tessl/pypi-pywinrm

docs

auth-security.md

exceptions.md

index.md

protocol.md

response.md

session.md

tile.json