24

I am trying to create a couple lines of code that will pull from WMI if a machine is either 32/64 bit and then if it is 64 do this .... if it is 32bit do this...

Can anyone help?

Josh D'Ambrosio
  • 265
  • 1
  • 3
  • 10

8 Answers8

31

There's two boolean static methods in the Environment you can inspect and compare, one looks at the PowerShell process, one looks at the underlying OS.

if ([Environment]::Is64BitProcess -ne [Environment]::Is64BitOperatingSystem)
{
"PowerShell process does not match the OS"
}
David Cobb
  • 680
  • 6
  • 11
  • 1
    This variable is not available in older environments, e.g., Powershell 2.0 on Windows 7. @Guvante's answer seems to work. – dmattp Dec 16 '19 at 12:13
  • @dmattp [`Is64BitProcess`](https://docs.microsoft.com/dotnet/api/system.environment.is64bitprocess) and [`Is64BitOperatingSystem`](https://docs.microsoft.com/dotnet/api/system.environment.is64bitoperatingsystem) were introduced with .NET 4.0 — first utilized by PowerShell 3.0 — whereas the [`Win32_OperatingSystem` WMI class](https://docs.microsoft.com/windows/win32/cimwin32prov/win32-operatingsystem) was introduced with Vista/Server 2008. On older systems one could [implement the same logic](https://referencesource.microsoft.com/#mscorlib/system/environment.cs,75feca36cdd83149) themselves. – Lance U. Matthews Apr 23 '20 at 21:12
  • On my 64-bit windows the `if` always fail, because both condition are `True`, the `-ne` should always fail here. We should use `-or` here. – coanor Apr 24 '22 at 04:39
25

Random discussion about it

Assuming you are running at least Windows 7, the following should work.

Including a sample that worked for me in a 32 bit version of powershell running on a 64 bit machine:

Get-WmiObject win32_operatingsystem | select osarchitecture

Returns "64-bit" for 64 bit.

if ((Get-WmiObject win32_operatingsystem | select osarchitecture).osarchitecture -eq "64-bit")
{
    #64 bit logic here
    Write "64-bit OS"
}
else
{
    #32 bit logic here
    Write "32-bit OS"
}
Guvante
  • 18,775
  • 1
  • 33
  • 64
  • Older OSes don't have an osarchitecture property, fwiw. – Mike Shepard Aug 13 '15 at 01:00
  • What are older OS's? We only have windows 7 and up – Josh D'Ambrosio Aug 13 '15 at 01:07
  • I think you're good, then. Vista might have been the last one without it. – Mike Shepard Aug 13 '15 at 02:52
  • 2
    64-bit isn't always guaranteed, I ran into a user who was getting "64 bits" as the response. – JustSomeQuickGuy Aug 12 '19 at 03:22
  • @QuickNull: Can you expand on that comment? This logic can totally fail to detect 64-bit (as mentioned in other comments) but I can't think of a situation where it would falsely detect 64-bit. – Guvante Aug 12 '19 at 18:46
  • @Guvante Sure -- the text response "64-bit" isn't guaranteed. So in the logic above, since it's looking specifically for that string might fail. I came across a user who was getting "64 bits" as the response so I had to change the logic to "if ((Get-WmiObject Win32_OperatingSystem).OSArchitecture.Contains("64") -eq $true)" – JustSomeQuickGuy Aug 13 '19 at 19:19
  • this is not working on Win11 build 22622 x64 Fr with PS version is 5.1.22621.436 – Nolmë Informatique Aug 04 '22 at 05:59
  • @NolmëInformatique: I inlined the alias in the answer that the link I provided used and got it to work on my Windows 11 machine – Guvante Sep 13 '22 at 17:32
6

This is similar to a previous answer but will get a correct result regardless of 64-bit/64_bit/64bit/64bits format.

if ((Get-WmiObject win32_operatingsystem | select osarchitecture).osarchitecture -like "64*")
{
#64bit code here
Write "64-bit OS"
}
else
{
#32bit code here
Write "32-bit OS"
}
3

Two lines smashed togther for a nice one-liner:

Write-Host "64bit process?:"$([Environment]::Is64BitProcess) ;Write-Host "64bit OS?:"$([Environment]::Is64BitOperatingSystem);
anon
  • 31
  • 1
2
[IntPtr]::Size -eq 4 # 32 bit

The size of an IntPtr will be 4 bytes on a 32 bit machine and 8 bytes on a 64 bit machine (https://msdn.microsoft.com/en-us/library/system.intptr.size.aspx).

theadriangreen
  • 2,218
  • 1
  • 14
  • 14
  • how would I put this into and if statement? – Josh D'Ambrosio Aug 13 '15 at 00:50
  • 8
    This only tells you what version of Powershell you are running. Pulled up a 32 bit window to verify. – Guvante Aug 13 '15 at 00:50
  • 1
    "The size of an IntPtr will be 4 bytes on a 32 bit machine and 8 bytes on a 64 bit machine" is incorrect. This code checks if the _process_, not the _operating system_, is 32-bit. See the linked documentation where it says (emphasis mine) "The size of a pointer or handle in **this process**, measured in bytes. The value of this property is 4 in a 32-bit **process**, and 8 in a 64-bit **process**." – Lance U. Matthews Apr 23 '20 at 21:50
2
if($env:PROCESSOR_ARCHITECTURE -eq "x86"){"32-Bit CPU"}Else{"64-Bit CPU"}

-edit, sorry forgot to include more code to explain the usage.

if($env:PROCESSOR_ARCHITECTURE -eq "x86")
 {
#If the powershell console is x86, create alias to run x64 powershell console.
 set-alias ps64 "$env:windir\sysnative\WindowsPowerShell\v1.0\powershell.exe"

$script2=[ScriptBlock]::Create("#your commands here, bonus is the script block expands variables defined above")

ps64 -command $script2
 }
 Else{
 #Otherwise, run the x64 commands.
user4317867
  • 2,397
  • 4
  • 31
  • 57
  • How would I put that into an if statement so i can put my code after 32 bit cpu and after 64 bit cpu. I tried your line with no luck, although I am sure there is more to is – Josh D'Ambrosio Aug 13 '15 at 00:50
  • 4
    This returns true in a 32 bit version of powershell running on a 64 bit version of Windows. – Guvante Aug 13 '15 at 00:51
  • 1
    Apologies, forgot to include the code for dealing with running in x64 or x86 powershell. – user4317867 Aug 13 '15 at 01:08
  • Will this be fine running on newer versions of windows ex.8.1 – Josh D'Ambrosio Aug 13 '15 at 01:14
  • I don't think there would be any problems, as long as the Powershell environment variable `$env:PROCESSOR_ARCHITECTURE` was available. – user4317867 Aug 13 '15 at 03:08
  • To echo @Guvante's comment, the `%PROCESSOR_ARCHITECTURE%` environment variable indicates the architecture of the _process_, not the _operating system_. Further, according to [The 'Sysnative' folder in 64-bit Windows explained](https://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm) "The Sysnative folder is only available in a 64-bit Windows. A 32-bit Windows does not have any Sysnative folder.", so this code seems to assume it's differentiating between 32- and 64-bit processes specifically on 64-bit Windows. – Lance U. Matthews Apr 23 '20 at 21:26
0

Reusing Guvante's Answer to create a global boolean

$global:Is64Bits=if((gwmi win32_operatingsystem | select osarchitecture).osarchitecture -eq "64-bit"){$true}else{$false}
Jose Ortega
  • 1,002
  • 13
  • 23
0

It is never necessary to filter a Boolean value (such as the value returned by the -Eq operator) through an “If” or to compare a Boolean value or expression to $True or $False.

Jose's one-liner simplifies to:

$global:Is64Bits=(gwmi win32_operatingsystem | select osarchitecture).osarchitecture -eq "64-bit"