Сценарий PowerShell для возврата версий of.NET рамки на машине?



каким должен быть сценарий PowerShell для возврата версий .NET Framework на машине?



моя первая догадка-это что-то с участием WMI. Есть ли что-то лучше?



Он должен быть однострочным, чтобы возвращать только последнюю версию для каждой установки .NET [на каждой строке].

575   13  

13 ответов:

Если вы собираетесь использовать реестр, вы должны повторить для того, чтобы получить полную версию для 4.х рамках. Более ранние ответы возвращают корневой номер в моей системе для .NET 3.0 (где номера WCF и WPF, которые вложены под 3.0, выше-я не могу этого объяснить) и не возвращают ничего для 4.0 ...

EDIT: для .Net 4.5 и выше это снова немного изменилось, так что теперь есть хороший статья MSDN здесь объясняя, как преобразовать релиз значение для номера версии .Net, это полное крушение поезда: - (

Это выглядит правильно для меня (обратите внимание, что он выводит отдельные номера версий для WCF & WPF на 3.0. Я не знаю, что это). Он также выводит оба клиент и полное на 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'
}

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

на самом деле, поскольку я продолжаю обновлять этот ответ, вот сценарий для создания сценария выше (с небольшим добавлением) из источника markdown для этой веб-страницы. Это, вероятно, сломается в какой-то момент, поэтому я сохраняю текущую копию выше.

# 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)\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 }}
"@
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des                                  |
select -fi 1 -exp pschildname

этот ответ не возвращает 4.5, если он установлен. Ответ ниже от @Jaykul и с помощью recurse делает.

[environment]::Version

дает вам экземпляр Version для среды CLR используется текущая копия PSH (как описано здесь).

синтаксис:

[System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion()
#or
$PSVersionTable.CLRVersion

The 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   

добавлена поддержка V4.7. 2 для скрипта:

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" }    
        {$_ -gt 461814} { [Version]"Undocumented version (> 4.7.2), please update script" }
      }
    }
}

Я нашел это через завершение вкладки в powershell для osx:

[System.Runtime.InteropServices.RuntimeInformation]::get_FrameworkDescription() .NET Core 4.6.25009.03

нет надежного способа сделать это для всех платформ и архитектур с помощью простого скрипта. Если вы хотите узнать, как это сделать надежно, начните с сообщения в блоге обновленный пример кода обнаружения .NET Framework, который выполняет более глубокую проверку.

Не очень. наверняка не очень:

ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer } | select -exp Name -l 1

Это может или не может работать. Но что касается последней версии, это должно быть довольно надежным, так как есть по существу пустые папки для старых версий (1.0, 1.1), но не более новые – они появляются только после установки соответствующей платформы.

тем не менее, я подозреваю, что должен быть лучший способ.

обратитесь к странице скрипт для поиска, какие версии .NET установлены на удаленных рабочих станциях.

сценарий там может быть полезно найти версию .NET для нескольких машин в сети.

хорошее решение

попробуйте использовать загружаемые DotNetVersionLister модуль (на основе информации реестра и некоторой таблицы поиска версии для маркетинга).

который будет использоваться следующим образом:

PS> Get-DotNetVersion -LocalHost


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        :

    Script start time: 09/03/2018 09:21:18
    Script end time:   09/03/2018 09:21:19

Или вот так, если вы просто хотите проверить его для некоторых .NET framework > = 4.* :

PS> (Get-DotNetVersion -LocalHost).">=4.x"
  Script start time: 09/03/2018 09:25:55
  Script end time:   09/03/2018 09:25:55

4.5.2

но он не будет работать (установка/импорт), например, с ПС П2.0 (Win 7,Win Server 2010 стандартные) из-за несовместимости...

мотивация для функций "наследие" ниже

(вы можете пропустить это и использовать код ниже)

мы должны были работать с PS 2.0 на некоторых машинах и не удалось установить / импортировать выше DotNetVersionLister.
На других машинах мы хотели обновить (с PS 2.0) к PS 5.1 (который в turn needs .NET Framework > = 4.5) С помощью двух компаний-custom Install-DotnetLatestCompany и Install-PSLatestCompany.
Чтобы хорошо направлять администраторов в процессе установки/обновления, нам нужно было бы определить версию .NET в этих функциях на всех существующих машинах и версиях PS.
Таким образом, мы использовали также следующие функции, чтобы определить их более безопасно во всех средах...

функции для устаревших сред PS (например ПС П2.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

Я не в курсе синтаксиса PowerShell, но я думаю, что вы могли бы просто позвонить

вот общая идея:

получить дочерние элементы в каталоге .NET Framework, которые являются контейнерами, имена которых совпадают шаблон v номер точка номер. Отсортируйте их по убыванию имени, возьмите первый объект, и вернуть его свойство 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

Я бы попробовал это в PowerShell: Работал на меня!

(Get-ItemProperty "HKLM: Software\Microsoft\NET Framework Setup\NDP\v4\Full").Версия

Comments

    Ничего не найдено.