Skrypt PowerShell do zwracania wersji .NET Framework na komputerze?

182

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

Moje pierwsze przypuszczenie dotyczy WMI. Czy jest coś lepszego?

Powinno być jedno-liniowe, aby zwracać tylko najnowszą wersję dla każdej instalacji platformy .NET [w każdym wierszu].

MattUebel
źródło
7
Maszyna może (i będzie) mieć wiele wersji Fx. Jak chcesz sobie z tym poradzić? A potem jest bałagan Fx2 .. Fx3.5SP1. Jaką wersję chcesz usłyszeć?
Henk Holterman
Przypuszczam, że konieczne będzie zwrócenie pełnego numeru wersji dla każdej instalacji.
MattUebel,
1
Czy nie ma na to sposobu za pomocą WMI?
Mark Richman
Prosiłeś o PowerShell, zrobiłem coś dla C # (aplikacja konsolowa). Jeśli jesteś zainteresowany, oto on ...
Matt
To naprawdę niewiarygodne, że nie ma czegoś takiego:asp.net -v
Altimus Prime

Odpowiedzi:

354

Jeśli zamierzasz korzystać z rejestru, musisz się powtórzyć, aby uzyskać pełną wersję dla 4.x Framework. Wcześniejsze odpowiedzi zarówno zwracają numer główny w moim systemie dla .NET 3.0 (gdzie numery WCF i WPF, które są zagnieżdżone w 3.0, są wyższe - nie mogę tego wyjaśnić), i nie zwracają niczego dla 4.0. .

EDYCJA: W przypadku wersji .Net 4.5 i nowszych sytuacja nieco się zmieniła, więc jest tutaj ładny artykuł MSDN wyjaśniający, jak przekonwertować wartość Release na numer wersji .Net, jest to całkowity wrak pociągu :-(

To wygląda mi dobrze (zauważ, że wyświetla osobne numery wersji dla WCF i WPF w 3.0. Nie wiem o co chodzi). Wyprowadza także zarówno Klient, jak i Pełny w wersji 4.0 (jeśli masz je obie 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 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)\p{L}'} |
  Select-Object @{name = ".NET Framework"; expression = {$_.PSChildName}}, 
@{name = "Product"; expression = {$Lookup[$_.Release]}}, 
Version, Release

W rzeczywistości, ponieważ wciąż muszę aktualizować tę odpowiedź, oto skrypt do wygenerowania powyższego skryptu (z dodatkowymi dodatkami) ze źródła Markdown dla tej strony internetowej. Prawdopodobnie w pewnym momencie się zepsuje, więc trzymam obecną 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 }}
"@
Jaykul
źródło
Tego właśnie szukam, ale trudno mi się skupić na tym, co dokładnie robi. Z tego, co rozumiem, wychodzi do rejestru NDP i rekurencyjnie przeszukuje każdy folder, który pasuje do '^(?!S)\p{L}'wyrażenia regularnego, i otrzymuje informacje o wersji i wydaniu. Czym dokładnie jest to wyrażenie regularne, które się kwalifikuje?
Johnrad,
2
@Johnrad PSChildNameto nazwa liścia klucza rejestru. \p{L}to dowolny znak w kategorii „litera” w Unicode. (?!S)jest negatywnym rozejrzeniem się i ^jest początkiem ciągu. Więc musi zaczynać się od litery innej niż S. Więc jeśli weźmiesz pod uwagę tylko ASCII, jest to to samo co $_.PSChildName -cmatch '^[A-RT-Za-z]'(zwróć uwagę na -cmatch). Znajduje więc klucze, których nazwa zaczyna się na literę inną niż S. Nie mam pojęcia, dlaczego miałbyś przejmować się nie-ASCII, jeśli odfiltrowujesz nazwy zaczynające się od S... Zdecydowanie, ponieważ jest to tak mylące.
jpmc26
1
Teraz jestem bardziej zdezorientowany co do cholery Get-ItemProperty -name Version,Release -EA 0robi. Wiem, że -EA 0jest taki sam -ErrorAction SilentlyContinue, ale jaki efekt miałby Get-ItemProperty -name Version,Releaseprzy przekazywaniu do niego wszystkich wyników? Wydaje się, że nie usuwa żadnych zmiennych z obiektu, ponieważ inne są używane w późniejszych poleceniach potoku. Czy to działa, występuje błąd, gdy w kluczu brakuje nazwy Versionlub Release, a następnie przekazuje obiekty, w których się udało, do następnego polecenia w potoku?
jpmc26,
3
Get-ChildItem zwraca WSZYSTKIE podklucze rejestru (podfoldery, jeśli chcesz). Get-ItemProperty zwraca wartości (w szczególności: „Wersja” i „Wydanie”) - ignorujemy błędy, ponieważ nie dbamy o foldery, które nie mają tych wartości. Tak, w zasadzie znajdujemy KAŻDY podfolder, a następnie szukamy wersji lub wydania (wszystkie foldery bez jednego lub obu z nich są ignorowane).
Jaykul,
3
Niesamowite! Zmodyfikowałem tylko (?!S)klauzulę, aby (?![SW])dodatkowo wykluczać wpisy „Windows *”. Można to również zrobić, (?=[vCF])ponieważ jedynymi kluczami, na których nam naprawdę zależy, są katalogi główne wersji oraz klucze „Full” i „Client” dla .NET 4.0+. ;)
Chiramisu,
27
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 z @Jaykul i używanie rekurencji.

Jason Stangroome
źródło
5
gci 'HKLM: \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP' | sort pschildname -des | foreach-object {$ _. name; $ _. GetValue („Wersja”);}
MattUebel
dla mnie odpowiedź jest teraz na górze, więc tutaj link do niej :-): stackoverflow.com/a/3495491/1747983
Tilo
1
Po zainstalowaniu .NET 4.7.1 w systemie Windows 10 nadal zwraca v4.0.
Matt
24

Dodano obsługę skryptu 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" }
      }
    }
}
AlexBar
źródło
21
[environment]::Version

Daje instancję VersionCLR, której używa bieżąca kopia PSH (zgodnie z dokumentacją tutaj ).

Richard
źródło
3
Mam zainstalowaną platformę .NET 4, ale PowerShell będzie używać tylko środowiska wykonawczego 2.0. To tak naprawdę nie jest pomocne w tym przypadku.
Joey
@Johannes: Zobacz komentarz do swojego Q, musisz wyraźnie powiedzieć, czego chcesz.
Richard
9
W przypadku programu Powershell 2.0 można również użyć $PSVersionTabledo znalezienia wersji programu CLR PowerShell.
Keith Hill
6
Co powiesz na wyższe wersje? Mam teraz .NET 4.7.1 , a skrypt zawsze zwraca 4.0.30319 Rev. 42000.
Matt
@Matt musisz przetłumaczyć mniejszą część wersji ... i pamiętaj, że w zależności od tego, co jest ustawione w konfiguracji Powershell, może nie używać najnowszej wersji mniejszej / łatki.
Richard,
13

Prawidłowa składnia:

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

GetSystemVersionFunkcja zwraca ciąg znaków takich jak to:

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

lub tak

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

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

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      30319  18444   
Desmond Lee
źródło
1
Próbowałem tego na Win8, nic nie zwraca. W systemie Windows 7 zwraca 2, gdy 4.5.1 jest już zainstalowany. Nie wiem, dlaczego nie jest to przydatne na nowych platformach. Na Win Sesverver 2008 działa.
maks.
Pierwsza opcja działa w moim 64-bitowym środowisku Windows 8. Druga opcja działa, ale myślę, że pokazuje ona tylko wersję .NET, w której działa bieżąca instancja programu PowerShell, która jest prawie zawsze najnowsza. (Edytuj: Może oboje tak.)
Vimes
to samo tutaj. w systemie Windows 7 mam zarówno .net 2.0, jak i 4.0, ale polecenie pokazuje tylko v2.0.50727. Użyj podejścia Jaykul.
maks.
Wersja Clr nie równa się wersji ramowej, wszystkie ramy 4+ są oparte na 4 clr
janv8000 15.04.16
Co powiesz na wyższe wersje? Mam teraz .NET 4.7.1 , a skrypt zawsze zwraca 4.0.30319 Rev. 42000.
Matt
11

Znalazłem to poprzez uzupełnienie tabulacji w PowerShell dla OSX:

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

js2010
źródło
1
Tak, zwraca .NET Framework 4.7.2558.0 - ale jak odróżnić 4.7 z 4.7.1 (mam 4.7.1 na moim komputerze z systemem Windows 10).
Matt
1
[version]([Runtime.InteropServices.RuntimeInformation]::FrameworkDescription -replace '^.[^\d.]*','')
Rabash
2

Niezłe rozwiązanie

Spróbuj użyć modułu DotNetVersionLister do pobrania (na podstawie informacji z rejestru i tabeli wyszukiwania wersji od wersji marketingowej).

Który byłby użyty w ten sposób:

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        :

Lub w ten sposób, jeśli chcesz go przetestować pod kątem .NET Framework> = 4. * :

PS> (Get-DotNetVersion -LocalHost -nosummary).">=4.x"
4.5.2

Ale to nie będzie działać (instalacja / import) np. Z PS v2.0 ( Win 7 , standard Win Server 2010 ) z powodu niezgodności ...

Motywacja do „starszych” funkcji poniżej

(Możesz pominąć czytanie 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 komputerach chcieliśmy zaktualizować (z PS 2.0 ) do PS 5.1 (co z kolei wymaga .NET Framework> = 4.5 ) przy pomocy dwóch niestandardowych programów Install-DotnetLatestCompanyi Install-PSLatestCompany.
Aby ładnie przeprowadzić administratorów przez proces instalacji / aktualizacji, musielibyśmy określić wersję .NET w tych funkcjach na wszystkich istniejących komputerach i wersjach PS.
Dlatego użyliśmy również poniższych funkcji, aby określić je bezpieczniej we wszystkich środowiskach ...

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

Zatem 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
Andreas Dietrich
źródło
Aby zobaczyć czasy, użyj(Get-DotNetVersion -LocalHost -nosummary).">=4.x"
ΩmegaMan
@ ΩmegaMan: thx - zaktualizowałem twoją dobrą rekomendację w odpowiedzi powyżej :)
Andreas Dietrich
1

Nie ładna Zdecydowanie nie ładna:

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

To może, ale nie musi działać. Jednak w przypadku najnowszej wersji powinno to być dość niezawodne, ponieważ są 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.

Joey
źródło
Musisz trochę przefiltrować, „V [.0-9] +” powinno ograniczyć dopasowanie do folderów .NET (mam tam inne foldery). A potem sprawdź, czy jest prawdziwa instalacja ... WMI na zainstalowanych komponentach może być łatwiejsze.
Richard
Hm, racja ... na tym komputerze jest też kilka innych folderów - miałem tylko kilka innych plików na innym komputerze. Cała ta odpowiedź była jednak raczej przypadkiem „działa dla mnie”. Jestem pewien, że istnieje wiarygodny i zamierzony sposób na uzyskanie tych informacji.
Joey
6
psake (narzędzie do budowania automatyzacji) przyjmuje podobne podejście i używa go z powodzeniem (a przynajmniej nikt go nie zmienił z powodu problemu). Ale to prawda, że ​​nie potrzebują pełnej wersji frameworka ... Dla mojego komputera jest to coraz bliżej:ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer -and $_.Name -match '^v\d.[\d\.]+' } | % { $_.Name.TrimStart('v') }
stej
Ze wszystkich linijek w odpowiedzi, ta dostarczona przez stej jest najczystsza i działa zgodnie z oczekiwaniami. Gdyby to była odpowiedź, głosowałbym za nią.
Bratch
Niestety nie jest wiarygodny. Mam teraz .NET 4.7.1 , a skrypt zawsze zwraca v4.0.30319.
Matt
0

Jeśli masz zainstalowany program Visual Studio na swoim komputerze, otwórz wiersz polecenia programu Visual Studio Developer i wpisz następujące polecenie: clrver

Wyświetli listę wszystkich zainstalowanych wersji .NET Framework na tym komputerze.

Abdul Rauf
źródło
To polecenie pobiera wersję CLR, a nie wersję .NET Framework - która jest inna.
user11909
0

Oto moje zdanie na temat tego pytania zgodnie z dokumentacją msft :

$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.' }
    }
)"

Ten przykład działa ze wszystkimi wersjami PowerShell i będzie działał bez końca, ponieważ 4.8 jest ostatnią wersją .NET Framework.

Maksymilian Burszley
źródło
-1

Oto ogólny pomysł:

Pobierz elementy podrzędne w katalogu .NET Framework, które są kontenerami, których nazwy pasują do wzorca v numer kropki numer . Posortuj je według malejącej nazwy, weź pierwszy obiekt i zwróć jego właściwość name.

Oto skrypt:

(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
sprawca
źródło
Mam zainstalowaną wersję 4.6.1, ale skrypt zwraca v4.0.30319
rob
To nie działa na moim komputerze (mam zainstalowaną wersję 4.7.1). Drukuje v4.0.30319
Matt
-1

Chciałbym spróbować tego w PowerShell: Pracowałem dla mnie!

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

GB
źródło
To nie mówi prawdy. Tam będzie podany numer wersji, na przykład 4.7.03056, gdy wersja produktu to 4.7.2
Jaykul,
-2

Nie jestem przy mojej składni PowerShell, ale myślę, że możesz po prostu wywołać System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion () . Zwróci to wersję jako ciąg znaków (coś, jak v2.0.50727myślę).

Andy
źródło
2
W przypadku aktualnie wykonywanego środowiska uruchomieniowego niekoniecznie jest to najnowszy zainstalowany.
Joey
W przypadku PowerShell poprawna składnia to [System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion():, ale zwraca tylko v4.0.30319, mimo że v4.6 jest zainstalowane w moim przypadku.
Matt
@matt 4.0.30319 to wersja CLR od .Net Framework 4.0 do .Net Framework 4.7.1. Tak więc środowisko v4.6 faktycznie używa wersji 4.0.30319 jako swojej wersji CLR. Zauważ, że tylko część Wersja wersji jest różnicą między wszystkimi frameworkami .Net. Zobacz też: Wersje i zależności platformy .NET Framework - Dokumenty Microsoft
walterlv
@walterlv - Dziękujemy za link. Tak, jestem tego świadomy. Microsoft popełnił duży błąd, nie jest łatwo zdalnie połączyć się z serwerem i dowiedzieć się, która wersja .net jest tam faktycznie zainstalowana. Kolejny duży ból głowy dla administratorów i programistów.
Matt
Może to również pomóc: Microsoft: Jak ustalić wersje i poziomy dodatków Service Pack .NET Framework . Pokazuje także, jak skomplikowane stało się ustalenie, co dokładnie jest zainstalowane na twoim komputerze ... :-(
Matt
-2

Jest to pochodna poprzedniego postu, ale w moich testach otrzymuję najnowszą wersję .NET Framework 4.

get-itemproperty -name version,release "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\FULL"

Który pozwoli ci na wywołanie polecenia na zdalnym komputerze:

invoke-command -computername server01 -scriptblock {get-itemproperty -name version,release "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\FULL" | select pscomputername,version,release} 

Który ustawia tę możliwość z ADModule i prefiksem konwencji nazewnictwa:

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
Bill Curtis
źródło