从PowerShell确定操作系统版本,Linux和Windows

52

如何在脚本中使用Powershell来确定操作系统类型(Linux,Windows)?

当我的脚本在Linux主机上运行时,无法识别ResponseUri。

$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上会失败,因为它无法被识别。


“get-host” 包含那个数据吗? - 4c74356b41
这可能会有用:http://www.sqlserver-dba.com/2012/06/how-to-check-operating-system-type-with-powershell.html - G42
我看不出来。也没有从文档中找到任何信息链接 - boomcubist
10个回答

79

其他平台的操作系统上难道没有可以查看环境变量的方法吗?

Get-ChildItem -Path Env:

特别是在Windows系统中,至少存在一个操作系统环境变量,因此您可以使用$Env:OS来实现这一点。


由于一些时间过去了,PowerShell Core(v6)现在已经成为GA产品(自v7起,Core品牌已被取消),您可以根据以下自动布尔变量更准确地确定您的平台:

$IsMacOS
$IsLinux
$IsWindows

1
@gms0ulman 看起来它在任何 Windows 机器上都报告 Windows_NT。我认为 OP 是在寻找其中之一,因为他没有询问类似于“我是在 Windows 10 还是 Ubuntu 上吗?”的问题。 - Maximilian Burszley
2
@boomcubist 我想到了一个更简单的检查方法(并且无法编辑我的其他评论):If ($env:OS),因为它只有两种状态。 - Maximilian Burszley
10
请使用 [System.Environment]::OSVersion.Platform。该命令在 MSDN 上有记录,并且似乎在所有 .NET 版本(1.1、2.0、3.0、3.5 和当前版本)中都存在。在 PowerShell 6 Core 中,$PSVersionTable.Platform 命令会返回相同的值(https://learn.microsoft.com/zh-cn/powershell/scripting/whats-new/what-s-new-in-powershell-core-60?view=powershell-6#engine-updates)。在 Windows 上,它将是 Win32NT,在 Linux 和 macOS 上,它将是 Unix - Dave F
5
自从PSv6发布以来,现在有$IsMacOS$IsLinux的自动变量可供使用,您可以通过它们确定您的操作系统。 - Maximilian Burszley
1
另外值得一提的是,$IsWindows 可以用来判断操作系统是否为 Windows。然而,在旧版本的 PowerShell 中,这个变量会被评估为 false,因此只有在脚本打算与较新版本一起使用时才应该使用它。 - Dave F
显示剩余11条评论

21

对于 PowerShell Core(Powershell版本6.0+),您可以使用自动变量$IsLinux$IsMacOS$IsWindows

例如,

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

15
自PowerShell 6.1版本在Windows/Linux/OSX上发布后,您可以使用$PSVersionTableOSPlatformGitCommitId的新属性。 更新:在v6.0.0-beta.3中存在一些破坏性更改
  • 将powershell.exe的位置参数从-Command更改为-File

$PSVersionTable 的输出结果为:

平台为 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

2
在运行 PowerShell 6 版本之前,这并不能帮助你。 - lit
1
@lit $env:OS 的缺失/存在情况会告诉我们不同于 $PSVersionTable.Os$PSVersionTable.Platform 的缺失/存在情况。 - user6811411
1
@LotPings - 是的,也许能够从一些广泛的事物集合中解密该平台。听起来编写代码很棘手,甚至更难以维护。 - lit
3
我认为[System.Environment]::OSVersion.Platform适用于所有版本。请查看我对被接受答案的评论。 - Dave F
1
@lit,似乎我们总是不得不反向工作... 代码试图假设它在最新的环境中,并向后工作到某个级别的“我无法在此环境中工作。请升级”。 在Windows上,$PSVersionTable不在Powershell 1.0中。因此,尽管有些笨拙,但检查$PSVersionTable是否存在可以作为一种廉价而粗略的检查Powershell 1.0的方法,因为它没有像$PSVersionTable现在提供的方便的检查方式。 - user1390375

10
在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版本以来就已经可用。有关详细信息,请参见PlatformID文档

请参见Dave F的评论;我写下了这个答案,因为这似乎是SO从评论中获得答案的方式。


6
实际上,PowerShell控制台本身应该添加全局变量--尽管它们不被视为环境变量,这就是为什么使用dir env:命令获取列表时不会显示。我目前看到的操作系统特定变量有$IsLinuxIsMacOS$IsWindows。这至少适用于Mac/Linux的PowerShell版本6.0.0-rc及以上版本。您可以通过使用Get-Variable来查看可用列表(在没有加载配置文件的新会话中,如果您只想要默认内置内容)。

6

基于以上内容,如果你只想检测自己是否在运行Windows系统,并且你需要一个在PowerShell和PowerShell Core中都具有前向和后向兼容性的脚本,可以使用以下代码:

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

3

当你只需要检查操作系统是Windows还是Linux时,可以使用以下代码(快速而简单):

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

1
这将适用于任何版本的PowerShell,解决其他答案评论中描述的问题。
$iswin = $PSVersionTable.Platform -match '^($|(Microsoft )?Win)'

$False为'nix'时。


这个有问题。在Win 11上,$PSVersionTable.Platform返回$null,而$PSVersionTable.Platform -match '^($|(Microsoft )?Winadfsdfsd)'返回true。 - duct_tape_coder
不,那个可行。返回了true并且你在使用Windows。所有的Linux版本都有该字符串,而一些Windows版本也有。我已经设置好了它可以在这三种情况下工作。 - Hashbrown
@duct_tape_coder - Hashbrown

1
一些适用于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)

0
如果您没有安装最新的PowerShell Core,您可以使用以下小脚本块:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接