63

How can I determine the OS type, (Linux, Windows) using Powershell from within a script?

The ResponseUri isn't recognised when this part of my script is ran on a Linux host.

$UrlAuthority = $Request.BaseResponse | Select-Object -ExpandProperty ResponseUri | Select-Object -ExpandProperty Authority 

So I want an If statement to determine the OS type that would look similar to this:

If ($OsType -eq "Linux") { $UrlAuthority = ($Request.BaseResponse).RequestMessage | Select-Object -ExpandProperty RequestUri | Select-Object -ExpandProperty host } Else $UrlAuthority = $Request.BaseResponse | Select-Object -ExpandProperty ResponseUri | Select-Object -ExpandProperty Authority 

I could use Get-CimInstance Win32_OperatingSystem but it would fail on Linux as it's not recognised.

2
  • doesn't get-host contain that data? Commented Jun 22, 2017 at 15:33
  • Not that I can tell. Nor from the documentation link Commented Jun 22, 2017 at 15:38

11 Answers 11

92

Aren't there environment variables you can view on the other platforms for the OS?

Get-ChildItem -Path Env: 

Particularly, on Windows at least, there's an OS environment variable, so you should be able to accomplish this by using $Env:OS.


Since some time has passed and the PowerShell Core (v6) product is GA now (the Core branding has been dropped as of v7), you can more accurately determine your platform based on the following automatic boolean variables:

$IsMacOS $IsLinux $IsWindows 
Sign up to request clarification or add additional context in comments.

16 Comments

@gms0ulman It looks like it reports Windows_NT on any Windows box. I think OP is looking for one versus the other since he wasn't asking something along the lines of "Am I on Windows 10 or Ubuntu?"
@boomcubist I thought of an even simpler check (and was unable to edit my other comment): If ($env:OS) since it only has two states
Use [System.Environment]::OSVersion.Platform. It is documented on MSDN for and appears to be present in all .NET versions (1.1, 2.0, 3.0, 3.5, and the current version). $PSVersionTable.Platform returns that value in PowerShell 6 Core. It will be Win32NT on Windows or Unix on Linux and macOS.
@DaveF Since PSv6 has gone GA, there are now $IsMacOS and $IsLinux automatic variables where you can determine your OS.
Also, it's worth mentioning that $IsWindows can be used to determine if the OS is Windows. However, this variable will evaluate to false on older versions of PowerShell so it should only be used if scripts are intended to be used with newer releases.
|
28

For PowerShell Core (Powershell Version 6.0+), you can use Automatic Variables: $IsLinux, $IsMacOS and $IsWindows.

For example,

if ($IsLinux) { Write-Host "Linux" } elseif ($IsMacOS) { Write-Host "macOS" } elseif ($IsWindows) { Write-Host "Windows" } 

Comments

15

Since the PowerShell versions 6.1 on Windows/Linux/OSX went to GA you can use the new properties of $PSVersionTable, OS, Platform and GitCommitId

Update In v6.0.0-beta.3 there are some breaking changes:

  • Change positional parameter for powershell.exe from -Command to -File

$PSVersionTable on :

Platform Win32NT OS Microsoft Windows 10.0.15063

PS C:\Users\LotPings> $PSVersionTable Name Value ---- ----- PSVersion 6.1.0 PSEdition Core GitCommitId 6.1.0 OS Microsoft Windows 10.0.17134 Platform Win32NT PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0 

Platform Unix OS Linux (ubuntu)

PS /home/LotPings> $PSVersionTable Name Value ---- ----- PSVersion 6.1.0 PSEdition Core GitCommitId 6.1.0 OS Linux 4.15.0-34-generic #37-Ubuntu SMP Mon Aug 27 15:21:48 UTC 2018 Platform Unix PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0 

Platform Unix OS Darwin

PS /Users/LotPings> $PSVersionTable Name Value ---- ----- PSVersion 6.1.0 PSEdition Core GitCommitId 6.1.0 OS Darwin 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RE... Platform Unix PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0 

5 Comments

This won't help when running on PowerShell before version 6.
@lit The absence/presence of $env:OS will tell something different as the absence/presence of $PSVersionTable.Os or $PSVersionTable.Platform
@LotPings - Yes, it might be possible to decipher the platform from some broad collection of things present and things not. Sounds like temperamental code to write and even more temperamental to maintain.
@lit I believe that [System.Environment]::OSVersion.Platform works for all versions. See my comment for the accepted answer.
@lit, seems like we always have to work backwards anyways... code tries to assume it's on latest-and-greatest, and work backwards to some level of "I can't work in this environment. Please upgrade". On Windows, $PSVersionTable isn't in Powershell 1.0. So, kludgey as it is, checking if $PSVersionTable exists works as a cheap-and-dirty check for Powershell 1.0, which didn't really come with a convenient way to check like $PSVersionTable provides now.
15

Prior to PowerShell [Core] version 6, this was only possible by asking .NET directly. This can be done with one line:

[System.Environment]::OSVersion.Platform 

This will return either Win32NT for anything descended from Windows NT (all current versions of Windows) or Unix for anything *nix (including Mac, Linux, &c.). If it returns Unix then you're obviously running v6+, so further information can be had from $PSVersionTable.PSEdition, $PSVersionTable.Platform, and $PSVersionTable.OS, and the automatic variables will be available too: $IsLinux, $IsMacOs, and $IsWindows.

Here's what I have in my profile.ps1 to make this easier by setting $IsWindows:

function Get-PSPlatform { return [System.Environment]::OSVersion.Platform } switch (Get-PSPlatform) { 'Win32NT' { New-Variable -Option Constant -Name IsWindows -Value $True -ErrorAction SilentlyContinue New-Variable -Option Constant -Name IsLinux -Value $false -ErrorAction SilentlyContinue New-Variable -Option Constant -Name IsMacOs -Value $false -ErrorAction SilentlyContinue } } 

This works in all versions of PowerShell as this has been available from .NET since version 1.x. See PlatformID documentation for details.

— Please see Dave F's comment; I wrote this answer because that seems how SO works to get an answer promoted from a comment.

Comments

7

Building on the above, if you only want to detect whether or not you're running under Windows, and you want a script that's forwards and backwards compatible in PowerShell and PowerShell Core, there's this:

if ($IsWindows -or $ENV:OS) { Write-Host "Windows" } else { Write-Host "Not Windows" } 

Comments

6

Actually, there should be global variables added by the PowerShell console itself--they're not considered environment variables though, which is why they wouldn't show up when using dir env: to get a list.The OS-specific ones I see for now are $IsLinux, IsMacOS and $IsWindows. This is of at least PowerShell version 6.0.0-rc and above for Mac/Linux.

You can see a list of what's available by using just Get-Variable (in a fresh session without loading your profile, if you just want what comes build-in by default).

Comments

3

When you only have to check if it is windows or linux, maybe you could use this (quick and dirty):

if ([System.Boolean](Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue)) { #windows } else { #Not windows } 

Comments

1

This will work in any version of Powershell for the problems described in the comments on other answers.

$iswin = $PSVersionTable.Platform -match '^($|(Microsoft )?Win)' 

With $False being 'nix.

4 Comments

Something wrong with this one. $PSVersionTable.Platform returns $null on Win 11 and $PSVersionTable.Platform -match '^($|(Microsoft )?Winadfsdfsd)' returns true.
Nope, that's working. Returned true and you're on windows. All linux versions have the string populated, and some windows do. I've set it up in a way that it'll work in all three cases
@duct_tape_coder
EDIT: Nevermind, MY BAD, it also returns true for empty string on old PowerShell, I'm blind. Then it begs an explanation in the answer instead about the approach taken :)
1

Some more ways for Osx:

sw_vers -productVersion 10.12.6 

Or (there's a "key - os_version" right above it, but I don't see how they relate):

[xml]$xml = system_profiler SPSoftwareDataType -xml $xml.plist.array.dict.array.dict.string -match 'macos' macOS 10.12.6 (16G1510) 

Json is much easier than xml key/string pairs within dict ("| select os_version"). You can run this remotely with "invoke-command -hostname comp001 -filename script.ps1" (ssh with shared keys).

system_profiler SPSoftwareDataType -json | convertfrom-json | % spsoftwaredatatype | ? _name -eq os_overview _name : os_overview boot_mode : normal_boot boot_volume : Macintosh HD kernel_version : Darwin 20.6.0 local_host_name : comp001 os_version : macOS 11.6 (20G165) secure_vm : secure_vm_enabled system_integrity : integrity_enabled uptime : up 5:17:27:52 user_name : admin (admin) 

Comments

0

I you don't have the latest PowerShell core installed you can use a small scriptblock like:

if ($PSVersionTable.PSVersion.Major -lt 6.0) { switch ($([System.Environment]::OSVersion.Platform)) { 'Win32NT' { New-Variable -Option Constant -Name IsWindows -Value $True -ErrorAction SilentlyContinue New-Variable -Option Constant -Name IsLinux -Value $false -ErrorAction SilentlyContinue New-Variable -Option Constant -Name IsMacOs -Value $false -ErrorAction SilentlyContinue } } } $script:IsLinuxEnv = (Get-Variable -Name "IsLinux" -ErrorAction Ignore) -and $IsLinux $script:IsMacOSEnv = (Get-Variable -Name "IsMacOS" -ErrorAction Ignore) -and $IsMacOS $script:IsWinEnv = !$IsLinuxEnv -and !$IsMacOSEnv 

Comments

0

Most of the answers seem overly complex. It appears the only time $IsWindows is $null is in PowerShell 5.1, so wouldn't this work?

if($null -eq $IsWindows) {$IsWindows, $IsLinux, $IsMacOS = $true, $false, $false} 

Afterwards, run a test:

[PSCustomObject]@{Windows = $IsWindows; Linux = $IsLinux; MacOS = $IsMacOS} 

PowerShell 5.1 returns:

Windows Linux MacOS ------- ----- ----- True False False 

PowerShell 7.4.6 on Windows returns:

Windows Linux MacOS ------- ----- ----- True False False 

And PowerShell 7.4.6 on Linux returns:

Windows Linux MacOS ------- ----- ----- False True False 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.