determine 32 or 64bit OS?

Hello,

Need to determine via script if running on a 32 or 64bit version of windows. It needs to work on server 2003, 2008, and 2008R2, so Win32_Operatingsystem's OSArchitecture property will not work for all (not available on server 2003).

I've seen others say to use the following (copy/paste from MSDN doc)
http://msdn.microsoft.com/en-us/library/aa394373%28v=VS.85%29.aspx : 

--------------------------
The Win32_Processor class has these properties.

AddressWidth
Data type: uint16
Access type: Read-only

On a 32-bit operating system, the value is 32 and on a 64-bit operating system it is 64. This property is inherited from CIM_Processor.

------------

so considering that is a property of the processor, I'm wondering if this can be relied on to determine the OS architecture? Can anyone confirm this is the recommended and reliable way to go? Otherwise, I will write a function that uses OSArchitecture for 2008 and 2008R2 and use the Win32_OperatingSystem 'Name' property for server 2003. Between those two things I know I can reliable return the correct information, but if there is one simple place to check, of course I would rather just do that.

anyone?

March 6th, 2012 6:00pm

Powershell is built on top of the .NET Framework.

In the .NET Framework, the IntPtr structure represents a pointer or handle in the underlying operating system. And it has a Size property. Just check if it's 4 or 9 bites long.

Assuming only 32-bit or 64-bit:

if ([System.IntPtr]::Size -eq 4) { "32-bit" } else { "64-bit" }

Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 6:17pm

Using the win32_processor class will tell you about the processor, not the O/S.  The processor may be 64-bit, but have a 32-bit O/S installed.
March 6th, 2012 6:18pm

Paulo,

That is beautiful! No less than a work of art for the particular question :)

One question though: will this *always* be accurate? The only thing I can think of (which I don't even know is even possible at the moment) is if a 64bit OS was configured specifically to run the 32bit version of .net... ? is that even possible? If it is I'm guessing that might be a scenario that would make this method not work.

I hope that's not possible, because I love your suggested approach.

let me know if you know, I'll also do some googling. BTW, you may be thinking even if that were possible, how often would I really come across it? well, if its possible, I will come across it, my environment is a large server hosting environment 5000+ servers, so I really need to cover all my bases.

thanks again and please let me know if 64bit OS can sometimes be configured to run only 32bit version of .net and therefore make this not work.

March 6th, 2012 6:39pm

Bigteddy, yea, that's what I thought also... but since the MSDN doc says "On a 32-bit operating system, the value is 32 and on a 64-bit operating system it is 64." I wasn't sure if this may be a case where the processor class actually yields some operating system specific info... anyone else know about that particular one?

Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 6:41pm

thanks Bhavik, that link (in the comments section) also said the 'addressWidth' of 'Win32_Processor' will do the job, and for the OS, not the CPU.
  • Proposed as answer by Dodoxx Tuesday, June 10, 2014 8:49 AM
March 6th, 2012 6:53pm

Paulo,

That is beautiful! No less than a work of art for the particular question :)

This method will only work when run on the system itself.  So you would need Powershell (with remoting) installed on all your target servers for this to work.

I think you will have to make do with WMI, and write code to distinguish between 2003 and o

Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 6:57pm

Bigteddy, thanks again for the input.

All the scripts will actually be executed locally (delivered via Tivoli Endpoint Manager to it's agent which will execute it locally).

I know I can get to the right answer via wmi (using a combination of properties), but the main question here is if I still need to do that, or if there is one check that will work on all... and so far, there are two potential options that are one checks that will work on all. Both Paulo's option and the Win32_Processor's AddressWidth property.

As of now, I want to use Paulo's option, but I'm uncertain about the scenario of someone forcing a 64bit OS to only use 32bit version of .net... I don't know if that is even possible. I know you can create a 32bit .net assembly and force it to run in a 32bit process on a 64bit OS, but in my particular case, powershell will be executed and passed a file to run... no explicit path, so it will use the path environment variable and typically that means on 32bit OS's 32bit version of PS will run, and on 64bit OS's, 64bit version of PS will run, each using that particular version of .net. I have confirmed using Paulo's option on 32bit powershell running on 64bit OS will return "32-bit". But I don't think that case will happen, for me, which is running from an agent that just issues the powershell command with parameters for a script file to run etc... the only case I think this could break is if there is *some* way that a 64bit OS can be configured to *only* use the 32bit version of .net.

anyone further input from anyone? all your help is appreciated, everyone. thanks.

March 6th, 2012 7:37pm

So if I understand you, all your servers have Powershell installed?
Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 7:47pm

dont yours?    
March 6th, 2012 7:55pm

So if I understand you, all your servers have Powershell
Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 7:56pm

Not just the servers.  All the workstations too, (XP upwards), with remoting enabled.  What a pleasure to administrate!
March 6th, 2012 7:57pm

there are good odds that if the agent is 32bit on a 64bit system that the 32bit powershell will be run    
Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 8:06pm

oh man... that is the case here. I'll need to test to confirm, but the agent *is* 32bit.

thank you jrich! That could decide this for me... I'll post back.

March 6th, 2012 9:12pm

You're right to be cautionous.

IntPtr.Size will actually report if the process is 32-bit or 64-bit.

This is code I actually am using to configure the registry for a 32-bit application, regardless of it's a 32 or 64 bit Powershell console:

if ([System.IntPtr]::Size -eq 8) {
    $RegistryRoot = 'HKLM:\SOFTWARE\Wow6432Node\MyApp'
}
else {
    $RegistryRoot = 'HKLM:\SOFTWARE\MyApp'
}

Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 9:29pm

My 64-bit Windows OS shows 8 as the value of [System.IntPtr]::Size    - Larry   >  > On 3/6/2012 12:17 PM, Paulo Morgado [MVP] wrote: > Powershell is built on top of the .NET Framework. > > In the .NET Framework, the IntPtr structure  > represents a pointer or handle in the underlying operating system.  > And it has a Size property > Just check if it's 4 or 9 bites long. > > Assuming only 32-bit or 64-bit: > if ([System.IntPtr]::Size -eq 4) {"32-bit"  } else {"64-bit"  } >  
March 6th, 2012 9:55pm

Of courese it does. The 9 was a typo.

But it will show 4 on the x86 console.

Free Windows Admin Tool Kit Click here and download it now
March 6th, 2012 10:01pm

Thanks all for the input, I appreciate it.

I confirmed that the Tivoli agent is a 32bit process, and thus it executes the 32bit version of powershell. So this would lead to [System.IntPtr]::Size reporting 32-bit even on my 64bit systems. As Paulo already said, this tells us if the 'process' is 64 or 32 bit. So my case is a peculiar circumstance that makes this very elegant solution not an option for me. However I will certainly be using it for other cases, as its a great way to concisely get this information... and the more 'typical' scenario (when a 32 bit agent is not launching your script for you, forcing it to 32bit version of PS) would be a user executing the script and it would work great for that... or in remoting cases. Even though I can't use for my scenario I'll be marking as an answer. Thank you Paulo. 

Thank you jrich for catching that one (the fact that if the agent is 32bit and it starts powershell, it will start the 32bit version of powershell)!

I will use the method I have been using, which I know works. It's my own function that first determines if it's running on server 2003 or 2008 and uses the methods that work for them. For 2003, I parse the Win32_OperatingSystem.Caption property for 'x64', if it's there, it's 64bit, if not, it's 32bit. For 2008 and newer I use Win32_OperatingSystem.OSArchitecture. I'll stick with this method for my Tivoli agent based scenario.

Thanks again all!
March 6th, 2012 10:51pm

I'd just like to say, well done, for exploring all the possibilities, and seeing the possible pitfalls of each.  In the end you came back to your original code, but you certainly did a thorough investigation of othe
Free Windows Admin Tool Kit Click here and download it now
March 7th, 2012 6:17am

I also looked into this when I was using WMI to gather some data from my servers. On Windows kernel 6 and higher servers it is quite easy you can just do:

gwmi win32_operatingsystem | select osarchitecture

Something that works on Windows kernel 5 and up is this:

gwmi win32_processor | select -first 1 | select addresswidth

  • Marked as answer by c0pe Friday, March 09, 2012 10:04 PM
March 7th, 2012 7:06am

Under .NET V4 (so PowerShell V3, or earlier if using a .config to force use of .NET 4) there are properties on [Environment] that directly exposes this:

PS> [environment]::Is64BitOperatingSystem
True
PS> [environment]::Is64BitProcess
True

Free Windows Admin Tool Kit Click here and download it now
March 7th, 2012 11:45am

On a 64 bit machine, this is defined in system environment variables:

ProgramFiles(x86)=C:\Program Files (x86)

  • Marked as answer by c0pe Friday, March 09, 2012 10:05 PM
March 7th, 2012 8:49pm

According to the question, that's not right.

The IntPtr size of a 32-bit Process on a 64-bit OS is still 4.

It's not possible to detect the OS-architecture with the IntPtr. You can only detect the Bit-Architecture of the current Process.
Free Windows Admin Tool Kit Click here and download it now
January 9th, 2015 7:33am

Using PowerShell and SystemInfo:

systeminfo | Where-Object { $_.Contains("System Type") }

Result may be:
System Type:               X86-based PC
or
System Type:               x64-based PC


PS C:\Windows\system32> $bitVersion = (systeminfo | Where-Object { $_.Contains("System Type") }).Substring(28, 2)
PS C:\Windows\system32> $bitVersion
64
May 22nd, 2015 5:31am

Using PowerShell and SystemInfo:

systeminfo | Where-Object { $_.Contains("System Type") }

Result may be:
System Type:               X86-based PC
or
System Type:               x64-based PC


PS C:\Windows\system32> $bitVersion = (systeminfo | Where-Object { $_.Contains("System Type") }).Substring(28, 2)
PS C:\Windows\system32> $bitVersion
64
Free Windows Admin Tool Kit Click here and download it now
May 22nd, 2015 9:26am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics