Skrypt PowerShell zwracający wersje of.NET Framework na maszynie?

Czym byłby skrypt PowerShell, aby zwrócić wersje. NET Framework na komputerze?

Moje pierwsze przypuszczenie to coś związanego z WMI. Jest coś lepszego?

Powinno być jednoliniowe, aby zwracać tylko najnowszą wersję dla każdej instalacji. net [na każdej linii].

Author: Peter Mortensen, 2010-08-15

13 answers

Jeśli masz zamiar użyć rejestru, musisz rekurencyjnie, aby uzyskać pełną wersję dla 4.X Framework. Wcześniejsze odpowiedzi zwracają zarówno numer główny w moim systemie dla. NET 3.0 (gdzie numery WCF i WPF, które są zagnieżdżone pod 3.0, są wyższe - nie mogę tego wyjaśnić), jak i nie zwracają niczego dla 4.0 ...

EDIT: dla. Net 4.5 i nowszych, to się nieco zmieniło, więc teraz jest ładny artykuł MSDN tutaj wyjaśniający, jak przekonwertować wydanie wartość do numeru wersji. Net, to totalny wrak pociągu: - (

To wygląda dobrze dla mnie (zauważ, że wypisuje oddzielne numery wersji dla WCF & WPF na 3.0. Nie wiem o co chodzi). Wyświetla również zarówno Client, jak i Full w wersji 4.0 (jeśli oba są zainstalowane):

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

Na podstawie artykułu MSDN można zbudować tabelę wyszukiwania i zwrócić numer wersji produktu marketingowego dla wydań po wydaniu 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

W rzeczywistości, ponieważ ciągle muszę update this answer, here ' s a script to generate the script above (with a little extra) from the markdown source for that web page. To prawdopodobnie pęknie w pewnym momencie, więc zachowuję aktualną kopię powyżej.

# 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 }}
"@
 281
Author: Jaykul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 19:56:40
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des                                  |
select -fi 1 -exp pschildname

Ta odpowiedź nie zwraca 4.5 jeśli jest zainstalowana. Odpowiedź poniżej od @Jaykul i używając recurse robi.

 26
Author: Jason Stangroome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 20:00:15
[environment]::Version

Daje przykład Version dla CLR używana jest bieżąca Kopia PSH (jak udokumentowano TUTAJ ).

 21
Author: Richard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-15 12:25:54

Poprawna składnia:

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

The GetSystemVersion funkcja zwraca łańcuch taki jak:

v2.0.50727        #PowerShell v2.0 in Win 7 SP1

Lub w ten sposób

v4.0.30319        #PowerShell v3.0 (Windows Management Framework 3.0) in Win 7 SP1

$PSVersionTable jest obiektem tylko do odczytu. Właściwość CLRVersion jest strukturyzowanym numerem wersji, takim jak:

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      30319  18444   
 12
Author: Desmond Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 14:21:48

Dodano obsługę v4.7.2 do skryptu:

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" }
      }
    }
}
 10
Author: AlexBar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 20:33:16

Znalazłem to poprzez uzupełnianie kart w powershell dla osx:

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

 6
Author: js2010,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 12:31:46

Nie ma niezawodnego sposobu, aby to zrobić dla wszystkich platform i architektur za pomocą prostego skryptu. Jeśli chcesz dowiedzieć się, jak to zrobić niezawodnie, zacznij od wpisu na bloguzaktualizowany przykładowy kod wykrywania. NET Framework, który bardziej dogłębnie sprawdza.

 4
Author: x0n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 20:01:52

Nieładnie. zdecydowanie nie ładnie:

ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer } | select -exp Name -l 1
To może, ale nie musi działać. Ale jeśli chodzi o najnowszą wersję, powinno to być dość wiarygodne, ponieważ istnieją zasadniczo puste foldery dla starych wersji (1.0, 1.1), ale nie nowsze – te pojawiają się dopiero po zainstalowaniu odpowiedniego frameworka. Mimo to, podejrzewam, że musi być lepszy sposób.
 2
Author: Joey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-15 13:43:18

Zobacz stronę skrypt do wyszukiwania, które wersje. NET są zainstalowane na zdalnych stacjach roboczych.

Skrypt może być przydatny do znalezienia wersji. NET dla wielu komputerów w sieci.

 2
Author: kalidoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 20:04:47

Ładne rozwiązanie

Spróbuj użyć do pobrania Moduł DotNetVersionLister (na podstawie informacji o rejestrze i niektórych tabelach wyszukiwania wersji na marketing).

Które byłyby użyte w ten sposób:

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

Lub w ten sposób, jeśli chcesz po prostu przetestować go pod kątem jakiegoś . 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

Ale nie zadziała (instalacja/import) np. z PS v2.0 (Win 7, Win Server 2010 standard) ze względu na niezgodność...

Motywacja do" dziedziczenia " funkcji poniżej

(możesz pominąć czytanie tego i użyć kodu poniżej)

Musieliśmy pracować z PS 2.0 na niektórych komputerach i nie mogliśmy zainstalować / zaimportować powyższego DotNetVersionLister .
Na innych maszynach chcieliśmy zaktualizować (z PS 2.0) do PS 5.1 (który z kolei potrzebuje . NET Framework >= 4.5 ) z pomocą dwóch firm-custom Install-DotnetLatestCompany i Install-PSLatestCompany.
Poradnik dla adminów ładnie w procesie instalacji/aktualizacji musielibyśmy określić wersję. NET w tych funkcjach na wszystkich istniejących maszynach i wersjach PS.
W ten sposób wykorzystaliśmy również poniższe funkcje, aby określić je bezpieczniej we wszystkich środowiskach...

Funkcje dla starszych środowisk PS (np. PS v2.0)

Tak więc poniższy kod i poniższe (wyodrębnione) przykłady użycia są przydatne tutaj (na podstawie innych odpowiedzi tutaj):

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 } }
}

Przykładowe użycie:

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
 0
Author: Andreas Dietrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-03 07:35:08

Nie jestem na mojej składni PowerShell, ale myślę, że można po prostu zadzwonić System.Runtime.InteropServices./ Align = "left" / GetSystemVersion () . Zwróci To wersję jako ciąg znaków (coś w rodzaju v2.0.50727, myślę).

 -1
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-02 17:49:46

Oto ogólna idea:

Pobieranie elementów potomnych w katalogu. NET Framework, które są kontenerami, których nazwy pasują wzór V Liczba kropka numer . Sortuj je po malejącej nazwie, weź pierwszy obiekt, i zwrócić jego nazwę własności.

Oto scenariusz:

(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
 -1
Author: doer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-20 09:50:00

Wypróbowałbym ten w PowerShell: Zadziałało na mnie!

(Get-ItemProperty "HKLM: Software \ Microsoft \ NET Framework Setup \ NDP \ V4 \ Full").Wersja

 -2
Author: G.B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-01 17:18:38