สคริปต์ PowerShell เพื่อส่งคืน. NET Framework รุ่นบนเครื่อง?


182

สคริปต์ PowerShell จะส่งคืนเวอร์ชันใด ๆ ของ. NET Framework บนเครื่อง

การเดาครั้งแรกของฉันคือสิ่งที่เกี่ยวข้องกับ WMI มีอะไรที่ดีกว่านี้ไหม?

ควรเป็นหนึ่งซับเพื่อส่งคืนเฉพาะเวอร์ชันล่าสุดสำหรับการติดตั้ง. NET แต่ละครั้งในแต่ละบรรทัด


7
เครื่องสามารถ (และจะ) มีFx หลายรุ่น คุณต้องการจัดการกับสิ่งนั้นอย่างไร แล้วมี Fx2 .. Fx3.5SP1 ระเบียบ คุณต้องการได้ยินรุ่นใด
Henk Holterman

ฉันคิดว่ามันจำเป็นต้องส่งคืนหมายเลขเวอร์ชันเต็มสำหรับการติดตั้งแต่ละครั้ง
MattUebel

1
ไม่มีวิธีการทำเช่นนี้ผ่าน WMI หรือไม่
Mark Richman

คุณขอ PowerShell ฉันทำบางสิ่งบางอย่างสำหรับ C # (แอปพลิเคชันคอนโซล) หากคุณสนใจที่นี่มันคือ ...
แมตต์

เป็นเรื่องที่น่าเหลือเชื่อจริงๆที่ไม่มีสิ่งใดเหมือน:asp.net -v
23419 Altimus Prime

คำตอบ:


354

หากคุณกำลังจะใช้รีจิสตรีคุณจะต้องรับเงินคืนเพื่อให้ได้เวอร์ชันเต็มสำหรับ 4.x Framework คำตอบก่อนหน้านี้ทั้งคืนหมายเลขรูทบนระบบของฉันสำหรับ. NET 3.0 (โดยที่หมายเลข WCF และ WPF ซึ่งซ้อนอยู่ภายใต้ 3.0 จะสูงกว่า - ฉันไม่สามารถอธิบายได้) และไม่สามารถส่งคืนสิ่งใดสำหรับ 4.0 .

แก้ไข: สำหรับ. Net 4.5 ขึ้นไปการเปลี่ยนแปลงนี้เล็กน้อยอีกครั้งดังนั้นขณะนี้มีบทความ MSDN ที่ดีที่นี่อธิบายวิธีการแปลงค่าReleaseเป็นหมายเลข. 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'
    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

ในความเป็นจริงเนื่องจากฉันต้องอัปเดตคำตอบนี้ต่อไปนี้เป็นสคริปต์เพื่อสร้างสคริปต์ด้านบน (มีเพิ่มเล็กน้อย) จากแหล่งมาร์กอัปสำหรับหน้าเว็บนั้น นี่อาจจะแตกในบางจุดดังนั้นฉันเก็บสำเนาปัจจุบันข้างต้น

# 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 }}
"@

นี่คือสิ่งที่ฉันกำลังมองหาเช่นกัน แต่ฉันมีเวลาที่ยากลำบากใจของฉันรอบสิ่งที่สิ่งนี้จะทำ จากสิ่งที่ฉันเข้าใจมันกำลังออกไปยังรีจิสทรีของ NDP และทำการค้นหาซ้ำในแต่ละโฟลเดอร์ที่เหมาะกับ'^(?!S)\p{L}'regex และรับข้อมูล Version และ Release นิพจน์ทั่วไปนั้นพยายามทำคุณสมบัติอะไร
Johnrad

2
@Johnrad PSChildNameเป็นชื่อลีฟของคีย์รีจิสตรี \p{L}เป็นอักขระใด ๆ ในหมวดหมู่ "จดหมาย" ของ Unicode (?!S)เป็นลบมองไปรอบ ๆ และ^เป็นจุดเริ่มต้นของสตริง Sดังนั้นจึงมีการเริ่มต้นด้วยตัวอักษรอื่นที่ไม่ใช่ ดังนั้นหากคุณพิจารณาเฉพาะ ASCII จะเป็นเช่นเดียวกับ$_.PSChildName -cmatch '^[A-RT-Za-z]'(หมายเหตุ-cmatch) Sดังนั้นจึงพบว่ากุญแจที่ชื่อขึ้นต้นด้วยตัวอักษรอื่นที่ไม่ใช่ ฉันไม่รู้ว่าทำไมคุณถึงสนใจว่าไม่ใช่ ASCII หากคุณกำลังกรองชื่อที่ขึ้นต้นด้วยS... แน่นอนว่าคุณกำลังสับสนอยู่
jpmc26

1
ตอนนี้ฉันสับสนมากขึ้นเกี่ยวกับสิ่งที่ห่าGet-ItemProperty -name Version,Release -EA 0ทำ ฉันรู้ว่า-EA 0เหมือนกัน-ErrorAction SilentlyContinueแต่จะGet-ItemProperty -name Version,Releaseมีผลกระทบอะไรบ้างเมื่อส่งผลลัพธ์ทั้งหมดให้กับมัน ดูเหมือนจะไม่ตัดตัวแปรใด ๆ ออกจากวัตถุเนื่องจากมีการใช้คำสั่งอื่น ๆ ในภายหลังในไปป์ไลน์ มันทำงานเกิดข้อผิดพลาดเมื่อไม่มีชื่อVersionหรือReleaseหายไปจากคีย์แล้วส่งวัตถุที่สำเร็จไปยังคำสั่งถัดไปในไปป์ไลน์หรือไม่
jpmc26

3
Get-ChildItem ส่งคืนคีย์ย่อยของรีจิสทรีทั้งหมด (โฟลเดอร์ย่อยหากคุณต้องการ) Get-ItemProperty คืนค่า (โดยเฉพาะ: "เวอร์ชั่น" และ "ปล่อย") - เราไม่สนใจข้อผิดพลาดเพราะเราไม่สนใจโฟลเดอร์ที่ไม่มีค่าเหล่านั้น ใช่แล้วโดยทั่วไปเราพบโฟลเดอร์ย่อยทุกแห่งแล้วมองหา Version หรือ Release (โฟลเดอร์ใด ๆ ที่ไม่มีหนึ่งหรือทั้งสองจะถูกละเว้น)
Jaykul

3
! น่ากลัว ฉันแก้ไขเฉพาะ(?!S)ข้อเพื่อ(?![SW])ยกเว้นรายการ "Windows *" เพิ่มเติม นอกจากนี้ยังสามารถทำได้(?=[vCF])เนื่องจากมีเพียงคีย์เดียวที่เราสนใจคือรูทเวอร์ชันและคีย์ "เต็ม" และ "ไคลเอนต์" สำหรับ. NET 4.0+ ;)
Chiramisu

27
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des                                  |
select -fi 1 -exp pschildname

คำตอบนี้จะไม่ส่งคืน 4.5 หากติดตั้งไว้ คำตอบด้านล่างจาก @Jaykul และการใช้การเรียกเก็บเงินคืนจะทำอย่างไร


5
gci 'HKLM: \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP' | จัดเรียง pschildname -des | foreach-object {$ _. name; $ _. GetValue ("Version");}
MattUebel

สำหรับฉันคำตอบคือตอนนี้อยู่ด้านบนดังนั้นที่นี่ลิงค์ไป :-): stackoverflow.com/a/3495491/1747983
Tilo

1
หลังจากติดตั้ง. NET 4.7.1 บน Windows 10 แล้วยังคงส่งคืน v4.0
แมตต์

24

เพิ่มการรองรับ 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" }
      }
    }
}

21
[environment]::Version

ให้อินสแตนซ์Versionสำหรับ CLR ให้คุณใช้สำเนาปัจจุบันของ PSH (ตามที่ระบุไว้ที่นี่ )


3
ฉันติดตั้ง. NET 4 ไว้แล้ว แต่ PowerShell จะใช้งานรันไทม์ 2.0 เท่านั้น ดังนั้นนี่ไม่ใช่ความช่วยเหลือจริงๆที่นี่
Joey

@Johannes: ดูความคิดเห็นใน Q ของคุณคุณจะต้องชัดเจนเกี่ยวกับสิ่งที่คุณต้องการ
ริชาร์ด

9
สำหรับ Powershell 2.0 คุณสามารถใช้$PSVersionTableเพื่อค้นหารุ่นของ CLR PowerShell ที่กำลังทำงานอยู่
Keith Hill

6
แล้วรุ่นที่สูงกว่าล่ะ ฉันมี. NET 4.7.1แล้วและสคริปต์จะส่งคืน 4.0.30319 Rev. 42000 เสมอ
Matt

@Matt คุณจะต้องแปลส่วนย่อยของรุ่น ... และโปรดทราบว่าขึ้นอยู่กับสิ่งที่ตั้งค่าไว้ในการตั้งค่าของ Powershell อาจไม่ได้ใช้เวอร์ชันรอง / แพทช์ล่าสุด
ริชาร์ด

13

ไวยากรณ์ที่ถูกต้อง:

[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   

1
ฉันลองมันใน win8 มันไม่ได้ผลอะไรเลย บน windows 7 จะส่งคืน 2 ขณะที่ติดตั้ง 4.5.1 ไว้แล้ว ฉันไม่รู้ว่าทำไมจึงไม่สามารถใช้งานได้บนแพลตฟอร์มใหม่ ใน win sesrver 2008 มันใช้งานได้
สูงสุด

ตัวเลือกแรกทำงานบนสภาพแวดล้อม Windows 8 ของฉันแบบ 64 บิต ตัวเลือกที่สองใช้งานได้ แต่ฉันคิดว่าเพิ่งแสดงรุ่น. NET ที่อินสแตนซ์ปัจจุบันของ PowerShell กำลังทำงานซึ่งเกือบจะเป็นเวอร์ชั่นล่าสุดเสมอ (แก้ไข: บางทีพวกเขาทั้งคู่ทำ)
Vimes

กันที่นี่ บน windows 7 ฉันมีทั้ง. net 2.0 และ 4.0 แต่คำสั่งแสดงเฉพาะ v2.0.50727 ใช้แนวทางของ Jaykul
สูงสุด

เวอร์ชัน Clr ไม่เท่ากับเวอร์ชันของเฟรมเวิร์ก 4+ เฟรมเวิร์กทั้งหมดขึ้นอยู่กับ 4 clr
janv8000

แล้วรุ่นที่สูงกว่าล่ะ ฉันมี. NET 4.7.1แล้วและสคริปต์จะส่งคืน 4.0.30319 Rev. 42000 เสมอ
Matt

11

ฉันพบสิ่งนี้ผ่านการทำให้แท็บเสร็จสมบูรณ์ใน powershell สำหรับ osx:

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


1
ใช่มันส่งคืน. NET Framework 4.7.2558.0 - แต่จะแยกความแตกต่าง 4.7 จาก 4.7.1 ได้อย่างไร (ฉันมี 4.7.1 บนเครื่อง Windows 10 ของฉัน)
แมตต์

1
[version]([Runtime.InteropServices.RuntimeInformation]::FrameworkDescription -replace '^.[^\d.]*','')
Rabash

3

ไม่มีวิธีที่เชื่อถือได้สำหรับแพลตฟอร์มและสถาปัตยกรรมทั้งหมดโดยใช้สคริปต์อย่างง่าย ถ้าคุณต้องการเรียนรู้วิธีการที่เชื่อถือได้ให้เริ่มที่โพสต์บล็อกตัวอย่างรหัสตรวจจับ. NET Frameworkที่ทำการตรวจสอบในเชิงลึกมากขึ้น


2

อ้างถึงหน้าสคริปต์สำหรับการค้นหารุ่น NET ที่ติดตั้งบนเวิร์กสเตชันระยะไกลมีการติดตั้งบนเวิร์กสเตชันระยะไกล

สคริปต์อาจมีประโยชน์ในการค้นหาเวอร์ชัน. NET ของหลาย ๆ เครื่องบนเครือข่าย


2

ทางออกที่ดี

ลองใช้โมดูล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 Frameworkบางตัว> = 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 เพื่อให้คำแนะนำแก่ผู้ดูแลระบบผ่านกระบวนการติดตั้ง / อัปเดตเราจะต้องพิจารณารุ่น. NET ในฟังก์ชั่นเหล่านี้ในทุกเครื่องและรุ่น PS ที่มีอยู่ ดังนั้นเราจึงใช้ฟังก์ชั่นด้านล่างเพื่อกำหนดความปลอดภัยในทุกสภาพแวดล้อม ...Install-PSLatestCompany

ฟังก์ชั่นสำหรับสภาพแวดล้อม 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

หากไม่เห็นเวลาที่กำหนดให้ใช้(Get-DotNetVersion -LocalHost -nosummary).">=4.x"
ΩmegaMan

@ ΩmegaMan: ขอบคุณ - อัพเดทคำแนะนำที่ดีของคุณในคำตอบข้างต้น :)
Andreas Dietrich

1

ไม่สวย. ไม่สวยแน่นอน :

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

สิ่งนี้อาจใช้งานได้หรือไม่ แต่สำหรับเวอร์ชั่นล่าสุดนั้นน่าจะน่าเชื่อถือเพราะมีโฟลเดอร์ว่างสำหรับเวอร์ชั่นเก่า (1.0, 1.1) แต่ไม่ใช่โฟลเดอร์ที่ใหม่กว่า - โฟลเดอร์เหล่านั้นจะปรากฏเมื่อติดตั้งเฟรมเวิร์กที่เหมาะสมเท่านั้น

ถึงกระนั้นฉันสงสัยว่าจะต้องมีวิธีที่ดีกว่า


คุณต้องกรองเพิ่มอีกเล็กน้อย "V [.0-9] +" ควร จำกัด การจับคู่กับโฟลเดอร์. NET (ฉันมีโฟลเดอร์อื่นอยู่บ้าง) และจากนั้นตรวจสอบว่ามีการติดตั้งจริง ... WMI บนส่วนประกอบที่ติดตั้งอาจจะง่ายกว่า
ริชาร์ด

อืมใช่แล้ว ... บนเครื่องนี้มีโฟลเดอร์อื่นอยู่สองสามอันด้วย - ข้ามีไฟล์อื่น ๆ อยู่ในเครื่องอื่น คำตอบทั้งหมดนี้เป็นเรื่องของ»ทำงานให้ฉัน«มากกว่า ฉันแน่ใจว่ามีวิธีที่เชื่อถือได้และตั้งใจในการรับข้อมูลนั้น
Joey

6
psake (เครื่องมือสร้างอัตโนมัติ) ใช้วิธีการที่คล้ายกันและใช้งานได้สำเร็จ (หรืออย่างน้อยก็ไม่มีใครเปลี่ยนแปลงเพราะปัญหา) แต่มันเป็นความจริงที่ว่าพวกเขาไม่จำเป็นรุ่นกรอบเต็ม ... สำหรับคอมพิวเตอร์ของฉันได้ใกล้ชิดนี้:ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer -and $_.Name -match '^v\d.[\d\.]+' } | % { $_.Name.TrimStart('v') }
stej

จากหนึ่งใน liners ในคำตอบหนึ่งที่จัดทำโดย stej เป็นที่สะอาดและทำงานตามที่คาดไว้ ถ้าเป็นคำตอบฉันจะลงคะแนนให้
Bratch

น่าเสียดายที่มันไม่น่าเชื่อถือ ฉันมี. NET 4.7.1แล้วและสคริปต์จะส่งคืน v4.0.30319 เสมอ
แมตต์

0

หากคุณติดตั้ง Visual Studio บนเครื่องของคุณให้เปิดพรอมต์คำสั่งสำหรับนักพัฒนา Visual Studio และพิมพ์คำสั่งต่อไปนี้: clrver

มันจะแสดง. NET Framework รุ่นที่ติดตั้งไว้ทั้งหมดในเครื่องนั้น


คำสั่งนี้รับรุ่น CLR ไม่ใช่รุ่น. NET Framework ซึ่งแตกต่างกัน
user11909

0

ที่นี่ฉันจะใช้คำถามนี้ตามเอกสาร 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.' }
    }
)"

ตัวอย่างนี้ใช้งานได้กับ PowerShell ทุกรุ่นและจะใช้งานได้ตลอดกาลเนื่องจาก 4.8 เป็นเวอร์ชันล่าสุดของ. NET Framework


-1

นี่คือแนวคิดทั่วไป:

รับไอเท็มลูกในไดเร็กทอรี. NET Framework ที่เป็นคอนเทนเนอร์ที่มีชื่อตรงกับรูปแบบหมายเลข v จำนวนจุดวีจำนวนจำนวนจุดเรียงลำดับตามชื่อจากมากไปน้อยนำวัตถุแรกและส่งกลับคุณสมบัติของชื่อ

นี่คือสคริปต์:

(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
Matt

-1

ฉันจะลองอันนี้ใน PowerShell: ใช้งานได้สำหรับฉัน!

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


ไม่ได้บอกความจริงกับคุณ หมายเลขเวอร์ชันจะมีการพูดเช่น 4.7.03056 เมื่อรุ่นผลิตภัณฑ์เป็น 4.7.2
Jaykul

-2

ฉันไม่ได้อยู่ในไวยากรณ์ PowerShell ของฉัน แต่ฉันคิดว่าคุณสามารถเรียกSystem.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion ()ได้ นี่จะคืนค่าเวอร์ชันเป็นสตริง (เหมือนกับที่v2.0.50727ฉันคิด)


2
สำหรับรันไทม์ที่ดำเนินการอยู่ในปัจจุบันไม่จำเป็นต้องติดตั้งล่าสุด
Joey

สำหรับ powershell, ไวยากรณ์ที่ถูกต้องคือ: [System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion(), แต่มันจะคืนค่า v4.0.30319, แม้ว่า v4.6 จะถูกติดตั้งในเคสของฉัน
Matt

@matt 4.0.30319 เป็นรุ่น CLR จาก .Net Framework 4.0 ถึง. Net Framework 4.7.1 ดังนั้นเฟรมเวิร์ก v4.6 ของคุณใช้ 4.0.30319 เป็นเวอร์ชัน CLR ขอให้สังเกตว่าเฉพาะส่วนที่มีการปรับปรุงแก้ไขของรุ่นนั้นมีความแตกต่างระหว่าง. Net Framework ทั้งหมด ดูเพิ่มเติมที่: . NET Framework รุ่นและการอ้างอิง - Microsoft Docs
walterlv

@walterlv - ขอบคุณสำหรับลิงค์ ใช่ฉันรู้แล้ว ไมโครซอฟท์ทำผิดพลาดครั้งใหญ่ในการทำเช่นนั้นมันไม่ใช่เรื่องง่ายที่จะเชื่อมต่อระยะไกลไปยังเซิร์ฟเวอร์และค้นหาว่ามีการติดตั้ง. net เวอร์ชันใด อีกหนึ่งปวดหัวใหญ่สำหรับผู้ดูแลระบบและนักพัฒนา
Matt

และยุทธนี้ความช่วยเหลือเช่นกัน: ไมโครซอฟท์: วิธีการตรวจสอบรุ่นและระดับการให้บริการแพ็คของ .NET Framework มันยังแสดงให้เห็นว่ามันซับซ้อนเพียงใดในการค้นหาว่ามีการติดตั้งอะไรลงบนเครื่องของคุณ ... :-(
Matt

-2

นี่เป็นผลสืบเนื่องของการโพสต์ก่อนหน้านี้ แต่ได้รับรุ่นล่าสุดของกรอบสุทธิ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.