Wednesday, September 09, 2009

Force a powershell script to run in x86 process with arguments

I needed to instantiate TFS variables but they seem to only be available in 32 bit run space.  I found a few great work ups for the vcvars here:

http://www.agileprogrammer.com/dotnetguy/archive/2007/11/22/23853.aspx

http://www.tavaresstudios.com/Blog/post/The-last-vsvars32ps1-Ill-ever-need.aspx

 

I will note that in my travels I found Jaredpar and added most of these functions to my library to test for x64/x86 program space.

 

I ended up going w/ the last one but I then needed to make sure my script was running in x86 space.  This would be automated out of SCOM so I couldn’t really just tell my users to run in in the right version (besides, what kind of solution is that?).  Some of the tasks would be run from x86 space and some from x64. 

 

Vivek Sharma had a good write up that put me on the right path here: http://www.viveksharma.com/TECHLOG/archive/2008/12/03/running-scripts-that-only-work-under-32bit-cleanly-in-64bit.aspx.

 

I had two problems.  First off, the solution doesn’t work.  -file didn’t work, I assume this is a powershell 2 change.  Neither did –executionpolicy.  ( I didn’t check if either were around in v1 but I did check my solution against a v1 install).  I also needed the arguments so after a bit of banging around, this is what I came up with.

 

#force this to run in 32 bit

if ($env:Processor_Architecture -ne "x86")

{

      write-warning "Running x86 PowerShell..."

            &"$env:WINDIR\syswow64\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile $myInvocation.Line

      exit

}

 

 

 

I created the following and called it test-Launch32Bit.ps1 to show usage.  Run with PS> test-Launch32Bit.ps1 –arg1 argument1 –arg2 aarrrrgghhh

"My Script Line: $($myinvocation.line)"

"My Proc Architecture: $env:Processor_Architecture"

"List arguments below:"

"##############"

$args

"##############"

 

 

#force this to run in 32 bit

if ($env:Processor_Architecture -ne "x86")

{

      write-warning "Running x86 PowerShell..."

            &"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" -noninteractive -noprofile $myinvocation.Line

      exit

}

 

 

Note that you will need to set your execution policy beforehand for each x86 and x64 registry trees.  They are not the same setting!  I am sure this stems from the invisible x86 registry redirection.  Easiest thing is to just run each yourself and set-executionpolicy to whatever your env demands. 

5 comments:

  1. if you run PowerShell /? you will find that the executionpolicy switch is there, you just can't use "bypass" in v2. Use "-ExecutionPolicy Unrestricted" and you shouldn't have to worry about the 32-bit execution policy.

    ReplyDelete
  2. That's a good point, I should have mentioned you can do it as part of the command, depending on your security requirements. I generally set it to 'RemoteSigned' myself. YMMV.

    ReplyDelete
  3. This one is more flexible:

    if ($env:Processor_Architecture -ne "x86") {
    write-warning "Running x86 PowerShell..."
    if ($myInvocation.Line) {
    &"$env:WINDIR\syswow64\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile $myInvocation.Line
    } else {
    &"$env:WINDIR\syswow64\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile -file "$($myInvocation.InvocationName)" $args
    }

    exit $lastexitcode
    }

    Regards,
    Grischa Zengel

    ReplyDelete
  4. I forgot. If you want it vice versa:
    That means running 64bit powershell from 32bit powershell:

    if ($env:PROCESSOR_ARCHITEW6432 -eq "AMD64") {
    write-warning "Running AMD64 PowerShell..."
    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
    }

    Regards,
    Grischa Zengel

    ReplyDelete
  5. hello i try to run my old system clipper that only execute on x86 win7 but this err appear on poweshell x86 in windows7 64

    PS Z:\> .\EXAMEN.EXE
    Error al ejecutar el programa 'EXAMEN.EXE': Unknown error (0xd8)
    En línea: 1 Carácter: 13
    + .\EXAMEN.EXE <<<< .
    En línea: 1 Carácter: 1
    + <<<< .\EXAMEN.EXE
    + CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException
    + FullyQualifiedErrorId : NativeCommandFailed

    ReplyDelete

analytics