boomcubist
boomcubist

Reputation: 881

Determine the OS version, Linux and Windows from Powershell

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.

Upvotes: 61

Views: 59618

Answers (11)

Darin
Darin

Reputation: 2368

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

Upvotes: 0

js2010
js2010

Reputation: 27516

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)

Upvotes: 1

alain
alain

Reputation: 41

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

Upvotes: 0

gaelicWizard
gaelicWizard

Reputation: 161

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.

Upvotes: 13

Maximilian Burszley
Maximilian Burszley

Reputation: 19684

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

Upvotes: 91

Hashbrown
Hashbrown

Reputation: 13023

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.

Upvotes: 1

MCattle
MCattle

Reputation: 3167

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"
}

Upvotes: 7

zwcloud
zwcloud

Reputation: 4889

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"
}

Upvotes: 27

user6811411
user6811411

Reputation:

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

Upvotes: 15

areyling
areyling

Reputation: 2191

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).

Upvotes: 6

Patrick
Patrick

Reputation: 2208

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
}

Upvotes: 3

Related Questions