所以这是一个不寻常的,也许我只是错过了显而易见的,但我有以下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()
当它运行时,它给我以下错误:
The term 'Get-BitlockerVolume' is not recognized as the name of a cmdlet, function, script file, or operable program.
但是,如果我然后手动运行生成的脚本,它将完美地运行。为了增加奇怪性,如果我完全按照上面那样运行相同的命令,即:
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted ./getKey.ps1
它也完全按预期工作。
显然,上述错误是一个PowerShell错误,因此它成功运行了脚本。看起来好像PowerShell以某种方式知道这是从python运行的,并且当从特定源运行脚本时,它具有一些受限制的命令库。我认为这个想法没有任何意义,但它肯定是出现的。
我不认为这是一个权限问题,因为当你从一个无法升级的PowerShell提示符运行相同的命令时,会得到一个Access被拒绝的类型错误,而不是一个命令不存在的那种错误。
无论如何,任何帮助将不胜感激!
编辑:新证据帮助解决这个问题:
这绝对是正确加载cmdlet的问题。如果我以编程方式运行脚本以将所有可用命令的列表转储到文本文件中,那么它只有大约2/3的大小,就像我直接通过powershell提示一样
我敢打赌Python在64位Windows上作为32位进程运行。在这种情况下,您最终将运行32位PowerShell,这实际上是一件坏事,因为许多PowerShell模块依赖于可能没有32位等效的本机二进制文件。我使用IIS管理器命令行开关 - 命令行程序本身在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自动加载已生效。
这里的解决方案: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())
我有同样的问题,只是没有安装BitLocker功能,因此模块不存在。
我通过安装Bitlocker功能修复了它:
Windows Server:
Install-WindowsFeature BitLocker -IncludeAllSubFeature -IncludeManagementTools -Restart
Windows桌面:
Enable-WindowsOptionalFeature -Online -FeatureName BitLocker -All