src/Private/New-ReclaimReportCsv.ps1
|
function New-ReclaimReportCsv { <# .SYNOPSIS Exports the named per-account remediation list to CSV. FULL mode only. .DESCRIPTION This is the paid deliverable: the exact accounts to deprovision, one row per account, with the licenses to reclaim and the monthly dollars each is wasting. Refuses to write in Free mode so the gate cannot be bypassed via the CSV path. .OUTPUTS The path written, or $null if the report is not unlocked. #> [CmdletBinding()] param( [Parameter(Mandatory)] [object] $Report, [Parameter(Mandatory)] [string] $Path ) if ($Report.Mode -ne 'Full') { Write-Warning 'CSV export of the named account list requires an unlocked (Full) report. Run Unlock-OpteraLicenseReclaim.' return $null } # CSV formula-injection guard: a directory value beginning with =, +, -, @ (or a leading # tab/CR that Excel strips before re-evaluating) is treated as a formula when the file is # opened in a spreadsheet. Prefix such values with an apostrophe so they render as text. # The named remediation list is the whole point of this export, so it must be safe to open. function _csvSafe([object]$v) { $s = [string]$v if ($s -and $s[0] -in '=', '+', '-', '@', "`t", "`r") { return "'$s" } return $s } $rows = $Report.Reclaimable | Sort-Object MonthlyWasteUsd -Descending | ForEach-Object { [pscustomobject]@{ DisplayName = _csvSafe $_.DisplayName UserPrincipalName = _csvSafe $_.UserPrincipalName SamAccountName = _csvSafe $_.SamAccountName Domain = _csvSafe $_.Domain Reason = _csvSafe $_.Reason DaysSinceLogon = $_.DaysSinceLogon OrgUnit = _csvSafe $_.OrgUnit Licenses = _csvSafe (($_.Skus | ForEach-Object { $_.Name }) -join '; ') MonthlyWasteUsd = $_.MonthlyWasteUsd AnnualWasteUsd = [math]::Round($_.MonthlyWasteUsd * 12, 2) MatchedBy = _csvSafe $_.MatchedBy DistinguishedName = _csvSafe $_.DistinguishedName } } $dir = Split-Path -Parent $Path if ($dir -and -not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } $rows | Export-Csv -LiteralPath $Path -NoTypeInformation -Encoding UTF8 return $Path } |