Public/Get-EFBaseline.ps1

function Get-EFBaseline {
    <#
    .SYNOPSIS
    Loads a built-in or file-based Windows computer checklist.
 
    .DESCRIPTION
    A checklist is a list of things expected to be true, such as Windows settings,
    storage, applications, jobs, files, certificates, recent events, or an approved
    network service. PowerShell commands call it a baseline for compatibility. This
    command only loads and validates the JSON file. It does not read a target, perform a
    network-active check, check a setting, or change a computer. ListAvailable shows the
    checklists included with the module.
 
    .PARAMETER Name
    The built-in checklist name. EnterpriseRecommended is the default.
 
    .PARAMETER Path
    The path to a custom checklist JSON file. Review custom files before use because they
    choose which applications, jobs, local paths, event logs, certificates, accounts,
    update services, hosts, ports, and web addresses later checks can inspect or contact.
 
    .PARAMETER ListAvailable
    Lists information about every checklist included with the installed module.
 
    .EXAMPLE
    Get-EFBaseline -Name EnterpriseRecommended
 
    .EXAMPLE
    Get-EFBaseline -Path .\contoso-baseline.json
 
    .EXAMPLE
    Get-EFBaseline -ListAvailable
 
    .EXAMPLE
    Get-EFBaseline -Path .\checklists\Contoso.EverydayChecks.json
 
    Loads and validates an everyday-checklist file without running any of its checks.
 
    .OUTPUTS
    EndpointForge.Baseline or EndpointForge.BaselineInfo.
 
    .LINK
    New-EFBaseline
 
    .LINK
    Test-EFBaseline
    #>

    [CmdletBinding(DefaultParameterSetName = 'Name')]
    param(
        [Parameter(ParameterSetName = 'Name')]
        [ValidateNotNullOrEmpty()]
        [string]$Name = 'EnterpriseRecommended',

        [Parameter(Mandatory, ParameterSetName = 'Path')]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter(Mandatory, ParameterSetName = 'List')]
        [switch]$ListAvailable
    )

    if ($ListAvailable) {
        foreach ($file in Get-ChildItem -LiteralPath (Join-Path $script:ModuleRoot 'Data') -Filter '*.json' -File) {
            if ($file.Name -eq 'Baseline.schema.json') {
                continue
            }
            try {
                $item = Get-Content -LiteralPath $file.FullName -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop
                Assert-EFBaseline -Baseline $item
                [pscustomobject]@{
                    PSTypeName   = 'EndpointForge.BaselineInfo'
                    Name         = [string]$item.Name
                    Version      = [string]$item.Version
                    Description  = [string]$item.Description
                    ControlCount = @($item.Controls).Count
                    Path         = $file.FullName
                }
            }
            catch {
                Write-Warning "Skipping invalid built-in baseline '$($file.Name)': $($_.Exception.Message)"
            }
        }
        return
    }

    if ($PSCmdlet.ParameterSetName -eq 'Name') {
        if ($Name -notmatch '^[A-Za-z0-9._-]+$') {
            throw [System.ArgumentException]::new("Baseline name '$Name' contains invalid characters.")
        }
        $resolvedPath = Join-Path (Join-Path $script:ModuleRoot 'Data') "$Name.json"
        if (-not (Test-Path -LiteralPath $resolvedPath -PathType Leaf)) {
            throw [System.IO.FileNotFoundException]::new("Built-in baseline '$Name' was not found.")
        }
    }
    else {
        $resolvedPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
        if (-not (Test-Path -LiteralPath $resolvedPath -PathType Leaf)) {
            throw [System.IO.FileNotFoundException]::new("Baseline file '$resolvedPath' was not found.")
        }
    }

    try {
        $baseline = Get-Content -LiteralPath $resolvedPath -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop
    }
    catch {
        throw [System.IO.InvalidDataException]::new("Baseline '$resolvedPath' is not valid JSON: $($_.Exception.Message)")
    }

    Assert-EFBaseline -Baseline $baseline
    $baseline.PSObject.TypeNames.Insert(0, 'EndpointForge.Baseline')
    $baseline | Add-Member -NotePropertyName SourcePath -NotePropertyValue $resolvedPath -Force
    $baseline | Add-Member -NotePropertyName ControlCount -NotePropertyValue @($baseline.Controls).Count -Force
    $baseline | Add-Member -NotePropertyName RemediableCount -NotePropertyValue @($baseline.Controls | Where-Object Remediable).Count -Force
    return $baseline
}