为什么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架构),因为它总是返回给我类似"模块未找到"或"文件未找到"....
从我的回答:
在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