source/Private/ModuleVersionCheck.ps1

function Get-RJModuleVersion {
    <#
    .SYNOPSIS
    Returns the version of the currently running RealmJoin module instance.
 
    .DESCRIPTION
    Reads the module version from the function's own module context. Returns $null when the
    function is not running inside an imported module (e.g. dot-sourced Test-Debug.ps1 sessions),
    which callers use to skip version checks in development.
 
    .OUTPUTS
    [version] The running module's version, or $null if not running as an imported module.
    #>

    [CmdletBinding()]
    [OutputType([version])]
    param()

    $module = $MyInvocation.MyCommand.Module
    if ($null -eq $module) {
        Write-Verbose "Get-RJModuleVersion: not running inside a module context"
        return $null
    }

    return $module.Version
}

function Get-RJGalleryLatestVersion {
    <#
    .SYNOPSIS
    Queries the PowerShell Gallery for the latest published RealmJoin module version.
 
    .OUTPUTS
    [version] The latest version on the PowerShell Gallery, or $null if the lookup fails.
    #>

    [CmdletBinding()]
    [OutputType([version])]
    param()

    try {
        $latest = Find-Module -Name 'RealmJoin' -Repository PSGallery -ErrorAction Stop
        return [version]$latest.Version
    }
    catch {
        Write-Verbose "Get-RJGalleryLatestVersion: failed to query the PowerShell Gallery. Error: $($_.Exception.Message)"
        return $null
    }
}

function Show-RJModuleUpdateInstructions {
    <#
    .SYNOPSIS
    Shows user-friendly instructions to update to the latest RealmJoin module version.
 
    .PARAMETER InstalledVersion
    The currently installed/imported module version.
 
    .PARAMETER LatestVersion
    The latest version available on the PowerShell Gallery.
    #>

    [CmdletBinding()]
    [OutputType([void])]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Show-RJModuleUpdateInstructions')]
    param (
        [Parameter(Mandatory = $true)]
        [version]$InstalledVersion,

        [Parameter(Mandatory = $true)]
        [version]$LatestVersion
    )

    Write-Host "RealmJoin module is outdated - execution cannot proceed" -ForegroundColor Red
    Write-Host ""
    Write-Host "Installed version: $InstalledVersion" -ForegroundColor Yellow
    Write-Host "Latest version: $LatestVersion" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "To update, run the following command, then close this session, open a new one, and re-run:" -ForegroundColor Yellow
    Write-Host ""
    Write-Host " Install-Module -Name RealmJoin -Force -Scope CurrentUser" -ForegroundColor Cyan
    Write-Host ""
}

function Test-RJModuleVersion {
    <#
    .SYNOPSIS
    Verifies the running RealmJoin module is the latest version published on the PowerShell Gallery.
 
    .DESCRIPTION
    Compares the running module version against the PowerShell Gallery once per session (cached in
    $script:RJVersionCheckPassed) and blocks execution when outdated. Fails open (returns $true) when
    the Gallery cannot be reached, when not running as an imported module, or when
    $env:RJ_SKIP_UPDATE_CHECK is set to 'true'.
 
    .OUTPUTS
    [bool] True if execution should proceed, False if the module is outdated and must be updated.
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param()

    if ($env:RJ_SKIP_UPDATE_CHECK -ieq 'true') {
        Write-Verbose "Skipping module version check - RJ_SKIP_UPDATE_CHECK is set"
        return $true
    }

    if ($null -ne $script:RJVersionCheckPassed) {
        Write-Verbose "Using cached module version check result: $script:RJVersionCheckPassed"
        if (-not $script:RJVersionCheckPassed) {
            Show-RJModuleUpdateInstructions -InstalledVersion $script:RJModuleCheckInstalledVersion -LatestVersion $script:RJModuleCheckLatestVersion
        }
        return $script:RJVersionCheckPassed
    }

    $installedVersion = Get-RJModuleVersion
    if ($null -eq $installedVersion) {
        Write-Verbose "Module version check skipped - not running as an imported module"
        $script:RJVersionCheckPassed = $true
        return $true
    }

    $latestVersion = Get-RJGalleryLatestVersion
    if ($null -eq $latestVersion) {
        Write-Warning "Could not verify the latest RealmJoin version from the PowerShell Gallery. Continuing with installed version $installedVersion."
        $script:RJVersionCheckPassed = $true
        return $true
    }

    if ($installedVersion -ge $latestVersion) {
        Write-Verbose "RealmJoin module is up to date (installed: $installedVersion, latest: $latestVersion)"
        $script:RJVersionCheckPassed = $true
        return $true
    }

    $script:RJModuleCheckInstalledVersion = $installedVersion
    $script:RJModuleCheckLatestVersion = $latestVersion
    Show-RJModuleUpdateInstructions -InstalledVersion $installedVersion -LatestVersion $latestVersion
    $script:RJVersionCheckPassed = $false
    return $false
}