Answered by:
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?
Question
Answers
-
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" }
Paulo Morgado- Marked as answer by c0pe Tuesday, March 6, 2012 10:51 PM
-
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
Richard J Cox
- Marked as answer by c0pe Friday, March 9, 2012 10:07 PM
-
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 9, 2012 10:04 PM
-
This link should help you:
Thanks & Regards
Bhavik Solanki
Please click “Mark as Answer” if this post answers your question and click "Vote as Helpful if this Post helps you.- Marked as answer by c0pe Tuesday, March 6, 2012 10:55 PM
-
there are good odds that if the agent is 32bit on a 64bit system that the32bit powershell will be run
Justin Rich
http://jrich523.wordpress.com
PowerShell V3 Guide (Technet)
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Marked as answer by c0pe Tuesday, March 6, 2012 10:54 PM
-
All replies
-
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" }
Paulo Morgado- Marked as answer by c0pe Tuesday, March 6, 2012 10:51 PM
-
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.
Grant Ward, a.k.a. Bigteddy
-
This link should help you:
Thanks & Regards
Bhavik Solanki
Please click “Mark as Answer” if this post answers your question and click "Vote as Helpful if this Post helps you.- Marked as answer by c0pe Tuesday, March 6, 2012 10:55 PM
-
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.
-
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?
-
-
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 others.
Grant Ward, a.k.a. Bigteddy
What's new in Powershell 3.0 (Technet Wiki)
- Edited by Bigteddy Tuesday, March 6, 2012 6:57 PM
-
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.
-
So if I understand you, all your servers have Powershell installed?
Grant Ward, a.k.a. Bigteddy
-
don’t yours?
Justin Rich
http://jrich523.wordpress.com
PowerShell V3 Guide (Technet)
Please remember to mark the replies as answers if they help and unmark them if they provide no help. -
So if I understand you, all your servers have Powershell installed?
Grant Ward, a.k.a. Bigteddy
No, but that doesn't really matter. I'll only be running PS scripts on systems that have PS installed. Tivoli will be handling the targeting of the correct systems. Then the Tivoli agent on each system is what will actually be executing the scripts.
so at this point, I really just need to know if it's possible that when the agent executes, say this:
powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy unrestricted -File ".\someScript.ps1"is it 'possible' that a 64bit windows OS would start the 32bit version of powershell.exe rather than what it would normally do by default, which is start the 64bit version of powershell.exe? If you can't configure the OS to only run 32bit .net, then I think I should be good to go with Paulo's method. Otherwise I'll use Win32_Processor's AddressWidth property.
- Edited by c0pe Tuesday, March 6, 2012 7:57 PM
-
Not just the servers. All the workstations too, (XP upwards), with remoting enabled. What a pleasure to administrate!
Grant Ward, a.k.a. Bigteddy
-
there are good odds that if the agent is 32bit on a 64bit system that the32bit powershell will be run
Justin Rich
http://jrich523.wordpress.com
PowerShell V3 Guide (Technet)
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Marked as answer by c0pe Tuesday, March 6, 2012 10:54 PM
-
-
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' }
Paulo Morgado -
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" }>
-
-
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! -
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 other options!
Grant Ward, a.k.a. Bigteddy
What's new in Powershell 3.0 (Technet Wiki)
- Edited by Bigteddy Wednesday, March 7, 2012 6:18 AM
-
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 9, 2012 10:04 PM
-
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
Richard J Cox
- Marked as answer by c0pe Friday, March 9, 2012 10:07 PM
-
-
-
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- Edited by Dimitry Gordejev Friday, May 22, 2015 9:44 AM
-
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" }
Paulo MorgadoDG
-
-