4

I am writing a Powershell script which will be integrated into a product designed for 32 bit Windows machines. So on invocation it will by default run on the x86 Powershell even on 64 bit machines. I tried using [System.IntPtr]::Size but the output differs with the Powershell version on the same machine.

Powershell(32 bit) -

PS D:\powershellScripts>  [System.IntPtr]::Size    
4

Powershell(64 bit) on same machine-

PS D:\powershellScripts> [System.IntPtr]::Size
8

I need an independent solution which helps me distinguish the address size of the underlying machine.

vercetti
  • 55
  • 1
  • 8
  • 1
    Does this answer your question? [Determining 32/64 bit in Powershell](https://stackoverflow.com/questions/31977657/determining-32-64-bit-in-powershell) – Lance U. Matthews Apr 23 '20 at 20:47

2 Answers2

7

Thanks to BACON's link to a closely related question with this answer, the following concise solution is possible, which works from both 32-bit and 64-bit PowerShell sessions:

$pointerSizeInBytes = (4, 8)[[Environment]::Is64BitOperatingSystem]

A [bool] value interpreted as an array index ([int]) maps to either 0 ($false) or 1 ($true), which is used here to select the appropriate value from array 4, 8.


Here's the original form of the answer, which may have some related information of interest:


A simple test, assuming that you're always running from a 32-bit PowerShell instance:

$is64Bit = Test-Path C:\Windows\SysNative

32-bit processes (only) on 64-bit systems see the 64-bit SYSTEM32 (sic) directory as C:\Windows\SysNative

However, the following works from both 32-bit and 64-bit sessions:

$is64Bit = Test-Path 'Env:ProgramFiles(x86)'

Only on 64-bit systems does an automatically defined ProgramFiles(x86) environment variable exist alongside the ProgramFiles variable.

To get the OS-native pointer size in bytes:

$pointerSizeInBytes = (4, 8)[[bool] ${env:ProgramFiles(x86)}]

${env:ProgramFiles(x86)} uses namespace variable notation to return the value of env. var. ProgramFiles(x86) directly; casting a string value to [bool] returns $true only for non-empty strings; a [bool] interpreted as an array index ([int]) maps to either 0 ($false) or 1 ($true), which is used here to select the appropriate value from array 4, 8.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Another approach is to wrap it inside a small helper function:

function Get-Architecture {
    # What bitness does Windows use
    $windowsBitness = switch ([Environment]::Is64BitOperatingSystem) {   # needs .NET 4
        $true  { 64; break }
        $false { 32; break }
        default {
            (Get-WmiObject -Class Win32_OperatingSystem).OSArchitecture -replace '\D'
            # Or do any of these:
            # (Get-WmiObject -Class Win32_ComputerSystem).SystemType -replace '\D' -replace '86', '32'
            # (Get-WmiObject -Class Win32_Processor).AddressWidth   # slow...
        }
    }

    # What bitness does this PowerShell process use
    $processBitness = [IntPtr]::Size * 8
    # Or do any of these:
    # $processBitness = $env:PROCESSOR_ARCHITECTURE -replace '\D' -replace '86', '32'
    # $processBitness = if ([Environment]::Is64BitProcess) { 64 } else { 32 }

    # Return the info as object
    return New-Object -TypeName PSObject -Property @{
        'ProcessArchitecture' = "{0} bit" -f $processBitness
        'WindowsArchitecture' = "{0} bit" -f $windowsBitness
    }
}

Get-Architecture

This will return both the 'bitness' of the currently running PowerShell process aswell as the bitness of the OS like:

ProcessArchitecture WindowsArchitecture
------------------- -------------------
64 bit              64 bit   
Theo
  • 57,719
  • 8
  • 24
  • 41