functions/softwareupdate/Get-MicrosoftComponentVersions.ps1

function Get-MicrosoftComponentVersions {
    [CmdletBinding()]
    param ()

    $results = @()

    # --- .NET Framework ---
    $fw = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -ErrorAction SilentlyContinue
    if ($fw -and $fw.Release) {
        $release = $fw.Release
        $fwVersion = switch ($release) {
            { $_ -ge 533325 } { "4.8.1"; break }
            { $_ -ge 528040 } { "4.8"  ; break }
            { $_ -ge 461808 } { "4.7.2"; break }
            { $_ -ge 461308 } { "4.7.1"; break }
            { $_ -ge 460798 } { "4.7"  ; break }
            default { "Unknown ($release)" }
        }

        $results += [PSCustomObject]@{
            Component         = '.NET Framework'
            InstalledVersion  = $fwVersion
            LatestVersion     = '4.8.1'
            DownloadUrl       = 'https://dotnet.microsoft.com/en-us/download/dotnet-framework'
        }
    }

    # --- .NET SDKs und Runtimes ---
    $dotnet = Get-Command dotnet -ErrorAction SilentlyContinue
    if ($dotnet) {
        $dotnetPath = $dotnet.Source

        $sdks = & $dotnetPath --list-sdks 2>$null
        foreach ($sdk in $sdks) {
            $ver = ($sdk -split '\s+\[')[0]
            $results += [PSCustomObject]@{
                Component         = '.NET SDK'
                InstalledVersion  = $ver
                LatestVersion     = $null
                DownloadUrl       = 'https://dotnet.microsoft.com/en-us/download'
            }
        }

        $runtimes = & $dotnetPath --list-runtimes 2>$null
        foreach ($rt in $runtimes) {
            $parts = ($rt -split '\s+\[')[0] -split '\s+'
            $component = "$($parts[0]) Runtime"
            $ver = $parts[1]

            $results += [PSCustomObject]@{
                Component         = $component
                InstalledVersion  = $ver
                LatestVersion     = $null
                DownloadUrl       = 'https://dotnet.microsoft.com/en-us/download'
            }
        }
    }

    # --- Neueste SDK- & Runtime-Versionen aus dem JSON-Feed ---
    try {
        $indexUri = 'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json'
        $index = Invoke-RestMethod -Uri $indexUri -UseBasicParsing

        # Den neuesten LTS-Kanal finden, der NICHT "preview" ist
        $latestStableLts = $index.'releases-index' |
            Where-Object { $_.'release-type' -ne 'preview' -and $_.'support-phase' -eq 'lts' } |
            Sort-Object -Property 'latest-release-date' -Descending |
            Select-Object -First 1

        $releasesJsonUri = $latestStableLts.'releases.json'
        $releaseInfo = Invoke-RestMethod -Uri $releasesJsonUri -UseBasicParsing

        $latestSdk = $releaseInfo.releases |
            Where-Object { $_.sdk.version } |
            Select-Object -ExpandProperty sdk |
            Select-Object -ExpandProperty version -First 1

        $results | Where-Object { $_.Component -eq '.NET SDK' -and -not $_.LatestVersion } |
            ForEach-Object { $_.LatestVersion = $latestSdk }

        $latestRuntimes = @{}
        foreach ($release in $releaseInfo.releases) {
            foreach ($rt in $release.runtime) {
                if ($rt.name -and $rt.version) {
                    $key = "$($rt.name) Runtime"
                    if (-not $latestRuntimes.ContainsKey($key)) {
                        $latestRuntimes[$key] = $rt.version
                    }
                }
            }
        }

        foreach ($item in $results) {
            if (-not $item.LatestVersion -and $latestRuntimes.ContainsKey($item.Component)) {
                $item.LatestVersion = $latestRuntimes[$item.Component]
            }
        }

    } catch {
        Write-Warning "Fehler beim Abrufen der Online-Daten: $_"
    }

    return $results
}