PowerShell script для возврата версий .NET Framework на машину?
Каким образом PowerShell script должен возвращать версии .NET Framework на машине?
Мое первое предположение - это что-то, что связано с WMI. Есть что-то лучше?
Он должен быть однострочным, чтобы возвращать только последнюю версию для каждой установки .NET [в каждой строке].
Ответы
Ответ 1
Если вы собираетесь использовать реестр, вам нужно выполнить рекурсию, чтобы получить полную версию для 4.x Framework. Предыдущие ответы оба возвращают номер root в моей системе для .NET 3.0 (где номера WCF и WPF, вложенные в 3.0, выше - я не могу этого объяснить) и не возвращают ничего для 4.0..
ОБНОВЛЕНИЕ: Для .Net 4.5 и выше, это снова немного изменилось, так что теперь есть хорошая статья MSDN здесь, объясняющая, как преобразовать значение Release в номер версии .Net, это полное крушение поезда :-(
Это выглядит правильно для меня (обратите внимание, что он выводит отдельные номера версий для WCF и WPF на 3.0. Я не знаю, о чем это). Он также выводит как Client, так и Full на 4.0 (если они установлены):
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}'} |
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-Oject 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)\p{L}'} |
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 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)\p{L}'} |
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 }}
"@
Ответ 2
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des |
select -fi 1 -exp pschildname
Этот ответ не возвращает 4.5, если он установлен. Ответ ниже от @Jaykul и использование recurse.
Ответ 3
[environment]::Version
Дает вам экземпляр Version
для CLR, который использует текущая копия PSH (как описано здесь).
Ответ 4
Добавлена поддержка v4.8 для скрипта:
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?![SW])\p{L}'} |
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" }
}
}
}
Ответ 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
Ответ 6
Я нашел это через вкладку завершения в powershell для osx:
[System.Runtime.InteropServices.RuntimeInformation]::get_FrameworkDescription()
.NET Core 4.6.25009.03
Ответ 7
Нет надежного способа сделать это для всех платформ и архитектур, используя простой script. Если вы хотите узнать, как сделать это надежно, начните с сообщения в блоге Обновленный образец кода обнаружения .NET Framework, который делает более глубокую проверку.
Ответ 8
Не очень. Определенно не красиво:
ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer } | select -exp Name -l 1
Это может работать или не работать. Но, что касается последней версии, это должно быть довольно надежным, поскольку по умолчанию существуют пустые папки для старых версий (1.0, 1.1), но не более новые - они появляются только после установки соответствующей структуры.
Тем не менее, я подозреваю, что должен быть лучший способ.
Ответ 9
Обратитесь к странице Script для определения того, какие версии .NET установлены на удаленных рабочих станциях.
script может оказаться полезным найти версию .NET для нескольких компьютеров в сети.
Ответ 10
Хорошее решение
Попробуйте использовать загружаемый модуль DotNetVersionLister (на основе информации реестра и таблицы поиска версий от маркетинговой версии).
Который будет использоваться так:
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://stackoverflow.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://stackoverflow.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)\p{L}'} |
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
Ответ 11
Если вы установили Visual Studio на свой компьютер, откройте командную строку разработчика Visual Studio и введите следующую команду:
clrver
В нем будут перечислены все установленные версии .NET Framework на этом компьютере.
Ответ 12
Здесь общая идея:
Получить дочерние элементы в каталоге .NET Framework, которые являются контейнерами, имена которых соответствуют
образец v число число число. Сортируйте их по нисходящему имени, возьмите первый объект,
и вернуть его свойство name.
Здесь script:
(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
Ответ 13
Я бы попробовал это в PowerShell: Работал для меня!
(Get-ItemProperty "HKLM: Программное обеспечение \Microsoft\NET Framework Setup\NDP\v4\Full"). Версия
Ответ 14
Я не использую синтаксис PowerShell, но я думаю, вы могли бы просто вызвать System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(). Это вернет версию в виде строки (что-то вроде v2.0.50727
, я думаю).