【问题标题】:Invoking a PowerShell script from Python从 Python 调用 PowerShell 脚本
【发布时间】:2011-10-17 15:04:33
【问题描述】:

我正在尝试从 python 启动一个 PowerShell 脚本,如下所示:

psxmlgen = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
                             './buildxml.ps1',
                             arg1, arg2, arg3], cwd=os.getcwd())
result = psxmlgen.wait()

问题是我收到以下错误:

文件 C:\Users\sztomi\workspace\myproject\buildxml.ps1 无法加载,因为在此禁用了脚本的执行 系统。有关详细信息,请参阅“get-help about_signing”。

尽管事实上我很久以前确实通过在管理员运行的 PS 终端中键入 Set-ExecutionPolicy Unrestriced 来启用在 Powershell 中运行脚本(为了确保再次这样做)。 powershell 可执行文件与开始菜单中的快捷方式指向的相同。 Get-ExecutionPolicy 正确报告 Unrestricted 无论我是否以管理员身份运行 PowerShell。

如何从 Python 中正确执行 PS 脚本?

【问题讨论】:

    标签: python powershell


    【解决方案1】:

    首先,Set-ExecutionPolicy Unrestriced 是基于每个用户和每个位的(32 位不同于 64 位)。

    其次,您可以从命令行覆盖执行策略。

    psxmlgen = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
                                 '-ExecutionPolicy',
                                 'Unrestricted',
                                 './buildxml.ps1',
                                 arg1, arg2, arg3], cwd=os.getcwd())
    result = psxmlgen.wait()
    

    显然,您可以使用此路径从 32 位 PowerShell 访问 64 位 PowerShell(感谢 cmets 中的@eryksun):

    powershell64 = os.path.join(os.environ['SystemRoot'], 
        'SysNative' if platform.architecture()[0] == '32bit' else 'System32',
        'WindowsPowerShell', 'v1.0', 'powershell.exe')
    

    【讨论】:

    • 哇,太好了,谢谢!实际上,我只是发现问题出在 Windows 7 x64 臭名昭著的文件系统重定向。 (我在 x64 版本中有 Unrestricted 策略,但在 x86 中没有,python 没有重定向到它)。
    • 我不完全确定如何使用子进程调用这样的可执行文件,但只是为了澄清一下,'./buildxml.ps1' 是被调用的实际命令吗?
    • @someone-or-other buildxml.ps1 是一个 powershell 脚本文件,可执行文件(如果这是你的意思是命令)是'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe'。以下列表中的所有项目都是传递给此可执行文件的参数。
    • 所以如果你想调用“ls”(这是一个例子,可以用“dir”来完成)你可以把它放在一个arg变量中?
    • 使用虚拟“SysNative”目录从 32 位 WOW64 程序运行本机 64 位系统可执行文件。另外,不要对系统根目录“C:\Windows”进行硬编码;这并不总是安装 Windows 的地方。我会使用powershell64 = os.path.join(os.environ['SystemRoot'], 'SysNative' if platform.architecture()[0] == '32bit' else 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe')
    【解决方案2】:

    对于我们这些想知道如何在将 arg1、arg2 和 arg3 的值传递给 powershell 后显示的人,您需要做的就是:

    Write-Host $args[0]
    Write-Host $args[1]
    Write-Host $args[2]
    

    【讨论】:

      猜你喜欢
      • 2015-07-07
      • 2016-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      相关资源
      最近更新 更多