如果从python运行,某些powershell cmdlet不可用?

2024-06-30 15:34:33 发布

您现在位置:Python中文网/ 问答频道 /正文

所以这是一个不寻常的例子,也许我只是错过了一个显而易见的东西,但是我有下面的python代码来创建一个powershell脚本并运行它。在

# Create the PowerShell file 
f = open("getKey.ps1", "w")

f.write('$c = Get-BitlockerVolume -MountPoint C:\n')
f.write('$c.KeyProtector[1].RecoveryPassword | Out-File C:\\Temp\\recovery.key\n')

# Invoke Script
startPS = subprocess.Popen([r'C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe',
                                           '-ExecutionPolicy', 'Unrestricted', './getKey.ps1'], cwd=os.getcwd())

result = startPS.wait()

运行时,会出现以下错误:

^{pr2}$

但是,如果我随后手动运行生成的脚本,它会完美地工作。更奇怪的是,如果我运行与上面完全相同的命令,即:

C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted ./getKey.ps1

它也和预期的完全一样。在

显然,上面的错误是powershell错误,因此它成功地运行了脚本。powershell似乎知道这是从python运行的,当脚本从特定源运行时,它有一些受限的命令库。我承认这个想法没有实际意义,但事情确实是这样的。在

我不认为这是一个权限问题,因为当你从一个不相关的powershell提示符运行同一个命令时,你会得到一个Access is denied类型的错误,而不是命令不存在之类的错误。在

无论如何,任何帮助都将不胜感激!在

  • 编辑

编辑:新的证据有助于弄清这一点:

这肯定是cmdlet是否正确加载的问题。如果我以编程方式运行一个脚本,将所有可用命令的列表转储到一个文本文件中,那么它的大小只相当于直接通过powershell提示符执行此操作的2/3


Tags: 命令脚本windows错误exewrite提示符powershell
3条回答

这里的解决方案:Run a powershell script from python that uses Web-Administration module为我提供了所需的cmdlet,但是即使使用此方法,仍然缺少cmdlet。我仍然不知道为什么有些是加载的,而另一些没有加载,但目前,我的脚本做了我需要它做的,我不能花更多的时间去弄清楚它。在

这里是我用过的代码作为参考

startPS = subprocess.Popen([r'C:\Windows\sysnative\cmd.exe', '/c', 'powershell',
    '-ExecutionPolicy', 'Unrestricted', './getKey.ps1'], cwd=os.getcwd())

我敢打赌Python在64位Windows上以32位进程的形式运行。在本例中,您将最终运行32位PowerShell,这在实践中是一件坏事,因为许多PowerShell模块依赖于本机二进制文件,而本机二进制文件可能没有32位等价物。我用IIS管理器commandlets实现了这一点——commandlet本身注册在32位PowerShell中,但它们所依赖的底层COM对象没有注册。在

如果需要从32位进程运行64位PowerShell,请将路径指定为%SystemRoot%\SysNative\WindowsPowerShell\v1.0\PowerShell.exe而不是System32。在

System32实际上是针对32位进程虚拟化的,它引用了%SystemRoot%\SysWow64中的32位二进制文件。这就是为什么您的路径(和PSMODULEPATH)看起来相同,但不是(SysNative也是一个虚拟化路径,只存在于虚拟化的32位进程中)

除了@jbsmith在评论中所说的,还要检查确保在python启动进程时PowerShell所依赖的环境变量知道它的模块在哪里被正确填充。在

%PSMODULEPATH%是所讨论的环境变量,其工作方式与%PATH%变量的工作方式相同,多个目录由;分隔。根据您所说的观察到的行为,您似乎在使用PowerShell 3.0,并且cmdlet自动加载已生效。在

相关问题 更多 >