ChatGPT解决这个技术问题 Extra ChatGPT

确定已安装的 PowerShell 版本

如何确定计算机上安装了哪个版本的 PowerShell,以及是否安装了它?

pwsh --version 应该可以正常工作。我检查了Windows 11。
@Kapil 请将其作为答案发布,以便可以与其他答案一起投票。无论如何,它在 Windows 10 上对我不起作用。
@Kapil pwsh 仅在安装了较新的 PowerShell 版本时用作命令。对于旧版本,例如 Windows 10 附带的 PowerShell 5,可执行文件称为 PowerShell.exe。 (在旧版本中也没有 --version。)

1
14 revs, 12 users 69% user156862

使用 $PSVersionTable.PSVersion 确定引擎版本。如果该变量不存在,则可以安全地假定引擎是版本 1.0

请注意,$Host.Version(Get-Host).Version 不可靠 - 它们仅反映主机的版本,而不是引擎的版本。 PowerGUI、PowerShellPLUS 等都是托管应用程序,它们会设置主机的版本以反映其产品版本 ——这完全正确,但不是您要查找的。

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1

@DanielCassidy - 晚了两年,但“某些功能无法解释地不可用”可能是由于只安装了 .Net 3.5 Compact 框架而不是完整的东西。
$PSVersionTable 更可靠并返回 $PSVersion。您也可以使用 $PSVersionTable.PSVersion。即使您远程连接到运行不同版本 (invoke-command -computername myRemotePC -Credential foo {$host}) 的机器,看起来 $host 只会显示他们同意进行序列化的最低版本。而 $PSVersionTable 将显示真实版本。希望它会帮助某人..
似乎 $host.Version 不是一个好的选择...如果您远程连接到运行 PowerShell 3 的机器,您将返回 1.0,因为 RemotingHost 似乎是 v1。正确使用 $PSVersionTable 会返回 3。
@Starfish 显示的命令使用命令提示符启动 Powershell。如果未安装,该命令是否会出现“找不到 powershell”的错误?
厌倦了为此而回到这里,我只是跑了 notepad $profile 并将 function psver { $PSVersionTable; $PSVersionTable.PSVersion } 倾倒在其中。使用 . $profile 重新加载,我可以随时键入 psver 以获取详细的版本信息和其他详细信息。
X
Xantium

我会使用 Get-Host$PSVersionTable。正如 Andy Schneider 指出的那样,$PSVersionTable 在版本 1 中不起作用;它是在版本 2 中引入的。

get-host

Name             : ConsoleHost
Version          : 2.0
InstanceId       : d730016e-2875-4b57-9cd6-d32c8b71e18a
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-GB
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

$PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.4200
BuildVersion                   6.0.6002.18111
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

谢谢你!注意:在我从 v1 Powershell 手动升级的 XP 上,实际的文件夹和注册表路径(误导?!)引用 v1 而不是 v2。这是其他人在这里指定的,但这就是为什么我如此担心我是否安装了它的原因。我的路径是; C:\WINDOWS\system32\windowspowershell\v1.0
如果 $psversiontable 不存在,那么假设您使用的是 v1.0 是完全安全的 - 嘿,这也回答了您的问题。 $host.version 不可靠 - 例如在 powergui 中,它返回与 powershell 引擎版本不同的 powergui 主机版本(这是所需的。)
接受的答案指出“... $Host.Version 和 (Get-Host).Version 不可靠 - 它们仅反映主机的版本,而不是引擎”。
X
Xantium

您可以查看内置变量 $psversiontable。如果它不存在,则您拥有 V1。如果它确实存在,它将为您提供所需的所有信息。

1 >  $psversiontable

Name                           Value                                           
----                           -----                                           
CLRVersion                     2.0.50727.4927                                  
BuildVersion                   6.1.7600.16385                                  
PSVersion                      2.0                                             
WSManStackVersion              2.0                                             
PSCompatibleVersions           {1.0, 2.0}                                      
SerializationVersion           1.1.0.1                                         
PSRemotingProtocolVersion      2.1    

h
hichris123

要确定是否安装了 PowerShell,您可以检查注册表中是否存在

HKEY_LOCAL_MACHINE\Software\Microsoft\PowerShell\1\Install

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3

并且,如果存在,该值是否为 1(表示已安装),详见博文 Check if PowerShell installed and version

要确定安装的 PowerShell 版本,您可以检查注册表项

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\PowerShellVersion

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellVersion

要确定从 .ps1 脚本安装的 PowerShell 版本,您可以使用以下单行代码,详细信息请参见 PowerShell.com 中的 Which PowerShell Version Am I Running

$isV2 = test-path variable:\psversiontable

同一站点还提供了返回版本的功能:

function Get-PSVersion {
    if (test-path variable:psversiontable) {$psversiontable.psversion} else {[version]"1.0.0.0"}
}

很有用,因为在 Windows 2003 服务器上我找不到 PowerShell 的开始菜单项(它在那里但不明显),但注册表项回答了我的问题。
对于 PowerScript 3.0,似乎有一个新条目 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3(除了 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1)。在这种情况下,获取版本的正确位置似乎是 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellVersion(示例值为“3.0”)。
P
Peter Mortensen

您可以通过外部调用 PowerShell(例如从命令提示符)直接用一行检查版本

powershell -Command "$PSVersionTable.PSVersion"

根据 @psaul,您实际上可以拥有一个与它的来源无关的命令(CMD、PowerShell 或 Pwsh)。谢谢你。

powershell -command "(Get-Variable PSVersionTable -ValueOnly).PSVersion"

我已经测试过,它在 CMD 和 PowerShell 上都能完美运行。

https://i.stack.imgur.com/WN2dY.png


我在尝试时遇到了这个可怕的错误:“System.Collections.Hashtable.PSVersion:‘System.Collections.Hashtable.PSVersion’一词未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。”。所以并不总是有效
我很高兴你指出了这一点,因为了解极端情况很好,但我想它仍然适用于大多数人。
@Gonmator 有人会认为 PowerShell 会以与此命令相同的方式运行,但不幸的是它不会。我尝试修复语法以在 cmdpowershell 之间不可知地工作,但无济于事。我也会期待同样的行为。 :)
@tresf(和@Gonmator)您可以从 CMD、PowerShell 甚至 Pwsh(PS 6.0)不可知地运行它,但您需要使用这种形式:powershell -command "(Get-Variable PSVersionTable -ValueOnly).PSVersion"(这将适用于所有情况)
也在mac上测试过。 pwsh -Command "(Get-Variable PSVersionTable -ValueOnly).PSVersion" 效果很好。
T
TylerH

您可以通过完成以下检查来验证是否安装了 Windows PowerShell 版本:

单击开始,单击所有程序,单击附件,单击 Windows PowerShell,然后单击 Windows PowerShell。在 Windows PowerShell 控制台中,在命令提示符处键入以下命令,然后按 Enter:Get-Host |选择对象版本

您将看到如下所示的输出:

Version
-------
3.0

http://www.myerrorsandmysolutions.com/how-to-verify-the-windows-powershell-version-installed/


您假设已使用默认选项安装了 powershell,并且未从“开始”菜单中删除快捷方式。最好使用注册表测试。
我认为,如果您首先需要使用 PowerShell,则尝试将其作为标准运行它应该安装,然后如果您没有找到尝试搜索它的图标,那么也许您尝试从命令提示符运行它。我不认为你从注册表开始。
接受的答案指出“... $Host.Version 和 (Get-Host).Version 不可靠 - 它们仅反映主机的版本,而不是引擎”。
S
Starfish

Microsoft's recommended forward compatible method for checking if PowerShell is installed and determining the installed version 是查看两个特定的注册表项。我已经在此处复制了详细信息,以防链接断开。

根据链接页面:

根据任何其他注册表项、PowerShell.exe 的版本或 PowerShell.exe 的位置,不能保证长期有效。

要检查是否安装了任何版本的 PowerShell,请检查注册表中的以下值:

密钥位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1

值名称:安装

值类型:REG_DWORD

数值数据:0x00000001(1

要检查是否安装了 PowerShell 版本 1.0 或 2.0,请检查注册表中的以下值:

密钥位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine

值名称:PowerShellVersion

值类型:REG_SZ

数值数据:<1.0 | 2.0>


对于 PowerShell 3.0,似乎有一个新版本,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3。
链接已失效;它说“403禁止”。
S
SharpC

我发现检查是否已安装的最简单方法是:

运行命令提示符(开始、运行、cmd,然后确定)

输入 powershell 然后回车。然后你应该得到 PowerShell PS 提示符:

C:\Users\MyUser>powershell

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\MyUser>

然后,您可以通过键入 $PSVersionTable.PSVersion 从 PowerShell 提示符检查版本:

PS C:\Users\MyUser> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
2      0      -1     -1

PS C:\Users\MyUser>

如果您想返回命令提示符,请输入 exit(如果您还想关闭命令提示符,请再次输入 exit)。

要运行脚本,请参阅 http://ss64.com/ps/syntax-run.html


the accepted answer 一样,这不会为 PowerShell 1.0 返回任何内容。 The registry method 更明确。
如果powershell不在路径中,这个版本会给人一种没有安装的错觉。 Registry 方法提供了完整的信息。存在和版本。
P
Peter Mortensen

$host.version 完全错误/不可靠。这为您提供了托管可执行文件的版本(powershell.exe、powergui.exe、powershell_ise.exe、powershellplus.exe 等),不是引擎本身的版本。

引擎版本包含在 $psversiontable.psversion 中。对于 PowerShell 1.0,这个变量不存在,所以很明显,如果这个变量不可用,那么假设引擎是 1.0 显然是完全安全的。


P
Peter Mortensen

利用:

$psVersion = $PSVersionTable.PSVersion
If ($psVersion)
{
    #PowerShell Version Mapping
    $psVersionMappings = @()
    $psVersionMappings += New-Object PSObject -Property @{Name='5.1.14393.0';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows 10 Anniversary Update'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.1.14300.1000';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows Server 2016 Technical Preview 5'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.494';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3172985 1607'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.122';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3140743 1603'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.117';FriendlyName='Windows PowerShell 5 RTM 1602';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.63';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3135173 1602'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.51';FriendlyName='Windows PowerShell 5 RTM 1512';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10514.6';FriendlyName='Windows PowerShell 5 Production Preview 1508';ApplicableOS='Windows Server 2012 R2'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10018.0';FriendlyName='Windows PowerShell 5 Preview 1502';ApplicableOS='Windows Server 2012 R2'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.9883.0';FriendlyName='Windows PowerShell 5 Preview November 2014';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows 8.1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='4.0';FriendlyName='Windows PowerShell 4 RTM';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='3.0';FriendlyName='Windows PowerShell 3 RTM';ApplicableOS='Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='2.0';FriendlyName='Windows PowerShell 2 RTM';ApplicableOS='Windows Server 2008 R2 SP1 and Windows 7'}
    foreach ($psVersionMapping in $psVersionMappings)
    {
        If ($psVersion -ge $psVersionMapping.Name) {
            @{CurrentVersion=$psVersion;FriendlyName=$psVersionMapping.FriendlyName;ApplicableOS=$psVersionMapping.ApplicableOS}
            Break
        }
    }
}
Else{
    @{CurrentVersion='1.0';FriendlyName='Windows PowerShell 1 RTM';ApplicableOS='Windows Server 2008, Windows Server 2003, Windows Vista, Windows XP'}
}

您可以从 How to determine installed PowerShell version 下载详细的脚本。


一旦哈希表中没有明确存在版本,这就会中断。
R
Roman Pokrovskij

忘记此页面并不再返回的最简单方法是学习 Get-Variable

Get-Variable | where {$_.Name -Like '*version*'} | %{$_[0].Value}

无需记住每个变量。只需 Get-Variable 就足够了(并且“应该有一些关于版本的信息”)。


$PSVersionTable 相同
找PS版?键入 $PSVersion [tab] [enter]。完毕。不需要记住任何东西:)
这只有在非常熟悉所使用的管道技巧时才有用。初学者不可能比记住 $PSVersionTable 更容易记住所有这些语法
伙计们,Get-Variable 单独工作很好(如果你只需要获取版本),管道只是一个笑话:) 我也不记得管道语法。
P
Peter Mortensen

由于最有用的答案没有解决 if exists 部分,我想我会通过一个快速而肮脏的解决方案来接受它。它依赖于 PowerShell 位于路径 environment variable 中,这可能是您想要的。 (帽子提示我不知道的最佳答案。)将其粘贴到 text 文件中并命名

测试 Powershell 版本.cmd

或类似的。

@echo off
echo Checking powershell version...
del "%temp%\PSVers.txt" 2>nul
powershell -command "[string]$PSVersionTable.PSVersion.Major +'.'+ [string]$PSVersionTable.PSVersion.Minor | Out-File ([string](cat env:\temp) + '\PSVers.txt')" 2>nul
if errorlevel 1 (
 echo Powershell is not installed. Please install it from download.Microsoft.com; thanks.
) else (
 echo You have installed Powershell version:
 type "%temp%\PSVers.txt"
 del "%temp%\PSVers.txt" 2>nul
)
timeout 15

A
Aliaksandr Belik

要检查是否安装了 PowerShell,请使用:

HKLM\Software\Microsoft\PowerShell\1 Install ( = 1 )

要检查是否安装了 RC2 或 RTM,请使用:

HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-00301) -- For RC2
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-04309) -- For RTM

来源:this website


P
Peter Mortensen

我需要检查 PowerShell 的版本,然后运行相应的代码。我们的一些服务器运行 v5,而其他服务器运行 v4。这意味着某些功能(例如压缩)可能可用也可能不可用。

这是我的解决方案:

if ($PSVersionTable.PSVersion.Major -eq 5) {
    #Execute code available in PowerShell 5, like Compress
    Write-Host "You are running PowerShell version 5"
}
else {
    #Use a different process
    Write-Host "This is version $PSVersionTable.PSVersion.Major"
}

M
Martin Prikryl

PowerShell 7

只有在计算机上安装了一个版本的 PowerShell 时,接受的答案才适用。随着 PowerShell 7 的出现,这种情况变得越来越不可能。

Microsoft 的 documentation 声明在安装 PowerShell 7 时会创建其他注册表项:

从 PowerShell 7.1 开始,[installer] 包会创建注册表项,用于存储 PowerShell 的安装位置和版本。这些值位于 HKLM\Software\Microsoft\PowerShellCore\InstalledVersions\ 中。 的值对于每种构建类型(发布或预览版)、主要版本和体系结构都是唯一的。

浏览上述位置的注册表会发现以下注册表值:SemanticVersion。该值包含我们寻求的信息。

在我的电脑上,它看起来如下所示:

Path                                                                                           Name              Type Data
----                                                                                           ----              ---- ----
HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\31ab5147-9a97-4452-8443-d9709f0516e1 SemanticVersion String 7.1.3

https://i.stack.imgur.com/uRpmX.png

可以看到,我电脑上安装的PowerShell 7的版本是7.1.3。如果目标计算机上未安装 PowerShell 7,则整个密钥不应该存在。

如 Microsoft 文档中所述,注册表路径会因安装的 PowerShell 版本而略有不同。

在某些情况下,部分关键路径更改可能会带来挑战,但对于那些对基于命令行的解决方案感兴趣的人来说,PowerShell 本身可以轻松处理这个问题。

用于查询此注册表值中数据的 PowerShell cmdlet 是 Get-ItemPropertyValue cmdlet。观察它的使用和输出如下(注意使用星号 wildcard 字符代替可能更改的密钥路径部分):

PS> Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\*" -Name "SemanticVersion"

7.1.3

只是一个简单的单线。


P
Peter Mortensen

以下 cmdlet 将返回 PowerShell 版本。

$PSVersionTable.PSVersion.Major

$PSVersionTable 是一个自动变量;一个东西。它不是 cmdlet。
M
Martin Prikryl

这是“批处理文件获取 powershell 版本”的最高搜索结果,所以我想提供一个基本示例,说明如何根据 powershell 版本在批处理文件中进行条件流

通用示例

powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
    echo Do some fancy stuff that only powershell v5 or higher supports
) else (
    echo Functionality not support by current powershell version.
)

现实世界的例子

powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
    rem Unzip archive automatically
    powershell Expand-Archive Compressed.zip
) else (
    rem Make the user unzip, because lazy
    echo Please unzip Compressed.zip prior to continuing...
    pause
)

我喜欢这个前提。我从没想过以这种方式返回“非错误”值作为退出代码。我在这里唯一担心的是 %errorlevel% 可能是什么时候出现任何意外错误,比如 powershell 不在路径上,或者 $PSVersionTable.PSVersion.Major 无法解析(这将在 PS v1 上发生)等。 ?
是的,好点。这个解决方案在这方面肯定是幼稚的。在我们的组织中,我们确信只有 v4 和 v5 在起作用。
P
Peter Mortensen

您还可以从 PowerShell 命令行调用“host”命令。它应该为您提供 $host 变量的值。


这是半错误的。 host 解析为 Get-Host。无论如何,这不是获取版本的可靠方法。
D
Dut A.

我在 version 7.1.0 上试过这个,它奏效了:

$PSVersionTable | Select-Object PSVersion

输出

PSVersion
---------
7.1.0

但它在 version 5.1 上不起作用,所以宁愿在 7 以下的版本上使用它:

$PSVersionTable.PSVersion

输出

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      18362  1171

编辑

从 PowerShell 7.2.5 开始,您现在可以执行以下操作:

pwsh -v

或者

pwsh --version

输出

PowerShell 7.2.5

这似乎只是重复了多个答案中已经共享的信息。请仅在有新信息时添加新答案。
@TylerH,你介意用 PowerShell 7 给我一个答案吗?环顾四周,我之前的最后一个答案是在 2016 年,v7.1 是相当新的。
您的第一个解决方案基本上复制了@Eclipses 2014 年 3 月的答案,而您的第二个解决方案复制了已接受的答案。如果您想强调它们是否适用于 PowerShell 7,也许可以在这些答案中添加评论。
@Bren0man,仅@Eclipses 版本 (Get-Host | Select-Object Version) 中的命令措辞就足以让它与众不同。另外,我不知道 2014 年是否有 Powershell 7。第二个版本可能是重复的,只是为了将替代品保留在一个地方,但我的主要观点是第一个版本。
P
Peter Mortensen

使用选择运算符扩展答案:

Get-Host | select {$_.Version}

接受的答案指出“... $Host.Version 和 (Get-Host).Version 不可靠 - 它们仅反映主机的版本,而不是引擎”。
@PeterMortensen 看起来我的答案是在接受答案之前
@HaBo 你在看什么?接受的答案来自 2009 年。
@TylerH 那又怎样?我没有关注你的问题。我的回答清楚地表明它是对已接受答案的扩展。它是一个简化版本。
@HaBo您之前的评论读起来就像您在证明您的答案是在接受的答案之前发布的事实,而事实并非如此。您的答案是在接受答案后 7 年发布的,而在您的答案实际“扩展”后 6 年;说到这一点,您的答案并没有明确表示它是 accepted 答案的扩展(甚至不使用 Get-Host)。
T
TylerH

我制作了一个可以确定 PowerShell 版本的小批量脚本:

@echo off
for /f "tokens=2 delims=:" %%a in ('powershell -Command Get-Host ^| findstr /c:Version') do (echo %%a)

这只是使用 Get-Host 提取 PowerShell 的版本并搜索字符串 Version

当找到带有版本的行时,它使用 for 命令提取版本。在这种情况下,我们说分隔符是一个冒号,然后搜索第一个冒号,结果是我的情况 5.1.18362.752