Public/Get-MpRelease.ps1

function Get-MpRelease {
    <#
    .SYNOPSIS
        Gets Microsoft Defender release information, engine rings, and optionally downloads latest updates.
    .DESCRIPTION
        Retrieves the latest Microsoft Defender engine, platform, and signature versions
        available from Microsoft's definition updates server. Can also download the latest
        virus definition module (VDM) and platform update files directly to the current directory.
         
        When using the EngineRings switch, retrieves information about different engine rings
        from Microsoft's manifest, which represent different release channels for the Defender engine.
    .PARAMETER AdlPackagesUri
        The URL to query for Microsoft Defender update information. Defaults to Microsoft's
        definition updates information endpoint.
    .PARAMETER VdmUri
        The URL to download the latest virus definition module. Defaults to Microsoft's
        official download link for x64 systems.
    .PARAMETER DownloadLatestVdm
        Switch to download the latest virus definition module (mpam-fe.exe) to the current directory.
    .PARAMETER PlatformUri
        The URL template for downloading the latest Platform Client. The {{PLATFORMVER}} placeholder
        will be replaced with the actual platform version.
    .PARAMETER DownloadLatestPlatform
        Switch to download the latest Platform update executable to the current directory.
    .PARAMETER ManifestUri
        The URL to query for Microsoft Defender manifest information. Used particularly when
        retrieving engine rings version information.
    .PARAMETER EngineRings
        Switch to retrieve engine rings version information from the manifest instead of
        the standard release information.
    .PARAMETER EngineRingsAsJson
        Switch to output the engine rings information as a formatted JSON string instead of
        PowerShell objects. Only applies when used with -EngineRings.
    .EXAMPLE
        Get-MpRelease
         
        Returns the latest available Microsoft Defender engine, platform and signature versions.
    .EXAMPLE
        Get-MpRelease -DownloadLatestVdm
         
        Returns version information and downloads the latest virus definition module to the current directory.
    .EXAMPLE
        Get-MpRelease -DownloadLatestPlatform
         
        Returns version information and downloads the latest platform update to the current directory.
    .EXAMPLE
        Get-MpRelease -EngineRings
         
        Returns detailed information about Microsoft Defender engine rings across multiple signature versions.
    .EXAMPLE
        Get-MpRelease -EngineRings -EngineRingsAsJson
         
        Returns engine rings information formatted as a JSON string.
    .OUTPUTS
        System.Collections.Specialized.OrderedDictionary or System.Array (when using -EngineRings)
        or System.String (when using -EngineRings with -EngineRingsAsJson)
    #>

    [CmdletBinding()]
    Param (
        [Parameter(HelpMessage="URL for Microsoft Defender update information")]
        [string]$AdlPackagesUri = "https://definitionupdates.microsoft.com/packages?action=info",
        
        [Parameter(HelpMessage="URL for downloading the latest virus definition module")]
        [string]$VdmUri = "https://go.microsoft.com/fwlink/?LinkID=121721&arch=x64",
        
        [Parameter(HelpMessage="Download the latest virus definition module")]
        [switch]$DownloadLatestVdm,

        [Parameter(HelpMessage="URL for downloading the latest Platform Client")]
        [string]$PlatformUri = "https://definitionupdates.microsoft.com/packages/content/updateplatform.exe?packageType=Platform&packageVersion={{PLATFORMVER}}&arch=x64",
        
        [Parameter(HelpMessage="Download the latest Platform Client")]
        [switch]$DownloadLatestPlatform,

        [Parameter(HelpMessage="URL for Microsoft Defender manifest information")]
        [string]$ManifestUri = "https://definitionupdates.microsoft.com/download/DefinitionUpdates/VersionedSignatures/am-manifest.xml",
        [Parameter(HelpMessage="Get engine rings version information only from manifest")]
        [switch]$EngineRings,
        [switch]$EngineRingsAsJson
    )
    
    try {

        # If EngineRings switch is set, call Get-EngineRingsVersion function
        if ($EngineRings) {
            return Get-EngineRingsVersion -ManifestUri $ManifestUri -PrintAsJSON:$EngineRingsAsJson
        }

        Write-Verbose "Getting latest Microsoft Defender engine and platform versions..."
        $packageInfo = Invoke-WebRequest -Uri $AdlPackagesUri -UseBasicParsing -ErrorAction Stop
        
        # Parse the XML response
        [xml]$xmlVersion = $packageInfo.Content
        
        # Create ordered dictionary with version information
        $releaseInfo = [ordered]@{ 
            EngineVersion = $xmlVersion.versions.engine
            PlatformVersion = $xmlVersion.versions.platform
            SignatureVersion = $xmlVersion.versions.signatures.'#text'
            RetrievedTime = (Get-Date)
        }
        
        # Download the latest virus definition module if requested
        if ($DownloadLatestVdm) {
            $outputPath = Join-Path -Path (Get-Location) -ChildPath "mpam-fe.exe"
            
            Write-Verbose "Downloading latest virus definition module to $outputPath"
            try {
                # Use System.Net.WebClient for faster downloads
                $webClient = New-Object System.Net.WebClient
                $webClient.DownloadFile($VdmUri, $outputPath)
                $fileInfo = Get-Item -Path $outputPath
                
                $releaseInfo.Add("VdmDownloaded", $true)
                $releaseInfo.Add("VdmPath", $outputPath)
                $releaseInfo.Add("VdmSize", $fileInfo.Length)
                
                Write-Verbose "Download completed successfully. File size: $($fileInfo.Length) bytes"
            }
            catch {
                Write-Error "Failed to download virus definition module: $_"
                $releaseInfo.Add("VdmDownloaded", $false)
                $releaseInfo.Add("VdmError", $_.Exception.Message)
            }
        }

        # Download the latest platform update if requested
        if ($DownloadLatestPlatform) {
            $actualPlatformUri = $PlatformUri -replace '{{PLATFORMVER}}', $releaseInfo.PlatformVersion
            $outputPath = Join-Path -Path (Get-Location) -ChildPath "UpdatePlatform.exe"
            
            Write-Verbose "Downloading latest platform update to $outputPath"
            try {
                # Use System.Net.WebClient for faster downloads
                $webClient = New-Object System.Net.WebClient
                $webClient.DownloadFile($actualPlatformUri, $outputPath)
                $fileInfo = Get-Item -Path $outputPath
                
                $releaseInfo.Add("PlatformDownloaded", $true)
                $releaseInfo.Add("PlatformPath", $outputPath)
                $releaseInfo.Add("PlatformSize", $fileInfo.Length)
                
                Write-Verbose "Platform download completed successfully. File size: $($fileInfo.Length) bytes"
            }
            catch {
                Write-Error "Failed to download platform update: $_"
                $releaseInfo.Add("PlatformDownloaded", $false)
                $releaseInfo.Add("PlatformError", $_.Exception.Message)
            }
        }
            
        return $releaseInfo
    }
    catch {
        Write-Error "Failed to retrieve Microsoft Defender release information: $_"
        return $null
    }
}


function Get-EngineRingsVersion {
    <#
    .SYNOPSIS
        Retrieves Microsoft Defender engine ring versions from Microsoft's definition updates manifest.
    .DESCRIPTION
        Gets detailed information about Microsoft Defender engine rings across multiple signature versions.
        Engine rings represent different release channels for the Defender engine, allowing Microsoft to
        gradually roll out updates. This function returns information about each signature version and its
        associated engine rings, including download links for each specific combination.
    .PARAMETER ManifestUri
        The URL to query for Microsoft Defender manifest information. Defaults to Microsoft's
        definition updates manifest endpoint containing the am-manifest.xml file.
    .PARAMETER PrintAsJSON
        Switch to output the results as a formatted JSON string instead of PowerShell objects.
        The JSON output has URL encodings properly replaced for better readability.
    .EXAMPLE
        Get-EngineRingsVersion
         
        Returns an array of PowerShell objects containing available Microsoft Defender engine ring versions.
    .EXAMPLE
        Get-EngineRingsVersion -PrintAsJSON
         
        Returns the engine rings information as a formatted JSON string for easier integration with other tools.
    .OUTPUTS
        System.Array or System.String (when using -PrintAsJSON)
    #>

    [CmdletBinding()]
    Param (
        [Parameter(HelpMessage="URL for Microsoft Defender manifest information")]
        [string]$ManifestUri = "https://definitionupdates.microsoft.com/download/DefinitionUpdates/VersionedSignatures/am-manifest.xml",
        [Parameter(HelpMessage="Output results as formatted JSON")]
        [switch]$PrintAsJSON
    )
    
    try {
        Write-Verbose "Getting Microsoft Defender engine rings versions..."
        $webClient = New-Object System.Net.WebClient
        $manifestContent = $webClient.DownloadString($ManifestUri)
        [xml]$amManifest = $manifestContent

        $engineRings = @()

        if ($amManifest) {
            $signatureVersions = $amManifest.manifest.SignatureVersions.SignatureVersion | Select-Object -First 10
            
            foreach ($sigVersion in $signatureVersions) {

                $engine_rings = $sigVersion.engine.version | ForEach-Object { 
                    [PSCustomObject]@{ 
                        "ring$($_.ring)" = $_.'#text'
                        download_uri = 'https://definitionupdates.microsoft.com/packages/content/mpam-fe.exe?packageType=Signatures&packageVersion=' + $sigVersion.ver + '&arch=amd64&engineVersion=' + $_.'#text'
                    }
                }

                $engineRings += [ordered]@{ 
                    sig_version = $sigVersion.ver
                    released = $sigVersion.released
                    engine_rings = $engine_rings
                }
            }
            
            Write-Verbose "Found engine rings: $($engineRings -join ', ')"
        }

        if($PrintAsJSON)
        {
            $outputjson = $engineRings | ConvertTo-Json -Depth 10
            $outputjson = $outputjson -replace "\\u0026", "&"
            Write-Output $outputjson
            return
        }
        
        return $engineRings
    }
    catch {
        Write-Error "Failed to retrieve Microsoft Defender engine rings information: $_"
        return $null
    }
}