我在Windows Server机器上启动了用于x86的Powershell控制台并执行:
get-childitem C:\Windows\System32\WindowsPowerShell\v1.0\Modules\*s
我得到以下列表:
CimCmdlets,DirectAccessClientComponents来说,KDS,Microsoft.PowerShell.Diagnostics,NetQoS的,NetworkConnectivityStatus,PSDiagnostics,ScheduledTasks,TLS
然后,我启动了x64控制台并执行相同的命令,并获得更多的DIR列表:
BestPractices ,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 \ WindowsPowerShell \ v1.0 \ Modules \ FailoverClusters \ FailoverClusters.psd1 \ Windows \ WinSxS \ amd64_microsoft-windows-f..rcluster-powershell_31bf3856ad364e35_6.3.9600.17112_none_8555e001e29b71bc \ FailoverClusters.psd1
(注意:看起来像目录本身没有链接,fsutil只返回一个条目 – 与dirname相同)
所以问题是:为什么Get-ChildItem
在x86与x64 Get-ChildItem
主机上的工作方式不同? 这实际上是如何工作的?
是的,我明白,FailoverClusters模块不能在x86架构上工作,但仍然…我打破了我的头,试图找出错误在哪里(意外编译我的x86架构的C#主机),因为它总是返回类似“未find模块”或“找不到文件”….
从我的答案这里 :
在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位操作系统上引用真实的 System32
,可以使用C:\Windows\SysNative
。
由于PowerShell具有32位和64位版本,并且位于系统文件夹内,因此需要使用上述规则来引用正确的可执行文件,具体取决于您是从64位还是32位进程调用它。
典型的场景(你想调用相同的位的版本)是最简单的(只需调用powershell.exe
或通过System32
引用它),但如果你想引用其他版本,它会变得毛茸茸的。
我会进一步补充说,如果你想查看哪些模块可用,你应该调用Get-modulee
而不是查看目录。
如果你需要一个只有64位代码的模块的功能,那么你可以使用PowerShell Remoting来完成这个功能。
你可以远程访问一个64位的机器(甚至是当前机器),执行你需要的代码,把结果返回到32位的过程。
您也可以使用隐式远程来远程使用这些命令,就像它们本地可用一样:
示例(从32位PowerShell):
$session = New-PSSession -ComputerName . # connecting to the local computer Invoke-Command -Session $session -ScriptBlock { Import-modulee NFS } Import-PSSessin -Session $session -modulee NFS # Call NFS cmdlets # more program stuff Remove-PSSession -Session $session