Определяем версию ОС, Linux и Windows из Powershell

Как я могу определить тип ОС (Linux, Windows) с помощью Powershell из скрипта?

ResponseUri не распознается, когда эта часть моего сценария выполняется на хосте Linux.

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

Итак, я хочу, чтобы оператор If определял тип ОС, который выглядел бы примерно так:

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

Я мог бы использовать Get-CimInstance Win32_OperatingSystem, но это не помогло бы в Linux, поскольку оно не распознается.


person boomcubist    schedule 22.06.2017    source источник
comment
разве get-host не содержит эти данные?   -  person 4c74356b41    schedule 22.06.2017
comment
Это может быть полезно   -  person G42    schedule 22.06.2017
comment
Не то, чтобы я мог сказать. Ни в документации ссылка   -  person boomcubist    schedule 22.06.2017


Ответы (9)


Разве нет переменных среды, которые вы можете просмотреть на других платформах для ОС?

Get-ChildItem -Path Env:

В частности, по крайней мере в Windows есть переменная среды ОС, поэтому вы должны сделать это с помощью $Env:OS.


Поскольку прошло некоторое время, и продукт PowerShell Core (v6) теперь общедоступен (торговая марка Core убрана с версии 7), вы можете более точно определить свою платформу на основе для следующих автоматических логических переменных:

$IsMacOS
$IsLinux
$IsWindows
person Maximilian Burszley    schedule 22.06.2017
comment
Сначала я попробовал это, и он вернул Windows_NT на моем компьютере с Windows 8.1 ... Я предполагаю, что OP требует более подробной информации. - person G42; 22.06.2017
comment
@gms0ulman gms0ulman Похоже, он сообщает о Windows_NT на любом компьютере с Windows. Я думаю, что OP ищет одно по сравнению с другим, поскольку он не спрашивал что-то вроде того, я на Windows 10 или Ubuntu? - person Maximilian Burszley; 22.06.2017
comment
Это потрясающе. Я могу сделать это If ("$($ENV:OS)" -ne $null) - в Linux он возвращает null, поэтому, если он не равен нулю, это Windows! Спасибо. - person boomcubist; 22.06.2017
comment
@boomcubist Вы можете упростить это, например: If ($env:OS -ne $null) Я бы предложил использовать GCI ENV: в подсказке, просто чтобы увидеть, есть ли переменная среды типа ОС, чтобы быть более детальной в вашей проверке. - person Maximilian Burszley; 22.06.2017
comment
@ TheIncorrigible1 Хорошо подмечено - я слишком усложнял это - person G42; 22.06.2017
comment
@boomcubist Я придумал еще более простую проверку (и не смог отредактировать свой другой комментарий): If ($env:OS), так как у него только два состояния - person Maximilian Burszley; 22.06.2017
comment
@TheIncorrigible1 Ты потрясающий. Это идеально. Спасибо еще раз. - person boomcubist; 22.06.2017
comment
В PowerShell 6 для Linux нет переменной Env:OS. $PSVersionTable имеет атрибуты OS и Platform. Они также доступны в PowerShell 6 для Windows. - person lit; 23.06.2017
comment
Используйте 1_. Он задокументирован в MSDN для и присутствует во всех версиях .NET (1.1, 2.0, 3.0, 3.5 и текущей версии). $PSVersionTable.Platform возвращает это значение в PowerShell 6 Core. Это будет Win32NT в Windows или Unix в Linux и macOS. - person Dave F; 04.05.2018
comment
@DaveF Поскольку PSv6 стал общедоступным, теперь есть автоматические переменные $IsMacOS и $IsLinux, по которым вы можете определить свою ОС. - person Maximilian Burszley; 04.05.2018
comment
Я видел Issues, размещенные на GitHub, где шли дебаты о введении этих переменных, но я не знал, что они были в финальном выпуске. - person Dave F; 06.05.2018
comment
Кроме того, стоит упомянуть, что $IsWindows можно использовать для определения того, является ли ОС Windows. Однако эта переменная оценивается как false в более старых версиях PowerShell, поэтому ее следует использовать только в том случае, если сценарии предназначены для использования в более новых выпусках. - person Dave F; 06.05.2018
comment
@DaveF Спасибо за разъяснения. Я отредактировал свой ответ, чтобы он был более полным теперь, когда версия 6.0 завершена (учитывая, что работа над 6.1 GA ведется) - person Maximilian Burszley; 25.07.2018
comment
Метод, предоставленный @DaveF, кажется наиболее универсальным для Windows PS, PS Core Linux/Windows/Azure. Другие методы не всегда реализованы во всех ОС версии PS. Например, $IsWindows не работает в Windows PS 5.1, а $PSVersionTable не сообщает о свойстве ОС. $env:ОС не работает в PS Core на Linux (или Azure Cloud Shell) - person BHall; 02.06.2019
comment
@BHall для этого вопроса вы бы дважды разветвились. Проверьте версию для v6+, и тогда вы сможете использовать решения в моем ответе. Если вы используете версию ниже этой, вы используете Windows по умолчанию. - person Maximilian Burszley; 02.06.2019

Поскольку версия PowerShell 6.1 для Windows/Linux/OSX перешла в общедоступную версию, вы можете использовать новые свойства из $PSVersionTable, OS, Platform и GitCommitId

Обновление В v6.0.0-beta.3 есть некоторые breaking changes:

  • Измените позиционный параметр для powershell.exe с -Command на -File

$PSVersionTable on :

Платформа Win32NT ОС 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

Платформа Unix ОС 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

Платформа Unix ОС 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
person Community    schedule 22.06.2017
comment
Это не поможет при работе с PowerShell до версии 6. - person lit; 23.06.2017
comment
@lit Отсутствие/присутствие $env:OS будет говорить о чем-то другом, как отсутствие/присутствие $PSVersionTable.Os или $PSVersionTable.Platform - person ; 23.06.2017
comment
@LotPings - Да, возможно, можно будет расшифровать платформу по некоторому широкому набору присутствующих и отсутствующих вещей. Звучит как темпераментный код для написания и еще более темпераментный для поддержки. - person lit; 23.06.2017
comment
@lit Я считаю, что [System.Environment]::OSVersion.Platform работает для всех версий. Смотрите мой комментарий для принятого ответа. - person Dave F; 04.05.2018
comment
@lit, похоже, нам всегда приходится работать в обратном порядке в любом случае ... код пытается предположить, что он находится на последнем и лучшем, и работает в обратном направлении до некоторого уровня, когда я не могу работать в этой среде. Пожалуйста, обновите. В Windows $PSVersionTable отсутствует в Powershell 1.0. Таким образом, как бы глупо это ни звучало, проверка существования $PSVersionTable работает как дешевая и грязная проверка для Powershell 1.0, которая на самом деле не поставлялась с удобным способом проверки, как сейчас $PSVersionTable. - person user1390375; 03.06.2018

Для PowerShell Core (Powershell Version 6.0+) вы можете использовать Автоматические переменные: $IsLinux, $IsMacOS и $IsWindows.

Например,

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

На самом деле должны быть глобальные переменные, добавленные самой консолью PowerShell — хотя они не считаются переменными среды, поэтому они не будут отображаться при использовании dir env: для получения списка. Специфичные для ОС, которые я вижу на данный момент являются $IsLinux, IsMacOS и $IsWindows. Это как минимум версия PowerShell 6.0.0-rc и выше для Mac/Linux.

Вы можете увидеть список того, что доступно, используя только Get-Variable (в новом сеансе без загрузки вашего профиля, если вы просто хотите, чтобы было встроено по умолчанию).

person areyling    schedule 26.03.2018

Когда вам нужно только проверить, является ли это Windows или Linux, возможно, вы могли бы использовать это (быстро и грязно):

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

Опираясь на вышеизложенное, если вы хотите только определить, работаете ли вы под Windows или нет, и вам нужен сценарий, совместимый с прямой и обратной совместимостью в PowerShell и PowerShell Core, вот что:

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

Еще несколько способов для Osx:

sw_vers -productVersion

10.12.6

Или (прямо над ним есть "key - os_version", но я не понимаю, как они связаны):

[xml]$xml = system_profiler SPSoftwareDataType -xml   
$xml.plist.array.dict.array.dict.string -match 'macos'  

macOS 10.12.6 (16G1510)
person js2010    schedule 30.12.2019

Это будет работать в любой версии Powershell для проблем, описанных в комментариях к другим ответам.

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

С $False "никсом".

person Hashbrown    schedule 05.09.2020

До PowerShell [Core] версии 6 это было возможно только путем прямого обращения к .NET. Это можно сделать одной строкой:

[System.Environment]::OSVersion.Platform

Это вернет либо Win32NT для всего, что происходит от Windows NT (все текущие версии Windows), либо Unix для чего-либо *nix (включая Mac, Linux и т. д.). Если он возвращает Unix, то вы, очевидно, используете v6+, поэтому дополнительную информацию можно получить из $PSVersionTable.PSEdition, $PSVersionTable.Platform и $PSVersionTable.OS, а также будут доступны автоматические переменные: $IsLinux, $IsMacOs и $IsWindows.

Вот что у меня есть в моем profile.ps1, чтобы упростить это, установив $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
     }
}

Это работает во всех версиях PowerShell, поскольку доступно в .NET, начиная с версии 1.x. См. документацию по идентификатору платформы. Детали.

- См. комментарий Дэйва Ф.; Я написал этот ответ, потому что кажется, что так работает SO, чтобы получить ответ из комментария.

person gaelicWizard    schedule 23.06.2021