Blogroll

Search

Calling PowerShell 64bit from 32bit and visa versa

November 4th, 2011 by Karl

So why would somebody want to call 64bit PowerShell for a 32bit PowerShell process or visa versa? Well there are numerous reasons but sometimes you happen to be in a host that is on kind of process (maybe triggered by SCCM, or inside a Opalis/Orchestrator runbook, or a custom application, but there are either dotnet Classes, Snapins or Modules, or even COM Objects that are soley of the opposite bitness. Sometimes your code actually has to do something that requires for instance a 64bit SnapIn, but also uses a COM object that is 32bit only.

So first how can we detect whether we are in a 64bit or 32bit process so our code can make a decision what to do? Well a 64bit Pointer is 64bits and as a byte is 8bits then 64/8 takes up 8 Bytes of space, while a 32bit weighs in at 4 Bytes. In Dotnet a convenient way to find this out is to see what the size of an IntPtr is with [IntPtr]::Size

image

So if you are in a 64bit Process , and want to call some 32Bit code, either waiting for it to finish or in the background, if you have PowerShell V2 or up. its easy. you can use Start-Job which normally will start a process in the same bitness as you but there is a parameter called –Runas32 . This is great and convenient and easy to use, and there are also other features like being able to use specific credentials easily.

Because jobs run in the background, if you want to wait and get the results you can pipe it to Wait-Job and then to Receive-Job. Here is an example

start-job { [intptr]::Size } -RunAs32 | wait-job | Receive-Job

and to prove that its doing what it should lets run it from a 64bit shell.

image

So with all this goodness we’d hope that when in 32 bit PowerShell there would be a –RunAs64 switch, but alas our hopes are fruitless in this case.

So what does a 32 Bit backwater admin do to escape this pain? Aha. we can call the PowerShell EXE directly!! I know where it lives

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

However we find that our new PowerShell is actually still 32 Bit? What is going on? We’ll system32 inside a 32bit process is redirected to the 32bit System32 which following Microsoft’s great legacy of confusing names is called SysWow64. So on a 64bit box, the real 64 bit system directory is System32 while the 32bit is SysWow64 !!! Man all these layers of confusion. If only we could just go native.

well that’s the key. There is an “invisible” folder name when inside a 32bit that lets you actually go inside the 64bit System32 directory and its called Sysnative. so lets try it out

image

and if you do the same this refering to Syswow64 from inside a 64 bit process you can load 32 bit powershell

image

So how can we best use this. We’ll I ussually have a quite complicated function that will test what bitness I am and do the sysnative \syswo64 trick only if needed However the simplest thing is just to make a couple of aliases.

set-alias ps64 "$env:windir\sysnative\WindowsPowerShell\v1.0\powershell.exe"
set-alias ps32 "$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe"

and here is an example using it, piping in data and also verifying the bitness difference

image

Just be aware that syswow64 won’t resolve when inside 32bit and sysnative won’t resolve when inside a 64bit process, so its best to make some nice robust wrapper functions.

Posted in Powershell | 2 Comments »

2 Responses

  1. Mike Merrett Says:

    That is SO useful, I’m amazed it’s so little known. Might even get around my problems with Portable ISE 64-bit….?

  2. PsCoder Says:

    You are a life saver! THANK YOU !!
    Being able to use PS modules from 32bit and 64bit is exactly what we were needing for Exchange and Office 365 scripts. Your examples and detailed explanation on intptr was spot one!

    Thumbs up to you! Sir!

    Kansas City

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.