What is the best way to program with powershell x64 and x86 variables

We have several scenarios that we use to install and configure dependencies that support the systems we support. We run them anytime we set up a development environment for testing, demonstration, training, production, etc. We often find that we have to deal with the x64 and x86 architecture, especially where powershell scripts are involved.

For example, I have a script that uses Windows Installer PowerShell Extensions to determine if a program / patch is installed. The script does not work in x64 without explicitly calling PowerShell (x86), which by default is not in the path. As we port these scripts to the x64 platform, it would be great to support one set of scripts that work in powershell on both architectures and only call x86 code if necessary.

Does anyone know of a strategy for this?

+7
powershell
Mar 02 '09 at 11:59
source share
2 answers

msgoodies blog has this suggestion for defining architecture . This approach can be used to determine the architecture and invocation of the x86 shell when a known incompatibility exists.

+2
Mar 02 '09 at 12:04
source share

I often encounter this problem with my configuration scripts. The main approach I take is

Unfortunately, much of this is done in a rude manner. Each particular x86 / x64-specific configuration entry essentially has 2 code paths (one for each architecture).

The only real exception that I could make was to check the existence of some programs on disk. I have a convenient function (Get-ProgramFiles32) that makes it easy to test programs.

if ( test-path (join-path Get-ProgramFiles32 "subversion") ) { ... 

Here are all the helper functions that I have in my shared library that deal with 32/64 bit differences.

 # Get the path where powershell resides. If the caller passes -use32 then # make sure we are returning back a 32 bit version of powershell regardless # of the current machine architecture function Get-PowerShellPath() { param ( [switch]$use32=$false, [string]$version="1.0" ) if ( $use32 -and (test-win64machine) ) { return (join-path $env:windir "syswow64\WindowsPowerShell\v$version\powershell.exe") } return (join-path $env:windir "System32\WindowsPowerShell\v$version\powershell.exe") } # Is this a Win64 machine regardless of whether or not we are currently # running in a 64 bit mode function Test-Win64Machine() { return test-path (join-path $env:WinDir "SysWow64") } # Is this a Wow64 powershell host function Test-Wow64() { return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432) } # Is this a 64 bit process function Test-Win64() { return [IntPtr]::size -eq 8 } # Is this a 32 bit process function Test-Win32() { return [IntPtr]::size -eq 4 } function Get-ProgramFiles32() { if (Test-Win64 ) { return ${env:ProgramFiles(x86)} } return $env:ProgramFiles } function Invoke-Admin() { param ( [string]$program = $(throw "Please specify a program" ), [string]$argumentString = "", [switch]$waitForExit ) $psi = new-object "Diagnostics.ProcessStartInfo" $psi.FileName = $program $psi.Arguments = $argumentString $psi.Verb = "runas" $proc = [Diagnostics.Process]::Start($psi) if ( $waitForExit ) { $proc.WaitForExit(); } } # Run the specified script as an administrator function Invoke-ScriptAdmin() { param ( [string]$scriptPath = $(throw "Please specify a script"), [switch]$waitForExit, [switch]$use32=$false ) $argString = "" for ( $i = 0; $i -lt $args.Length; $i++ ) { $argString += $args[$i] if ( ($i + 1) -lt $args.Length ) { $argString += " " } } $p = "-Command & " $p += resolve-path($scriptPath) $p += " $argString" $psPath = Get-PowershellPath -use32:$use32 write-debug ("Running: $psPath $p") Invoke-Admin $psPath $p -waitForExit:$waitForExit } 
+15
Mar 02 '09 at 13:03
source share



All Articles