Python subprocess调用PowerShell脚本失败,但命令行可正常执行
Hey there! Let's figure out why your PowerShell script runs fine directly in the command line but fails when executed via Python's subprocess.check_output. I’ve dealt with this exact scenario before, so here are the most common culprits and fixes:
Architecture Mismatch (32-bit vs 64-bit)
You’re calling the 32-bit PowerShell version located atC:\Windows\SysWOW64\..., but if your third-party module is built for 64-bit systems, it won’t load in a 32-bit shell. When you run PowerShell manually, you’re probably using the default 64-bit version (found atC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe).Fix: Switch to the 64-bit PowerShell path in your Python code:
from subprocess import check_output, STDOUT, CalledProcessError # Use 64-bit PowerShell cmd = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -nologo -file c:\\test.ps1' try: cmd_output = check_output(cmd, stderr=STDOUT, shell=True, text=True) print("Success output:\n", cmd_output) except CalledProcessError as e: print(f"Exit code: {e.returncode}\nError output:\n{e.output}")Execution Policy Restrictions
Python’s subprocess might be running under a stricter execution policy than your interactive command line. Even if you’ve set a permissive policy for your user, the system-wide or process-level policy could block the script.Fix: Add
-ExecutionPolicy Bypassto your PowerShell command to temporarily override the policy:cmd = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -nologo -ExecutionPolicy Bypass -file c:\\test.ps1'Missing Environment Variables
Third-party modules often rely on specific environment variables (likePATHentries pointing to their installation directory). Python’s subprocess inherits a stripped-down environment compared to your interactive command prompt, so the module might not be found.Fix 1: Explicitly import the module with its full path in your PowerShell script:
# At the top of test.ps1 Import-Module -Name "C:\Full\Path\To\Your\ThirdPartyModule.psd1" -ForceFix 2: Pass your full user environment to the subprocess in Python:
import os from subprocess import check_output, STDOUT, CalledProcessError env = os.environ.copy() # Add the module's directory to PATH if needed env['PATH'] += ';C:\\Path\\To\\Module\\Directory' cmd = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -nologo -file c:\\test.ps1' try: cmd_output = check_output(cmd, stderr=STDOUT, shell=True, env=env, text=True) print(cmd_output) except CalledProcessError as e: print(f"Error details: {e.output}")Working Directory Discrepancies
If your PowerShell script uses relative paths to load modules or access files, the subprocess’s working directory (which defaults to Python’s current working directory) might not match what your command prompt uses.Fix: Specify the working directory where your script resides using the
cwdparameter:cmd_output = check_output(cmd, stderr=STDOUT, shell=True, cwd='c:\\', text=True)
内容的提问来源于stack exchange,提问作者john johnson

