Public/License/Get-SPCLicenseInfo.ps1
|
function Get-SPCLicenseInfo { <# .SYNOPSIS Returns the currently registered SPClean license status. .DESCRIPTION Reads license status from the module cache or disk. Never throws — returns a status object whether licensed or not. Use this to check license tier before calling paid features. .EXAMPLE Get-SPCLicenseInfo Returns the current license status. Status will be 'Active', 'Expired', 'Invalid', or 'Unlicensed'. .EXAMPLE if ((Get-SPCLicenseInfo).Status -ne 'Active') { Write-Warning 'SPClean Pro license required for this operation.' } .OUTPUTS SPC.LicenseInfo .NOTES Purchase SPClean Pro or Consultant at https://spclean.gumroad.com #> [CmdletBinding()] [OutputType([PSCustomObject])] param() $makeInfo = { param([string]$Status, [string]$Tier, [string]$Email, [string]$LicId, $ExpiresAt, $RegisteredAt, [string]$FailureReason) $r = [PSCustomObject][ordered]@{ Tier = $Tier Email = $Email LicenseId = $LicId ExpiresAt = $ExpiresAt RegisteredAt = $RegisteredAt Status = $Status FailureReason = $FailureReason } $r.PSObject.TypeNames.Insert(0, 'SPC.LicenseInfo') $r } $unlicensed = { & $makeInfo 'Unlicensed' 'FREE' $null $null $null $null $null } # Step 1: return from cache if valid and not expired if ($null -ne $script:SPCLicenseCache) { $cached = $script:SPCLicenseCache if ($cached.Status -eq 'Active' -and $null -ne $cached.ExpiresAt -and $cached.ExpiresAt -gt [datetime]::UtcNow) { return $cached } $script:SPCLicenseCache = $null } # Step 2: read from disk $licPath = Get-SPCLicensePathInternal if (-not (Test-Path -Path $licPath -PathType Leaf)) { return (& $unlicensed) } $licRaw = $null try { $licRaw = Get-Content -Path $licPath -Encoding UTF8 -Raw -ErrorAction Stop $lic = $licRaw | ConvertFrom-Json } catch { Write-Verbose "Get-SPCLicenseInfo: Cannot read license.lic — $($_.Exception.Message)" return (& $makeInfo 'Invalid' $null $null $null $null $null 'CorruptFile') } if ([string]::IsNullOrWhiteSpace($lic.licenseKey)) { return (& $makeInfo 'Invalid' $null $null $null $null $null 'MissingLicenseKey') } # Step 3: re-verify key $secretBytes = $null $validation = $null try { $secretBytes = Get-SPCSecretKeyBytesInternal $validation = Test-SPCLicenseKey -LicenseKey $lic.licenseKey -SecretKeyBytes $secretBytes } catch { Write-Verbose "Get-SPCLicenseInfo: Verification error — $($_.Exception.Message)" return (& $makeInfo 'Invalid' $null $null $null $null $null 'VerificationError') } finally { if ($null -ne $secretBytes) { [System.Array]::Clear($secretBytes, 0, $secretBytes.Length) } } if (-not $validation.IsValid) { $status = if ($validation.FailureReason -eq 'Expired') { 'Expired' } else { 'Invalid' } return (& $makeInfo $status $null $null $null $null $null $validation.FailureReason) } $registeredAt = $null try { if (-not [string]::IsNullOrWhiteSpace($lic.registeredAt)) { $registeredAt = [datetime]::Parse( $lic.registeredAt, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind) } } catch {} # Step 5: populate cache and return $result = & $makeInfo 'Active' $validation.Tier $validation.Email $validation.LicenseId ` $validation.ExpiresAt $registeredAt $null $script:SPCLicenseCache = $result $result } |