为什么Get-ChildItem(或ls,或dir)在x86和x64 powershell控制台执行时返回不同的结果?

本文关键字:返回 执行 控制台 结果 powershell ls Get-ChildItem dir 为什么 x86 x64 | 更新日期: 2023-09-27 18:13:00

我在我的Windows Server机器上启动了x86版本的Powershell Console,并执行:

get-childitem C:'Windows'System32'WindowsPowerShell'v1.0'Modules'*s

,我得到以下列表:

CimCmdlets、DirectAccessClientComponents Kds、Microsoft.PowerShell.Diagnostics, NetQos, NetworkConnectivityStatus, PSDiagnostics, ScheduledTasks, TLS

然后我启动x64控制台并执行相同的命令,并获得更宽的DIRs列表:

常规, CimCmdlets, DirectAccessClientComponents, FailoverClusters , Kds、Microsoft.PowerShell.Diagnostics, NetQos, NetworkConnectivityStatus, NFS , PSDiagnostics, ScheduledTasks, SmbWitness , TLS

我检查了FailoverClusters模块文件的硬链接(我实际上试图导入):

PS C:'windows'system32'WindowsPowerShell'v1.0'Modules> fsutil hardlink list C:'Windows'System32'WindowsPowerShell'v1.0'Modules'FailoverClusters'failoverclusters.psd1

,得到如下结果:

' Windows ' System32系统' ' FailoverClusters ' FailoverClusters.psd1 WindowsPowerShell ' v1.0 '模块' Windows ' WinSxS ' amd64_microsoft-windows-f . . rcluster-powershell_31bf3856ad364e35_6.3.9600.17112_none_8555e001e29b71bc ' FailoverClusters.psd1

(注意:看起来目录本身没有链接,fsutil仍然只返回一个条目-与dirname相同)

所以问题是:为什么Get-ChildItem在x86和x64 powershell主机上工作不同?这到底是怎么回事?

是的,我知道FailoverClusters模块不工作在x86架构,但仍然…我打破了我的头试图找出错误在哪里(意外编译我的c#主机x86架构),因为它总是返回给我类似"模块未找到"或"文件未找到"....

为什么Get-ChildItem(或ls,或dir)在x86和x64 powershell控制台执行时返回不同的结果?

从我的回答:

在32位Windows操作系统下,系统文件夹为"C:'Windows'System32"。在64位的Windows操作系统下,64位的系统文件夹也是"C:'Windows'System32"。但是在64位Windows安装中,32位进程的系统文件夹实际上是C:'Windows'SysWOW64

为了兼容性,在64位操作系统上的32位进程会将任何对C:'Windows'System32的调用透明地重定向到C:'Windows'SysWOW64,而进程不知道。

要使32位进程在64位操作系统上引用real System32,可以使用C:'Windows'SysNative

由于PowerShell有32位和64位版本,并且它位于系统文件夹中,因此您需要使用上述规则来引用正确的可执行文件,这取决于您是从64位还是32位进程中调用它。

典型的场景(您想调用相同位的版本)是最简单的(只需调用powershell.exe或通过System32引用它),但如果您想引用其他版本,则会变得复杂。


获取模块

我将进一步补充,如果你想看看哪些模块是可用的,你应该调用Get-Module,而不是在目录中查找。

在32位代码中使用仅64位模块

如果你需要一个只能在64位代码中使用的模块的功能,在32位代码中,你可以使用PowerShell Remoting来完成这个任务。

你可以远程进入一台64位的机器(甚至是当前的机器),执行你需要的代码,在32位的过程中得到结果。

您还可以使用隐式远程处理来远程使用命令,就像它们在本地可用一样:

示例(来自32位powershell):

$session = New-PSSession -ComputerName . # connecting to the local computer
Invoke-Command -Session $session -ScriptBlock { Import-Module NFS }
Import-PSSessin -Session $session -Module NFS
# Call NFS cmdlets
# more program stuff
Remove-PSSession -Session $session