{"id":9234,"library":"pypsexec","title":"Run commands on a remote Windows host using SMB/RPC","description":"pypsexec is a Python library that enables running commands on a remote Windows host via SMB/RPC, similar to the popular PsExec tool. It achieves this by deploying and using a bundled PAExec executable on the remote target. The library is currently at version 0.3.0, with the last major release in October 2021, suggesting a maintenance release cadence.","status":"maintenance","version":"0.3.0","language":"en","source_language":"en","source_url":"https://github.com/jborean93/pypsexec","tags":["windows","remote execution","smb","rpc","psexec"],"install":[{"cmd":"pip install pypsexec","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core dependency for SMB/RPC communication. Requires Python 3.9+ for `smbprotocol` itself.","package":"smbprotocol"},{"reason":"Optional, for Kerberos authentication on Linux systems.","package":"python-gssapi","optional":true},{"reason":"Optional, for Kerberos authentication on Linux systems.","package":"pykrb5","optional":true}],"imports":[{"symbol":"Client","correct":"from pypsexec.client import Client"}],"quickstart":{"code":"import os\nfrom pypsexec.client import Client\n\nhostname = os.environ.get('PSEXEC_HOST', 'your_windows_host')\nusername = os.environ.get('PSEXEC_USERNAME', 'your_username')\npassword = os.environ.get('PSEXEC_PASSWORD', 'your_password')\n\nif not all([hostname, username, password]):\n    print(\"Please set PSEXEC_HOST, PSEXEC_USERNAME, PSEXEC_PASSWORD environment variables.\")\n    exit(1)\n\nc = Client(hostname, username=username, password=password, encrypt=True)\ntry:\n    c.connect()\n    c.create_service()\n    # Run 'whoami.exe /all' command\n    stdout, stderr, rc = c.run_executable('whoami.exe', arguments='/all')\n\n    print(f\"STDOUT:\\n{stdout.decode('utf-8') if stdout else ''}\")\n    print(f\"STDERR:\\n{stderr.decode('utf-8') if stderr else ''}\")\n    print(f\"Return Code: {rc}\")\nfinally:\n    c.remove_service()\n    c.disconnect()\n","lang":"python","description":"This example connects to a remote Windows host, creates a temporary service to execute a command ('whoami.exe /all'), captures its output, and then cleans up the service and connection. Credentials are pulled from environment variables."},"warnings":[{"fix":"For 32-bit process execution, add `wow64=True` to `run_executable()`: `c.run_executable('cmd.exe', arguments='/c echo Hello', wow64=True)`","message":"Starting from v0.2.0, processes are run as the native architecture's bitness (e.g., 64-bit on a 64-bit OS) by default. Previously, it always ran as a 32-bit process. Applications relying on 32-bit paths must set `wow64=True` in `run_executable()` to restore the old behavior.","severity":"breaking","affected_versions":">=0.2.0"},{"fix":"Upgrade your Python environment to 3.9 or newer.","message":"Version 0.3.0 dropped support for Python 2.7 and 3.5. The new minimum Python version is 3.6. However, its core dependency, `smbprotocol`, now explicitly requires Python 3.9+ for full functionality.","severity":"breaking","affected_versions":">=0.3.0"},{"fix":"When connecting to older Windows versions, initialize the client with `encrypt=False`: `c = Client('hostname', ..., encrypt=False)`","message":"SMB encryption (`encrypt=True`) is only supported on Windows versions with SMB 3.x.x+ (e.g., Windows 8 / Server 2012 and newer). For older systems like Windows 7, Server 2008, or Server 2008 R2, `encrypt` must be set to `False` to avoid connection issues.","severity":"gotcha","affected_versions":"<0.3.0 (default behaviour affected newer versions)"},{"fix":"Avoid `asynchronous=True` or `interactive=True` if you need to capture standard output or error streams.","message":"When running commands asynchronously (`asynchronous=True`) or interactively (`interactive=True`), `pypsexec` does not return `stdout` or `stderr`. These will always be `None` in the returned tuple.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure the remote user has administrative privileges and ADMIN$ share access. Check UAC settings on the remote host if encountering authentication or permission errors.","message":"The remote Windows host requires SMB to be running, the `ADMIN$` share to be enabled with read/write access, and the connecting user must be an administrator on the host. UAC filtering of logon tokens can prevent connections.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure `python.exe` is a standard installation and its path is accessible to the remote user. You might need to specify the full path to `python.exe` or adjust the remote system's PATH environment variable.","cause":"The Python executable might be from the Windows Store ('WindowsApps' directory) or another location with restricted permissions, or the user's PATH environment variable is not correctly configured for remote execution.","error":"Access Denied when trying to run python.exe -c \"command\""},{"fix":"Do not set `asynchronous=True` or `interactive=True` if you require `stdout` and `stderr` output. For long-running tasks where output is needed, you might need a different approach (e.g., redirecting output to a file and fetching it via SMB).","cause":"You are likely running the command with `asynchronous=True` or `interactive=True`, which explicitly suppresses stdout/stderr capture in `pypsexec`.","error":"Cannot get stdout/stderr for long-running commands, output is None."},{"fix":"To launch GUI applications, you need to use `interactive=True` and potentially specify an `interactive_session` ID. This is complex as it requires an active user session and understanding of Windows session management.","cause":"By default, `pypsexec` runs processes in a non-interactive session (session 0). GUI applications typically require an interactive user session to display.","error":"GUI applications (e.g., notepad.exe) do not launch or are not visible on the remote desktop."},{"fix":"Always wrap your `pypsexec` operations in a `try...finally` block to ensure `c.remove_service()` and `c.disconnect()` are called, even if an error occurs.","cause":"In cases of critical errors or if cleanup functions are not explicitly called, the temporary PAExec service and binary might not be removed.","error":"PAExec binary or service remains on the remote host after execution."},{"fix":"This is often a false positive. You may need to create an exclusion for the PAExec binary on the remote host or consider compiling your own PAExec binary from source if permitted.","cause":"While `PAExec` (the underlying executable) is generally considered legitimate, some antivirus solutions might flag it due to its nature of remote execution, especially if its hash is known or if used in suspicious contexts.","error":"Windows Defender or other AV flags PAExec as malicious."}]}