PowerShell 脚本返回机器上的 .NET Framework 版本?
Posted
技术标签:
【中文标题】PowerShell 脚本返回机器上的 .NET Framework 版本?【英文标题】:PowerShell script to return versions of .NET Framework on a machine? 【发布时间】:2010-08-15 12:02:02 【问题描述】:在机器上返回 .NET Framework 版本的 PowerShell 脚本是什么?
我的第一个猜测是涉及 WMI。有更好的吗?
对于每次安装的 .NET [在每一行中],只返回最新版本应该是单行的。
【问题讨论】:
一台机器可以(并且将会)拥有多个版本的Fx。你想怎么处理?然后是 Fx2 .. Fx3.5SP1 混乱。你想听什么版本? 我想每次安装都需要返回完整的版本号。 有没有办法通过 WMI 做到这一点? 你要求 PowerShell,我为 C#(控制台应用程序)做了一些东西。如果您有兴趣,here 它是... 没有类似的东西真是不可思议:asp.net -v
【参考方案1】:
如果您要使用注册表,您必须递归才能获得 4.x 框架的完整版本。较早的答案都返回我系统上 .NET 3.0 的根编号(其中嵌套在 3.0 下的 WCF 和 WPF 编号更高——我无法解释),并且无法返回 4.0 的任何内容。 .
编辑:对于 .Net 4.5 及更高版本,这又略有变化,所以现在有一个很好的 MSDN article here 解释如何将 Release 值转换为 .Net 版本号,这是一个完整的火车沉船:-(
这在我看来是正确的(请注意,它在 3.0 上为 WCF 和 WPF 输出单独的版本号。我不知道那是什么意思)。它还在 4.0 上同时输出 Client 和 Full(如果您同时安装了它们):
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where $_.PSChildName -match '^(?!S)\pL' |
Select PSChildName, Version, Release
根据 MSDN 文章,您可以构建一个查找表并返回 4.5 之后版本的营销产品版本号:
$Lookup = @
378389 = [version]'4.5'
378675 = [version]'4.5.1'
378758 = [version]'4.5.1'
379893 = [version]'4.5.2'
393295 = [version]'4.6'
393297 = [version]'4.6'
394254 = [version]'4.6.1'
394271 = [version]'4.6.1'
394802 = [version]'4.6.2'
394806 = [version]'4.6.2'
460798 = [version]'4.7'
460805 = [version]'4.7'
461308 = [version]'4.7.1'
461310 = [version]'4.7.1'
461808 = [version]'4.7.2'
461814 = [version]'4.7.2'
528040 = [version]'4.8'
528049 = [version]'4.8'
# For One True framework (latest .NET 4x), change the Where-Object match
# to PSChildName -eq "Full":
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -name Version, Release -EA 0 |
Where-Object $_.PSChildName -match '^(?!S)\pL' |
Select-Object @name = ".NET Framework"; expression = $_.PSChildName,
@name = "Product"; expression = $Lookup[$_.Release],
Version, Release
事实上,由于我必须不断更新这个答案,这里有一个脚本,用于从该网页的降价源生成上面的脚本(有一点额外的)。这可能会在某个时候中断,所以我保留了上面的当前副本。
# Get the text from github
$url = "https://raw.githubusercontent.com/dotnet/docs/master/docs/framework/migration-guide/how-to-determine-which-versions-are-installed.md"
$md = Invoke-WebRequest $url -UseBasicParsing
$OFS = "`n"
# Replace the weird text in the tables, and the padding
# Then trim the | off the front and end of lines
$map = $md -split "`n" -replace " installed [^|]+" -replace "\s+\|" -replace "\|$" |
# Then we can build the table by looking for unique lines that start with ".NET Framework"
Select-String "^.NET" | Select-Object -Unique |
# And flip it so it's key = value
# And convert ".NET FRAMEWORK 4.5.2" to [version]4.5.2
ForEach-Object
[version]$v, [int]$k = $_ -replace "\.NET Framework " -split "\|"
" $k = [version]'$v'"
# And output the whole script
@"
`$Lookup = @
$map
# For extra effect we could get the Windows 10 OS version and build release id:
try
`$WinRelease, `$WinVer = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ReleaseId, CurrentMajorVersionNumber, CurrentMinorVersionNumber, CurrentBuildNumber, UBR
`$WindowsVersion = "`$(`$WinVer -join '.') (`$WinRelease)"
catch
`$WindowsVersion = [System.Environment]::OSVersion.Version
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -name Version, Release -EA 0 |
# For The One True framework (latest .NET 4x), change match to PSChildName -eq "Full":
Where-Object `$_.PSChildName -match '^(?!S)\pL' |
Select-Object @name = ".NET Framework"; expression = `$_.PSChildName,
@name = "Product"; expression = `$Lookup[`$_.Release],
Version, Release,
# Some OPTIONAL extra output: PSComputerName and WindowsVersion
# The Computer name, so output from local machines will match remote machines:
@ name = "PSComputerName"; expression = `$Env:Computername,
# The Windows Version (works on Windows 10, at least):
@ name = "WindowsVersion"; expression = `$WindowsVersion
"@
【讨论】:
这正是我正在寻找的东西,但我很难弄清楚它到底在做什么。据我了解,它将进入 NDP 注册表并递归搜索适合'^(?!S)\pL'
正则表达式的每个文件夹并获取版本和发布信息。该正则表达式究竟是什么试图限定?
@Johnrad PSChildName
是注册表项的叶名称。 \pL
是 Unicode 类别“字母”中的任意字符。 (?!S)
是消极的环顾四周,^
是字符串的开头。所以它必须以S
以外的字母开头。因此,如果您只考虑 ASCII,它与$_.PSChildName -cmatch '^[A-RT-Za-z]'
相同(注意-cmatch
)。因此它会找到名称以S
以外的字母开头的键。如果您过滤掉以S
开头的名称,我不知道您为什么要关心非ASCII...肯定是因为您很困惑。
现在我对 Get-ItemProperty -name Version,Release -EA 0
到底在做什么感到更加困惑。我知道-EA 0
与-ErrorAction SilentlyContinue
相同,但是Get-ItemProperty -name Version,Release
在将所有结果传送给它时会产生什么影响?它似乎没有从对象中删除任何变量,因为其他变量在管道中的后续命令中使用。它是否运行,当键中缺少 Version
或 Release
名称时出错,然后将它成功的对象传递到管道中的下一个命令?
Get-ChildItem 返回所有注册表子项(如果您愿意的话,是子文件夹)。 Get-ItemProperty 返回值(特别是:“Version”和“Release”)——我们忽略错误,因为我们不关心没有这些值的文件夹。所以是的,基本上我们找到每个子文件夹,然后查找版本或发布(任何没有其中一个或两个的文件夹都会被忽略)。
太棒了!我只将(?!S)
子句修改为(?![SW])
以进一步排除“Windows*”条目。这也可以通过(?=[vCF])
完成,因为我们真正关心的唯一键是版本根以及 .NET 4.0+ 的“完整”和“客户端”键。 ;)【参考方案2】:
为脚本添加了 v4.8 支持:
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where $_.PSChildName -match '^(?![SW])\pL' |
Select PSChildName, Version, Release, @
name="Product"
expression=
switch -regex ($_.Release)
"378389" [Version]"4.5"
"378675|378758" [Version]"4.5.1"
"379893" [Version]"4.5.2"
"393295|393297" [Version]"4.6"
"394254|394271" [Version]"4.6.1"
"394802|394806" [Version]"4.6.2"
"460798|460805" [Version]"4.7"
"461308|461310" [Version]"4.7.1"
"461808|461814" [Version]"4.7.2"
"528040|528049" [Version]"4.8"
$_ -gt 528049 [Version]"Undocumented version (> 4.8), please update script"
【讨论】:
【参考方案3】:gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des |
select -fi 1 -exp pschildname
如果已安装,此答案不会返回 4.5。以下来自@Jaykul 并使用递归的答案确实如此。
【讨论】:
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |排序 pschildname -des | foreach-object $_.name; $_.GetValue("版本"); 对我来说,答案现在是最重要的,所以这里有一个链接:-):***.com/a/3495491/1747983 在 Windows 10 上安装了 .NET 4.7.1,这仍然返回 v4.0。【参考方案4】:[environment]::Version
为您提供当前 PSH 副本正在使用的 CLR 的 Version
实例(如文档中的 here 所述)。
【讨论】:
我安装了 .NET 4,但 PowerShell 只会使用 2.0 运行时。所以这在这里并没有真正的帮助。 @Johannes:看你对 Q 的评论,你需要明确你想要什么。 对于 Powershell 2.0,您还可以使用$PSVersionTable
查找运行 CLR PowerShell 的版本。
更高版本怎么样?我现在有 .NET 4.7.1,脚本总是返回 4.0.30319 Rev. 42000。
@Matt 您需要翻译版本的次要部分...并注意根据 Powershell 配置中设置的内容,它可能未使用最新的次要/补丁版本。【参考方案5】:
正确的语法:
[System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion()
#or
$PSVersionTable.CLRVersion
GetSystemVersion
函数返回如下字符串:
v2.0.50727 #PowerShell v2.0 in Win 7 SP1
或者像这样
v4.0.30319 #PowerShell v3.0 (Windows Management Framework 3.0) in Win 7 SP1
$PSVersionTable
是一个只读对象。 CLRVersion 属性是一个结构化的版本号,如下所示:
Major Minor Build Revision
----- ----- ----- --------
4 0 30319 18444
【讨论】:
我在win8上试过这个,它什么也没返回。在 Windows 7 上,它返回 2 而 4.5.1 已经安装。我不知道为什么这在新平台上不可用。在 win sesrver 2008 上,它可以工作。 第一个选项适用于我的 Windows 8 64 位环境。第二个选项有效,但我认为这只是显示当前 PowerShell 实例正在运行的 .NET 版本,它几乎总是最新的。 (编辑:也许他们都这样做。) 这里也一样。在 Windows 7 上,我同时拥有 .net 2.0 和 4.0,但该命令仅显示 v2.0.50727。使用 Jaykul 的方法。 clr版本不等于framework版本,4+framework都是基于4个clr 更高版本怎么样?我现在有 .NET 4.7.1,脚本总是返回 4.0.30319 Rev. 42000。【参考方案6】:我通过 osx 的 powershell 中的制表符完成找到了这个:
[System.Runtime.InteropServices.RuntimeInformation]::get_FrameworkDescription()
.NET Core 4.6.25009.03
【讨论】:
是的,它返回 .NET Framework 4.7.2558.0 - 但是如何区分 4.7 和 4.7.1(我的 Windows 10 机器上有 4.7.1)。[version]([Runtime.InteropServices.RuntimeInformation]::FrameworkDescription -replace '^.[^\d.]*','')
【参考方案7】:
没有可靠的方法可以使用简单的脚本为所有平台和架构执行此操作。如果您想了解如何可靠地做到这一点,请从博文开始Updated sample .NET Framework detection code that does more in-depth checking。
【讨论】:
【参考方案8】:不错的解决方案
尝试使用可下载的DotNetVersionLister module(基于注册表信息和一些版本到营销版本的查找表)。
会这样使用:
PS> Get-DotNetVersion -LocalHost -nosummary
ComputerName : localhost
>=4.x : 4.5.2
v4\Client : Installed
v4\Full : Installed
v3.5 : Installed
v3.0 : Installed
v2.0.50727 : Installed
v1.1.4322 : Not installed (no key)
Ping : True
Error :
或者如果你只是想为一些 .NET 框架 >= 4.* 测试它:
PS> (Get-DotNetVersion -LocalHost -nosummary).">=4.x"
4.5.2
但它不起作用(安装/导入),例如由于不兼容,与 PS v2.0(Win 7、Win Server 2010 标准)...
以下“遗留”功能的动机
(您可以跳过阅读并使用下面的代码)
我们不得不在某些机器上使用 PS 2.0,无法安装/导入上述 DotNetVersionLister。
在我们想要更新(从 PS 2.0)到 PS 5.1(这又需要 .NET Framework >= 4.5)的其他机器上,使用两个公司自定义Install-DotnetLatestCompany
和Install-PSLatestCompany
的帮助。
为了指导管理员顺利完成安装/更新过程,我们必须确定所有机器上这些功能中的 .NET 版本以及现有的 PS 版本。
因此,我们还使用以下函数在所有环境中更安全地确定它们...
旧 PS 环境的功能(例如 PS v2.0)
因此,以下代码和以下(提取的)使用示例在这里很有用(基于此处的其他答案):
function Get-DotNetVersionByFs
<#
.SYNOPSIS
NOT RECOMMENDED - try using instead:
Get-DotNetVersion
from DotNetVersionLister module (https://github.com/EliteLoser/DotNetVersionLister),
but it is not usable/importable in PowerShell 2.0
Get-DotNetVersionByReg
reg(istry) based: (available herin as well) but it may return some wrong version or may not work reliably for versions > 4.5
(works in PSv2.0)
Get-DotNetVersionByFs (this):
f(ile) s(ystem) based: determines the latest installed .NET version based on $Env:windir\Microsoft.NET\Framework content
this is unreliable, e.g. if 4.0* is already installed some 4.5 update will overwrite content there without
renaming the folder
(works in PSv2.0)
.EXAMPLE
PS> Get-DotnetVersionByFs
4.0.30319
.EXAMPLE
PS> Get-DotnetVersionByFs -All
1.0.3705
1.1.4322
2.0.50727
3.0
3.5
4.0.30319
.NOTES
from https://***.com/a/52078523/1915920
#>
[cmdletbinding()]
param(
[Switch]$All ## do not return only latest, but all installed
)
$list = ls $Env:windir\Microsoft.NET\Framework |
? $_.PSIsContainer -and $_.Name -match '^v\d.[\d\.]+' |
% $_.Name.TrimStart('v')
if ($All) $list else $list | select -last 1
function Get-DotNetVersionByReg
<#
.SYNOPSIS
NOT RECOMMENDED - try using instead:
Get-DotNetVersion
From DotNetVersionLister module (https://github.com/EliteLoser/DotNetVersionLister),
but it is not usable/importable in PowerShell 2.0.
Determines the latest installed .NET version based on registry infos under 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP'
.EXAMPLE
PS> Get-DotnetVersionByReg
4.5.51209
.EXAMPLE
PS> Get-DotnetVersionByReg -AllDetailed
PSChildName Version Release
----------- ------- -------
v2.0.50727 2.0.50727.5420
v3.0 3.0.30729.5420
Windows Communication Foundation 3.0.4506.5420
Windows Presentation Foundation 3.0.6920.5011
v3.5 3.5.30729.5420
Client 4.0.0.0
Client 4.5.51209 379893
Full 4.5.51209 379893
.NOTES
from https://***.com/a/52078523/1915920
#>
[cmdletbinding()]
param(
[Switch]$AllDetailed ## do not return only latest, but all installed with more details
)
$Lookup = @
378389 = [version]'4.5'
378675 = [version]'4.5.1'
378758 = [version]'4.5.1'
379893 = [version]'4.5.2'
393295 = [version]'4.6'
393297 = [version]'4.6'
394254 = [version]'4.6.1'
394271 = [version]'4.6.1'
394802 = [version]'4.6.2'
394806 = [version]'4.6.2'
460798 = [version]'4.7'
460805 = [version]'4.7'
461308 = [version]'4.7.1'
461310 = [version]'4.7.1'
461808 = [version]'4.7.2'
461814 = [version]'4.7.2'
$list = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -name Version, Release -EA 0 |
# For One True framework (latest .NET 4x), change match to PSChildName -eq "Full":
Where-Object $_.PSChildName -match '^(?!S)\pL' |
Select-Object `
@
name = ".NET Framework" ;
expression = $_.PSChildName,
@ name = "Product" ;
expression = $Lookup[$_.Release],
Version, Release
if ($AllDetailed) $list | sort version else $list | sort version | select -last 1 | % $_.version
示例用法:
PS> Get-DotNetVersionByFs
4.0.30319
PS> Get-DotNetVersionByFs -All
1.0.3705
1.1.4322
2.0.50727
3.0
3.5
4.0.30319
PS> Get-DotNetVersionByReg
4.5.51209
PS> Get-DotNetVersionByReg -AllDetailed
.NET Framework Product Version Release
-------------- ------- ------- -------
v2.0.50727 2.0.50727.5420
v3.0 3.0.30729.5420
Windows Communication Foundation 3.0.4506.5420
Windows Presentation Foundation 3.0.6920.5011
v3.5 3.5.30729.5420
Client 4.0.0.0
Client 4.5.2 4.5.51209 379893
Full 4.5.2 4.5.51209 379893
【讨论】:
看不到时间使用(Get-DotNetVersion -LocalHost -nosummary).">=4.x"
@ΩmegaMan:谢谢 - 在上面的答案中更新了你的好建议 :)【参考方案9】:
参考页面Script for finding which .NET versions are installed on remote workstations。
那里的脚本可能有助于查找网络上多台机器的 .NET 版本。
【讨论】:
【参考方案10】:不漂亮。 确实不漂亮:
ls $Env:windir\Microsoft.NET\Framework | ? $_.PSIsContainer | select -exp Name -l 1
这可能有效,也可能无效。但就最新版本而言,这应该是相当可靠的,因为旧版本(1.0、1.1)基本上有空文件夹,但新版本没有——这些只有在安装了适当的框架后才会出现。
不过,我怀疑一定有更好的方法。
【讨论】:
您需要再过滤一下,“V[.0-9]+”应该将匹配限制为 .NET 文件夹(我那里还有一些其他文件夹)。然后检查是否有真正的安装...安装组件上的 WMI 可能更容易。 嗯,对……在这台机器上还有一些其他文件夹——我的另一台机器上只有一堆其他文件。不过,整个答案更像是“为我工作”的案例。我确信有一种可靠且有意的方式来获取这些信息。 psake(构建自动化工具)采用了类似的方法并成功使用它(或者至少没有人因为问题而改变它)。但他们确实不需要完整的框架版本......对于我的电脑来说,这更接近:ls $Env:windir\Microsoft.NET\Framework | ? $_.PSIsContainer -and $_.Name -match '^v\d.[\d\.]+' | % $_.Name.TrimStart('v')
在答案中的所有单行代码中,由 stej 提供的最干净且按预期工作。如果是答案,我会投票给它。
不幸的是,它不可靠。我现在有 .NET 4.7.1,脚本总是 返回 v4.0.30319。【参考方案11】:
这是我在the msft documentation 之后对这个问题的看法:
$gpParams = @
Path = 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'
ErrorAction = 'SilentlyContinue'
$release = Get-ItemProperty @gpParams | Select-Object -ExpandProperty Release
".NET Framework$(
switch ($release)
( $_ -ge 528040 ) ' 4.8'; break
( $_ -ge 461808 ) ' 4.7.2'; break
( $_ -ge 461308 ) ' 4.7.1'; break
( $_ -ge 460798 ) ' 4.7'; break
( $_ -ge 394802 ) ' 4.6.2'; break
( $_ -ge 394254 ) ' 4.6.1'; break
( $_ -ge 393295 ) ' 4.6'; break
( $_ -ge 379893 ) ' 4.5.2'; break
( $_ -ge 378675 ) ' 4.5.1'; break
( $_ -ge 378389 ) ' 4.5'; break
default ': 4.5+ not installed.'
)"
此示例适用于所有 PowerShell 版本,并且将永久有效,因为 4.8 是最后一个 .NET Framework 版本。
【讨论】:
【参考方案12】:这纯粹是因为我不得不花时间制作/编辑它应该广泛使用的时候,所以我将它提供给其他人。
以下脚本将向 TEMP 输出几个 CSV 文件,其中包含选定(在代码中)OU 中每台机器的版本和漏洞状态。您将能够远程“安全审计”机器的 OU。
连接测试线需要Powershell 7.0 RSAT 需要获取 AD 模块 Visual Studio Code 需要获取 powershell 7.0(在 win7 上)
到您阅读本文时,文件中的版本列表可能已过期。使用此网站 https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies 添加更新的 dotnet 条目。只是“DotNet4Builds”中的一堆关键值
如果在 CompromisedCheck.csv 中机器显示为 =0,则它的安全性已手动关闭,您应该指出是供应商这样做,还是可疑员工。
我希望这可以帮助搜索它的人搜索他们的业务。
<#
Script Name : Get-DotNetVersions_Tweaked.ps1
Description : This script reports the various .NET Framework versions installed on the local or a remote set of computers
Author : Original by Martin Schvartzman - Edited by Mark Purnell
Reference : https://msdn.microsoft.com/en-us/library/hh925568
#>
$ErrorActionPreference = "Continue”
import-module ActiveDirectory
$searchOU = "OU=OU LEVEL 1,OU=OU LEVEL 2,OU=MACHINES,OU=OUR LAPTOPS,DC=PUT,DC=MY,DC=DOMAIN,DC=CONTROLLER,DC=HERE,DC=OK"
$computerList = Get-ADComputer -searchbase $searchOU -Filter *
function Get-DotNetFrameworkVersion($computerList)
$dotNetter = @()
$compromisedCheck = @()
$dotNetRoot = 'SOFTWARE\Microsoft\.NETFramework'
$dotNetRegistry = 'SOFTWARE\Microsoft\NET Framework Setup\NDP'
$dotNet4Registry = 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'
$dotNet4Builds = @
'30319' = @ Version = [System.Version]'4.0'
'378389' = @ Version = [System.Version]'4.5'
'378675' = @ Version = [System.Version]'4.5.1' ; Comment = '(8.1/2012R2)'
'378758' = @ Version = [System.Version]'4.5.1' ; Comment = '(8/7 SP1/Vista SP2)'
'379893' = @ Version = [System.Version]'4.5.2'
'380042' = @ Version = [System.Version]'4.5' ; Comment = 'and later with KB3168275 rollup'
'393295' = @ Version = [System.Version]'4.6' ; Comment = '(Windows 10)'
'393297' = @ Version = [System.Version]'4.6' ; Comment = '(NON Windows 10)'
'394254' = @ Version = [System.Version]'4.6.1' ; Comment = '(Windows 10)'
'394271' = @ Version = [System.Version]'4.6.1' ; Comment = '(NON Windows 10)'
'394802' = @ Version = [System.Version]'4.6.2' ; Comment = '(Windows 10 Anniversary Update)'
'394806' = @ Version = [System.Version]'4.6.2' ; Comment = '(NON Windows 10)'
'460798' = @ Version = [System.Version]'4.7' ; Comment = '(Windows 10 Creators Update)'
'460805' = @ Version = [System.Version]'4.7' ; Comment = '(NON Windows 10)'
'461308' = @ Version = [System.Version]'4.7.1' ; Comment = '(Windows 10 Fall Creators Update)'
'461310' = @ Version = [System.Version]'4.7.1' ; Comment = '(NON Windows 10)'
'461808' = @ Version = [System.Version]'4.7.2' ; Comment = '(Windows 10 April & Winserver)'
'461814' = @ Version = [System.Version]'4.7.2' ; Comment = '(NON Windows 10)'
'528040' = @ Version = [System.Version]'4.8' ; Comment = '(Windows 10 May 2019 Update)'
'528049' = @ Version = [System.Version]'4.8' ; Comment = '(NON Windows 10)'
foreach($computerObject in $computerList)
$computerName = $computerObject.DNSHostName
write-host("PCName is " + $computerName)
if(test-connection -TargetName $computerName -Quiet -TimeOutSeconds 1 -count 2)
if($regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computerName))
$os = (Get-WMIObject win32_operatingsystem -ComputerName SPL305350).Name
if(!$?)
write-host("wim not available")
$dotNetter += New-Object -TypeName PSObject -Property @
'ComputerName' = $computerName
'OS' = "WIM not available"
'Build' = "WIM not available"
'Version' = "WIM not available"
'Comment' = "WIM not available"
else
if ($netRegKey = $regKey.OpenSubKey("$dotNetRegistry"))
foreach ($versionKeyName in $netRegKey.GetSubKeyNames())
if ($versionKeyName -match '^v[123]')
$versionKey = $netRegKey.OpenSubKey($versionKeyName)
$version = [System.Version]($versionKey.GetValue('Version', ''))
write-host("adding old dotnet")
$dotNetter += New-Object -TypeName PSObject -Property @
ComputerName = $computerName
OS = $os
Build = $version.Build
Version = $version
Comment = ''
if ($net4RegKey = $regKey.OpenSubKey("$dotNet4Registry"))
if(-not ($net4Release = $net4RegKey.GetValue('Release')))
$net4Release = 30319
write-host("adding new dotnet")
$dotNetter += New-Object -TypeName PSObject -Property @
'ComputerName' = $computerName
'OS' = $os
'Build' = $net4Release
'Version' = $dotNet4Builds["$net4Release"].Version
'Comment' = $dotNet4Builds["$net4Release"].Comment
if ($netRegKey = $regKey.OpenSubKey("$dotNetRoot"))
write-host("Checking for hacked keys")
foreach ($versionKeyName in $netRegKey.GetSubKeyNames())
if ($versionKeyName -match '^v[1234]')
$versionKey = $netRegKey.OpenSubKey($versionKeyName)
write-host("versionKeyName is" + $versionKeyName)
write-host('ASPNetEnforceViewStateMac = ' + $versionKey.GetValue('ASPNetEnforceViewStateMac', ''))
$compromisedCheck += New-Object -TypeName PSObject -Property @
'ComputerName' = $computerName
'version' = $versionKeyName
'compromisedCheck' = ('ASPNetEnforceViewStateMac = ' + $versionKey.GetValue('ASPNetEnforceViewStateMac', ''))
else
write-host("could not connect to machine")
$dotNetter += New-Object -TypeName PSObject -Property @
'ComputerName' = $computerName
'OS' = $os
'Build' = "Could not connect"
'Version' = "Could not connect"
'Comment' = "Could not connect"
$dotNetter | export-CSV c:\temp\DotNetVersions.csv
$compromisedCheck | export-CSV C:\temp\CompromisedCheck.csv
get-dotnetframeworkversion($computerList)
【讨论】:
【参考方案13】:大致思路如下:
在 .NET Framework 目录中获取名称匹配的容器的子项 模式v number dot number。按名称降序排列,取第一个对象, 并返回其 name 属性。
这是脚本:
(Get-ChildItem -Path $Env:windir\Microsoft.NET\Framework | Where-Object $_.PSIsContainer -eq $true | Where-Object $_.Name -match 'v\d\.\d' | Sort-Object -Property Name -Descending | Select-Object -First 1).Name
【讨论】:
我安装了 4.6.1 但你的脚本返回 v4.0.30319 这在我的机器上不起作用(我安装了 4.7.1)。它打印 v4.0.30319【参考方案14】:我会在 PowerShell 中尝试这个: 为我工作!
(Get-ItemProperty "HKLM:Software\Microsoft\NET Framework Setup\NDP\v4\Full").Version
【讨论】:
这并没有告诉你真相。那里会说版本号,例如当产品版本为 4.7.2 时为 4.7.03056【参考方案15】:如果您已在计算机上安装了 Visual Studio,则打开 Visual Studio 开发人员命令提示符并键入以下命令: 聪明的
它将列出该计算机上所有已安装的 .NET Framework 版本。
【讨论】:
此命令获取 CLR 版本,而不是 .NET Framework 版本 - 这是不同的。【参考方案16】:我不了解我的 PowerShell 语法,但我认为您可以致电 System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion()。这会将版本作为字符串返回(我认为类似于 v2.0.50727
)。
【讨论】:
对于当前执行的运行时,不一定是最新安装的。 对于 powershell,正确的语法是:[System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion()
,但它只返回 v4.0.30319,即使在我的情况下安装了 v4.6。
@matt 4.0.30319 是从 .Net Framework 4.0 到 .Net Framework 4.7.1 的 CLR 版本。所以你的 v4.6 框架实际上使用 4.0.30319 作为它的 CLR 版本。请注意,只有版本的修订部分是所有 .Net 框架之间的差异。另请参阅:.NET Framework Versions and Dependencies - Microsoft Docs
@walterlv - 谢谢你的链接。是的,我知道这一点。微软在这方面犯了一个大错误,远程连接到服务器并找出其中实际安装了哪个 .net 版本并不容易。另一个让管理员和开发人员头疼的问题。
这也可能有所帮助:Microsoft: How to determine versions and service pack levels of .NET Framework。它还显示了找出你的机器上究竟安装了什么变得多么复杂...... :-(【参考方案17】:
这是上一篇文章的派生,但在我的测试中获得了最新版本的 .net framework 4。
get-itemproperty -name version,release "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\FULL"
这将允许您调用远程机器的命令:
invoke-command -computername server01 -scriptblock get-itemproperty -name version,release "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\FULL" | select pscomputername,version,release
使用 ADModule 和命名约定前缀设置了这种可能性:
get-adcomputer -Filter 'name -like "*prefix*"' | % invoke-command -computername $_.name -scriptblock get-itemproperty -name version,release "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\FULL" | select pscomputername,version,release | ft
【讨论】:
以上是关于PowerShell 脚本返回机器上的 .NET Framework 版本?的主要内容,如果未能解决你的问题,请参考以下文章
Powershell - 运行位于远程机器上的脚本,该脚本反过来从网络共享访问文件
用于查看当前登录用户(域和机器)+ 状态(活动、空闲、离开)的 Powershell 脚本
Powershell:如何使用不同的用户名/密码映射网络驱动器