none
determine 32 or 64bit OS?

    Question

  • 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?

    Tuesday, March 06, 2012 6:00 PM

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 06, 2012 10:51 PM
    Tuesday, March 06, 2012 6:17 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 09, 2012 10:07 PM
    Wednesday, March 07, 2012 11:45 AM
  • This link should help you:

    http://techibee.com/powershell/get-operating-system-architecture32-bit-or-64-bit-using-powershell/689


    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 06, 2012 10:55 PM
    Tuesday, March 06, 2012 6:36 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 09, 2012 10:04 PM
    Wednesday, March 07, 2012 7:06 AM
  • there are good odds that if the agent is 32bit on a 64bit system that the
    32bit 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 06, 2012 10:54 PM
    Tuesday, March 06, 2012 8:06 PM
  • 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
    Wednesday, March 07, 2012 8:49 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 06, 2012 10:51 PM
    Tuesday, March 06, 2012 6:17 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

    What's new in Powershell 3.0 (Technet Wiki)

    Tuesday, March 06, 2012 6:18 PM
  • This link should help you:

    http://techibee.com/powershell/get-operating-system-architecture32-bit-or-64-bit-using-powershell/689


    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 06, 2012 10:55 PM
    Tuesday, March 06, 2012 6:36 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.

    Tuesday, March 06, 2012 6:39 PM
  • 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?

    Tuesday, March 06, 2012 6:41 PM
  • 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.
    Tuesday, March 06, 2012 6:53 PM
  • 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 06, 2012 6:57 PM
    Tuesday, March 06, 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.

    Tuesday, March 06, 2012 7:37 PM
  • So if I understand you, all your servers have Powershell installed?

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Tuesday, March 06, 2012 7:47 PM
  • 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.
    Tuesday, March 06, 2012 7:55 PM
  • So if I understand you, all your servers have Powershell installed?

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    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 06, 2012 7:57 PM
    Tuesday, March 06, 2012 7:56 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

    What's new in Powershell 3.0 (Technet Wiki)

    Tuesday, March 06, 2012 7:57 PM
  • there are good odds that if the agent is 32bit on a 64bit system that the
    32bit 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 06, 2012 10:54 PM
    Tuesday, March 06, 2012 8:06 PM
  • 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.

    Tuesday, March 06, 2012 9:12 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

    Tuesday, March 06, 2012 9:29 PM
  • 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"  }
    >
     
    Tuesday, March 06, 2012 9:55 PM
  • Of courese it does. The 9 was a typo.

    But it will show 4 on the x86 console.


    Paulo Morgado

    Tuesday, March 06, 2012 10:01 PM
  • 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!
    Tuesday, March 06, 2012 10:51 PM
  • 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 07, 2012 6:18 AM
    Wednesday, March 07, 2012 6:17 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 09, 2012 10:04 PM
    Wednesday, March 07, 2012 7:06 AM
  • 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 09, 2012 10:07 PM
    Wednesday, March 07, 2012 11:45 AM
  • 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
    Wednesday, March 07, 2012 8:49 PM