Dynamically switch Powershell to run in 64-bit mode
03 Sep 2013Powershell is an amazing tool in the MS Windows world of computing, I explain to the unfamiliar that it’s like BASH for windows. You can accomplish pretty much anything in *nix using BASH scripting and the same is becoming true using Powershell for Windows. Want to query Active Directory for all startup scripts assigned to a user in an OU? Powershell can do it. Want to deploy an application to every PC in your remote office in Tunguska, Siberia? Powershell can do it. Want to verify a service is running on your helpdesk server and restart it not? Powershell can do it.
As with any new tool Powershell does have its own learning curve and quirks, getting a handle of the syntax and process behavior does take some time as you’ll see with this example.
I stumbled upon this Powershell oddity while trying to parse and import a Microsoft Excel document into JD Edwards EnterpriseOne table. To do this I was calling Powershell from a C program using the jdeSystem command (the JDE version of a C library ‘system’ call). I developed the application, the business function and the Powershell script on my development client, tested it and everything went swimmingly, of course all this on the first try too. ;) Next comes a build and deploy for a unit-test in our development environment JAS and application servers. This time when I run the test I get…nothing. No errors, no warnings and no expected data. I was baffled; it still runs perfectly on my dev client but not on the server.
The culprit a combination our 64-bit Microsoft Server 2008 R2 Enterprise Server, 64-bit MS Excel ODBC driver and our 32-bit compiled JDE software. All JD Edwards C functions are compiled as 32-bit programs so when you make a ‘system’ call to launch Powershell it will by default launch the 32-bit Powershell environment regardless of the 64-bit OS… and 32-bit Powershell just won’t play nice with a 64-bit ODBC driver.
After a lot of Google-fu I found a blog post describing a similar situation and derived my fix. You ask Powershell to verify its architecture and relaunch itself recursively using, in my case, the 64-bit environment.
This is another good explanation as to when the $env:PROCESSOR_ARCHITE6432
is set to either x86 or AMD64.
Here is a brief explanation of the script below:
- Script launches
- Checks the environment variable PROCESSOR_ARCHITEW6432 to determine if we are in 64 or 32 bit land.
- If in 32-bit land, relaunch script using 64-bit Powershell and exit. Otherwise complete the script normally.
This really saved me a lot of headache and I hope it helps someone else.
#################################################### # 32-bit-Test.ps1 # Created: 03/20/2013 # Author: me # Summary: This script will test if Powershell is # running in 32-bit mode and if true # launch itself in 64-bit mode for completion #################################################### ######################################################################################################## #If Powershell is running the 32-bit version on a 64-bit machine, we need to force powershell to run in #64-bit mode to allow the OleDb access to function properly. ######################################################################################################## if ($env:PROCESSOR_ARCHITEW6432 -eq "AMD64") { write-warning "Y'arg Matey, we're off to 64-bit land....." if ($myInvocation.Line) { &"$env:WINDIR\sysnative\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile $myInvocation.Line }else{ &"$env:WINDIR\sysnative\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile -file "$($myInvocation.InvocationName)" $args } exit $lastexitcode } write-host "Main script body" ################ # END ################