src/Public/Get-OpteraReclaimableLicense.ps1
|
function Get-OpteraReclaimableLicense { <# .SYNOPSIS Returns the reclaimable-license findings as objects for the pipeline (no file rendering). .DESCRIPTION Runs the same scan as Invoke-OpteraLicenseScan but emits objects instead of a report file. Gate behaviour mirrors the report so the named data cannot be obtained for free by switching cmdlets: - FULL (unlocked): emits one object per reclaimable account (the named remediation list). - FREE: emits the by-SKU rollup objects and warns how to unlock the named list. .EXAMPLE Get-OpteraReclaimableLicense | Where-Object MonthlyWasteUsd -gt 30 | Format-Table .EXAMPLE Get-OpteraReclaimableLicense -OfflineFixturePath .\tests\fixtures #> [CmdletBinding()] param( [string] $SearchBase, [string] $Server, # Scan every domain in the forest, not just the current one (multi-domain forests). [switch] $Forest, [ValidateRange(1, 3650)] [int] $StaleDays = 90, # OU(s) to suppress from the candidate list (full OU DN or a single component). [string[]] $ExcludeOu, [string] $PriceListPath, [string] $OfflineFixturePath, [string] $LicenseKey, [string] $TenantId, [string] $ClientId, [string] $CertificateThumbprint, [datetime] $ReferenceDate = (Get-Date) ) $report = Invoke-LicenseReclaimScanCore -SearchBase $SearchBase -Server $Server -Forest:$Forest -StaleDays $StaleDays ` -ExcludeOu $ExcludeOu -PriceListPath $PriceListPath -OfflineFixturePath $OfflineFixturePath -LicenseKey $LicenseKey ` -TenantId $TenantId -ClientId $ClientId -CertificateThumbprint $CertificateThumbprint ` -ReferenceDate $ReferenceDate if ($report.Mode -eq 'Full') { return $report.Reclaimable } Write-Warning ("Free mode: returning the aggregate per-SKU rollup only. {0} accounts (`${1:N0}/mo) are named in the full list - unlock with Unlock-OpteraLicenseReclaim." -f ` $report.Summary.ReclaimableAccountCount, $report.Summary.TotalMonthlyUsd) # Prefer the richer owned-vs-reclaimable inventory (adds the tenant's prepaid/consumed seat counts per # SKU) when the tenant license inventory was available; fall back to the plain by-SKU rollup # otherwise. Both are aggregate - no per-account data - so either is safe to emit in Free mode. if ($report.Inventory -and @($report.Inventory).Count) { return $report.Inventory } return $report.Summary.BySku } |