Private/Get-NSPConditionalAccessPolicyHash.ps1

function Get-NSPConditionalAccessPolicyHash {
    <#
    .SYNOPSIS
        SHA-256 of a policy's canonical content (lowercase hex). Equal content, equal hash.
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary]$Canonical
    )

    $json = ConvertTo-Json -InputObject $Canonical -Depth 8 -Compress
    $sha = [System.Security.Cryptography.SHA256]::Create()
    try {
        $bytes = $sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($json))
        -join ($bytes | ForEach-Object { $_.ToString('x2') })
    } finally {
        $sha.Dispose()
    }
}