【问题标题】:Determine the OS version, Linux and Windows from Powershell从 Powershell 确定操作系统版本、Linux 和 Windows
【发布时间】:2017-11-25 23:36:42
【问题描述】:

如何在脚本中使用 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 上会失败,因为它无法被识别。

【问题讨论】:

标签: linux windows powershell operating-system powershell-core


【解决方案1】:

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

Get-ChildItem -Path Env:

特别是,至少在 Windows 上,有一个操作系统环境变量,因此您应该能够通过使用 $Env:OS 来完成此操作。


由于一段时间过去了,PowerShell Core (v6) 产品现在是 GA(Core 品牌已从 v7 中删除),您可以更准确地确定您的平台基于以下自动布尔变量:

$IsMacOS
$IsLinux
$IsWindows

【讨论】:

  • @gms0ulman 看起来它在任何 Windows 机器上报告 Windows_NT。我认为 OP 正在寻找一个与另一个,因为他并没有问类似“我在 Windows 10 还是 Ubuntu 上?”
  • @boomcubist 我想到了一个更简单的检查(并且无法编辑我的其他评论):If ($env:OS) 因为它只有两个状态
  • 使用[System.Environment]::OSVersion.Platform。它记录在MSDN for and appears to be present in all .NET versions (1.1, 2.0, 3.0, 3.5, and the current version) 上。 $PSVersionTable.Platformreturns that value in PowerShell 6 Core。在 Windows 上为 Win32NT,在 Linux 和 macOS 上为 Unix
  • @DaveF 由于 PSv6 已经 GA,现在有 $IsMacOS$IsLinux 自动变量,您可以在其中确定您的操作系统。
  • 另外,值得一提的是$IsWindows可以用来判断操作系统是否为Windows。但是,此变量在旧版本的 PowerShell 上将评估为 false,因此仅当脚本打算与较新版本一起使用时才应使用它。
【解决方案2】:

由于Windows/Linux/OSX 上的 PowerShell 版本 6.1 进入 GA,您可以使用 $PSVersionTableOSPlatformGitCommitId 的新属性

更新在v6.0.0-beta.3中有一些breaking changes

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

【讨论】:

  • 这在 PowerShell 6 之前的版本上运行时没有帮助。
  • @lit $env:OS 的缺席/存在与$PSVersionTable.Os$PSVersionTable.Platform 的缺席/存在会有所不同
  • @LotPings - 是的,有可能从一些广泛的存在和不存在的事物集合中破译该平台。听起来像是要编写的喜怒无常的代码,维护起来更喜怒无常。
  • @lit 我相信[System.Environment]::OSVersion.Platform 适用于所有版本。请参阅我的评论以获取已接受的答案。
  • @lit,似乎我们总是不得不向后工作......代码试图假设它是最新和最好的,并向后工作到某种程度的“我不能在这个工作环境。请升级”。在 Windows 上,$PSVersionTable 不在 Powershell 1.0 中。因此,尽管很麻烦,检查 $PSVersionTable 是否存在对于 Powershell 1.0 来说是一种廉价而肮脏的检查,它并没有像现在 $PSVersionTable 提供的那样提供一种方便的检查方式。
【解决方案3】:

对于PowerShell Core(Powershell 6.0+ 版),您可以使用Automatic Variables$IsLinux$IsMacOS$IsWindows

例如,

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

【讨论】:

    【解决方案4】:

    实际上,应该有 PowerShell 控制台本身添加的全局变量——尽管它们不被视为环境变量,这就是为什么在使用 dir env: 获取列表时它们不会显示的原因。特定于操作系统的我现在看到的是$IsLinuxIsMacOS$IsWindows。这至少是适用于 Mac/Linux 的 PowerShell 版本 6.0.0-rc 及更高版本。

    您只需使用 Get-Variable 即可查看可用内容列表(如果您只想要默认内置的内容,则在不加载个人资料的新会话中)。

    【讨论】:

      【解决方案5】:

      在上述基础上,如果您只想检测您是否在 Windows 下运行,并且想要在 PowerShell 和 PowerShell Core 中向前和向后兼容的脚本,则如下:

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

      【讨论】:

        【解决方案6】:

        当你只需要检查它是 windows 还是 linux 时,也许你可以使用这个(又快又脏):

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

        【讨论】:

          【解决方案7】:

          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)
          

          【讨论】:

            【解决方案8】:

            这将适用于任何版本的 Powershell,以解决其他答案的 cmets 中描述的问题。

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

            $False 是“nix”。

            【讨论】:

              【解决方案9】:

              在 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,因为自 1.x 版起,.NET 已提供此功能。详情请见PlatformID documentation

              —— 请看Dave F's comment;我写了这个答案,因为这似乎是如何从评论中获得提升的答案。

              【讨论】:

                猜你喜欢
                • 2014-08-07
                • 2012-11-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-02-05
                • 2011-02-15
                • 2021-01-27
                相关资源
                最近更新 更多