Private/Import-NSPToolkitModule.ps1

function Import-NSPToolkitModule {
    <#
    .SYNOPSIS
        Loads a sibling NSP toolkit module on first use: an installed copy, else a checkout next to
        this repository (NSP-PoSHToolkits\NSP-X or GitRepo\NSP-X), else installs it from the
        PowerShell Gallery.
    .DESCRIPTION
        Copied from NSP.M365.ConditionalAccess, plus the second sibling location (NSP-Bootstrap
        lives directly under GitRepo, the others under NSP-PoSHToolkits). These modules are never
        RequiredModules entries, so this module still imports on a bare host. With
        -MinimumVersion, an older installed copy is passed over and a loaded older copy replaced.
 
        The Gallery install is what lets a plain `Install-Module NSP.<Tool>` work on its own: the
        siblings arrive the first time they're needed (AllUsers when elevated, else CurrentUser).
        NSP_NO_AUTOINSTALL=1 turns it off - the test runners set it so a test never reaches the
        network.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$Name,
        [version]$MinimumVersion,
        [switch]$Reload
    )

    $loaded = Get-Module -Name $Name | Sort-Object Version -Descending | Select-Object -First 1
    if ($loaded -and -not $Reload -and (-not $MinimumVersion -or $loaded.Version -ge $MinimumVersion)) { return }
    $findInstalled = {
        $m = Get-Module -ListAvailable -Name $Name | Where-Object { -not $MinimumVersion -or $_.Version -ge $MinimumVersion } |
            Sort-Object Version -Descending | Select-Object -First 1
        if ($m) { $m.Path }
    }
    $path = & $findInstalled
    if (-not $path) {
        $folder = $Name.Replace('.', '-')
        $toolkits = Split-Path -Parent $script:ModuleRoot
        foreach ($candidate in @((Join-Path $toolkits "$folder\$Name.psd1"), (Join-Path (Split-Path -Parent $toolkits) "$folder\$Name.psd1"))) {
            if (-not (Test-Path -LiteralPath $candidate)) { continue }
            if ($MinimumVersion -and [version](Import-PowerShellDataFile -LiteralPath $candidate).ModuleVersion -lt $MinimumVersion) { continue }
            $path = $candidate
            break
        }
    }
    $wanted = if ($MinimumVersion) { "$Name $MinimumVersion or later" } else { $Name }
    $installError = $null
    if (-not $path -and $env:NSP_NO_AUTOINSTALL -ne '1') {
        Write-Host "Installing $wanted from the PowerShell Gallery..." -ForegroundColor DarkGray
        try {
            [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
            $identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
            $scope = if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { 'AllUsers' } else { 'CurrentUser' }
            if (-not (Get-PackageProvider -ListAvailable -Name NuGet -ErrorAction SilentlyContinue | Where-Object { $_.Version -ge [version]'2.8.5.201' })) {
                Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope $scope -ErrorAction Stop | Out-Null
            }
            $install = @{ Name = $Name; Repository = 'PSGallery'; Scope = $scope; Force = $true; AllowClobber = $true; ErrorAction = 'Stop' }
            if ($MinimumVersion) { $install.MinimumVersion = $MinimumVersion }
            Install-Module @install
            $path = & $findInstalled
        } catch {
            $installError = $_.Exception.Message
        }
    }
    if (-not $path) {
        $why = if ($installError) { " Installing it from the PowerShell Gallery failed: $installError" } else { '' }
        throw "$wanted is required for this operation.$why Install it (Install-Module $Name), or check out $($Name.Replace('.', '-')) next to this repository."
    }
    if ($loaded) { Remove-Module -Name $Name -Force }
    Import-Module $path -Global -ErrorAction Stop
}