为什么powershell和python对同一个命令给出不同的结果?

为什么powershell和python对同一个命令给出不同的结果?,python,powershell,Python,Powershell,为什么要用Python编写此脚本 import subprocess, io p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path"], stdout=subprocess.PIPE) for line in io.TextIOWrapper(p.stdout, encoding="utf-8"): l

为什么要用Python编写此脚本

import subprocess, io
p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } |    Format-List Id,Name,Path"], stdout=subprocess.PIPE)
for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
    line = " ".join(line.split())
    print(line)

以及在Powershell中编写命令

Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path
有不同的结果吗? 例如,这是Powershell的一些结果:

Id   : 7692
Name : NVIDIA Share
Path : C:\Program Files\NVIDIA Corporation\NVIDIA GeForce Experience\NVIDIA Share.exe

Id   : 7232
Name : Origin
Path : C:\Program Files (x86)\Origin\Origin.exe
这与Python中的相同:

Id   : 7692
Name : NVIDIA Share
Path :

Id   : 7232
Name : Origin
Path : C:\Program Files (x86)\Origin\Origin.exe

有时,Python结果中的路径在Powershell中丢失。为什么会这样?有没有办法解决这个问题?

进程路径没有显示是缺乏提升访问的一个非常明显的迹象

即使您以管理员身份运行Python,子进程仍将失去其管理访问权限

您可以通过在Python内外运行以下检查来正确验证:

(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

进程路径未显示是缺乏提升访问的一个非常明确的指示

即使您以管理员身份运行Python,子进程仍将失去其管理访问权限

您可以通过在Python内外运行以下检查来正确验证:

(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
我认为,这是一个简单的海拔问题(通常90%的情况下都是这个问题)。所以,在盲目的系统管理员信任下,我决定测试它。让我们以管理员身份启动PowerShell,然后运行:

PS C:\> (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
True
嗯。好。我们有一个真正提升的PowerShell会话。让我们启动Python,一劳永逸地证明@Lolman不知道自己在做什么,并证明Python不知道如何启动适当的提升PowerShell会话:

PS C:\> python
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...
True
好极了!它会像预期的那样返回。。。嗯。。。啊哦<代码>真值。。。。。。。。好。。。嗯。。。坚果这是个好主意@洛曼确实知道如何尝试

嗯。这需要一些创造性的思考。让我们比较一下我得到的一些条目:

PowerShell

Python

那么,让我们来看看显示路径信息的进程与未显示路径信息的进程之间的差异。我看到很多
程序文件(x86)
,但没有
程序文件
。。。六羟甲基三聚氰胺六甲醚。。。这看起来是一个32位对64位的问题

为了证明这一点,我以管理员身份启动了32位的Windows PowerShell(x86),并运行了相同的命令:

Windows PowerShell(x86)

啊哈!它看起来确实像是32位对64位的问题。好啊那么,让我们来证明这一点。让我们下载64位Python并重试:

PS C:\> C:\Users\HAL9256\AppData\Local\Programs\Python\Python38\python.exe
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } |    Format-List Id,Name,Path"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...

Id   : 2660
Name : powershell
Path : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Id : 31200
Name : Code
Path : C:\Users\HAL9256\AppData\Local\Programs\Microsoft VS Code\Code.exe

Id : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...
对!!我们现在得到了所有的信息。PowerShell控制台以64位运行,因此可以查看完整路径和进程信息。Python默认为32位,因此无法查看64位进程的完整路径和进程信息。只有通过显式运行64位版本的Python(从提升的会话),我们才能看到所有的路径和进程信息。

我认为,这是一个简单的提升问题(通常90%的时间都是这个问题)。所以,在盲目的系统管理员信任下,我决定测试它。让我们以管理员身份启动PowerShell,然后运行:

PS C:\> (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
True
嗯。好。我们有一个真正提升的PowerShell会话。让我们启动Python,一劳永逸地证明@Lolman不知道自己在做什么,并证明Python不知道如何启动适当的提升PowerShell会话:

PS C:\> python
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...
True
好极了!它会像预期的那样返回。。。嗯。。。啊哦<代码>真值。。。。。。。。好。。。嗯。。。坚果这是个好主意@洛曼确实知道如何尝试

嗯。这需要一些创造性的思考。让我们比较一下我得到的一些条目:

PowerShell

Python

那么,让我们来看看显示路径信息的进程与未显示路径信息的进程之间的差异。我看到很多
程序文件(x86)
,但没有
程序文件
。。。六羟甲基三聚氰胺六甲醚。。。这看起来是一个32位对64位的问题

为了证明这一点,我以管理员身份启动了32位的Windows PowerShell(x86),并运行了相同的命令:

Windows PowerShell(x86)

啊哈!它看起来确实像是32位对64位的问题。好啊那么,让我们来证明这一点。让我们下载64位Python并重试:

PS C:\> C:\Users\HAL9256\AppData\Local\Programs\Python\Python38\python.exe
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } |    Format-List Id,Name,Path"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...

Id   : 2660
Name : powershell
Path : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Id : 31200
Name : Code
Path : C:\Users\HAL9256\AppData\Local\Programs\Microsoft VS Code\Code.exe

Id : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...

对!!我们现在得到了所有的信息。PowerShell控制台以64位运行,因此可以查看完整路径和进程信息。Python默认为32位,因此无法查看64位进程的完整路径和进程信息。只有通过显式运行64位版本的Python(从提升的会话),我们才能看到所有的路径和进程信息。

两个进程都提升了吗?两个进程都提升了。我的理解是,如果要运行多个进程并将结果从一个进程传递到下一个进程,必须将
shell=True
参数用于
Popen()
。由于您没有这样做,我甚至不知道您的命令是如何工作的。使用
shell=True
参数没有任何区别。两个x64进程都提升了吗?两个进程都提升了吗?两个进程都提升了。我的理解是,如果要运行多个进程并将结果从一个进程传递到下一个进程,必须将
shell=True
参数用于
Popen()
。由于您没有这样做,我不知道您的命令是如何工作的。使用
shell=True
参数没有任何区别。两个x64进程都是吗?现在这是一个完全令人信服的答案。使我的回答现在看起来像一个评论。我想把它留给上下文参考还是有点用处的。很好的侦查-投票结果良好。谢谢你给出的清晰而翔实的答案。老实说,我对我在那里做的事情不太了解。问题是运行32位Python。安装了64位版本并且运行正常。这是一个完全令人信服的答案。使我的回答现在看起来像一个评论。我想把它留给上下文参考还是有点用处的。很好的侦查-投票结果良好。谢谢你提供的清晰信息