マシン上の.NET Frameworkのバージョンを返すには、PowerShellスクリプトは何でしょうか?
私の最初の推測は、WMIに関係するものです。もっと良いものはありますか?
.NETのインストールごとに[各行に]最新バージョンのみを返すのは1行である必要があります。
asp.net -v
マシン上の.NET Frameworkのバージョンを返すには、PowerShellスクリプトは何でしょうか?
私の最初の推測は、WMIに関係するものです。もっと良いものはありますか?
.NETのインストールごとに[各行に]最新バージョンのみを返すのは1行である必要があります。
asp.net -v
回答:
レジストリを使用する場合は、4.xフレームワークのフルバージョンを取得するために再帰する必要があります。以前の回答はどちらも.NET 3.0のシステムのルート番号を返します(3.0の下にネストされているWCFとWPFの番号は大きいので、説明できません)。4.0では何も返しません。 。
編集:.Net 4.5以降では、これが少し変更されたため、リリース値を.Netバージョン番号に変換する方法を説明するMSDNの記事がここにあります。これは完全な問題です:-(
これは私には正しいように見えます(3.0ではWCFとWPFのバージョン番号が別々に出力されることに注意してください。それが何であるかはわかりません)。また、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
実際、私はこの回答を更新する必要があるため、そのWebページのマークダウンソースから上記のスクリプトを(少し追加して)生成するスクリプトを次に示します。これはおそらくどこかで壊れるので、上記の現在のコピーを保持します。
# 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 }}
"@
'^(?!S)\p{L}'
正規表現に適合する各フォルダを再帰的に検索し、バージョンとリリース情報を取得することです。その正規表現は正確には何を修飾しようとしていますか?
PSChildName
は、レジストリキーのリーフ名です。\p{L}
Unicodeカテゴリ「文字」の任意の文字です。(?!S)
は否定的な見方^
であり、文字列の始まりです。したがって、以外の文字で始まる必要がありS
ます。したがって、ASCIIのみを検討する場合は、$_.PSChildName -cmatch '^[A-RT-Za-z]'
(に注意-cmatch
)と同じです。したがって、名前が以外の文字で始まるキーを検索しますS
。S
...で始まる名前をフィルターで除外する場合に、なぜ非ASCIIを気にするのかわかりません。
Get-ItemProperty -name Version,Release -EA 0
が何をしているかについてより混乱しています。私-EA 0
はと同じだと知っていますが、すべての結果をそれにパイプ-ErrorAction SilentlyContinue
すると、どのような影響がGet-ItemProperty -name Version,Release
ありますか?他の変数はパイプラインの後のコマンドで使用されるため、オブジェクトから変数を取り除いていないようです。それが実行され、Version
またはRelease
名前がキーから欠落しているときにエラーが発生し、成功したオブジェクトをパイプラインの次のコマンドに渡しますか?
(?!S)
よう(?![SW])
に、条項を変更しただけです。(?=[vCF])
.NET 4.0以降では、バージョンのルートと「フル」および「クライアント」のキーのみが重要なので、これを使用して行うこともできます。;)
gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' |
sort pschildname -des |
select -fi 1 -exp pschildname
これがインストールされている場合、この回答は4.5を返しません。@Jaykulからの以下の回答と再帰の使用が行います。
スクリプトに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" }
}
}
}
$PSVersionTable
して、実行されているCLR PowerShellのバージョンを確認することもできます。
正しい構文:
[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
私はこれをosxのPowershellのタブ補完で見つけました:
[System.Runtime.InteropServices.RuntimeInformation]::get_FrameworkDescription()
.NET Core 4.6.25009.03
[version]([Runtime.InteropServices.RuntimeInformation]::FrameworkDescription -replace '^.[^\d.]*','')
単純なスクリプトを使用して、すべてのプラットフォームとアーキテクチャでこれを行う信頼できる方法はありません。確実に行う方法を学びたい場合は、ブログの投稿から始めてください。より詳細なチェックを行う、更新されたサンプルの.NET Framework検出コード。
リモートワークステーションにインストールされている.NETバージョンを確認するには、スクリプトページを参照してください。
そこにあるスクリプトは、ネットワーク上の複数のマシンの.NETバージョンを見つけるのに役立つ場合があります。
ダウンロード可能な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。
他のマシンでは、2つの会社のカスタムとの助けを借りて(PS 2.0から)PS 5.1(.NET Framework> = 4.5が必要)に更新したかった。
インストール/更新プロセスを通じて管理者を適切にガイドするには、すべてのマシンのこれらの関数の.NETバージョンと既存のPSバージョンを特定する必要があります。
したがって、以下の関数を使用して、すべての環境でより安全にそれらを決定しました...Install-DotnetLatestCompany
Install-PSLatestCompany
したがって、次のコードと以下の(抽出された)使用例がここで役立ちます(他の回答に基づく):
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"
きれいじゃない。間違いなくきれいではない:
ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer } | select -exp Name -l 1
これは機能する場合と機能しない場合があります。しかし、最新バージョンに関する限り、これはかなり信頼できるはずです。古いバージョン(1.0、1.1)には基本的に空のフォルダーがあり、新しいフォルダーはないためです。これらは、適切なフレームワークがインストールされた後にのみ表示されます。
それでも、もっと良い方法があるはずだと思います。
ls $Env:windir\Microsoft.NET\Framework | ? { $_.PSIsContainer -and $_.Name -match '^v\d.[\d\.]+' } | % { $_.Name.TrimStart('v') }
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バージョンであるため、永続的に機能します。
一般的な考え方は次のとおりです。
名前がパターンv番号ドット番号に一致するコンテナである.NET Frameworkディレクトリの子項目を取得します。名前の降順で並べ替え、最初のオブジェクトを取得して、その名前プロパティを返します。
スクリプトは次のとおりです。
(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構文を理解していませんが、ただ呼び出すことができると思います System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion()を。これはバージョンを文字列として返します(のようなものv2.0.50727
だと思います)。
[System.Runtime.InteropServices.RuntimeEnvironment]::GetSystemVersion()
ただし、私の場合はv4.6がインストールされていますが、v4.0.30319が返されます。
これは以前の投稿の派生物ですが、私のテストでは.netフレームワーク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