core/Save-BackupItem.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Saves a single backup item to a JSON file. .DESCRIPTION Converts an item to JSON and saves it to disk. Automatically creates the folder if needed. Sanitizes the filename by replacing illegal filesystem characters. .PARAMETER Item The object to save. .PARAMETER Folder The directory where the file will be saved. .PARAMETER FileName The base filename to use (without extension). If not provided, uses $Item.displayName. .PARAMETER PresetFileName A specific filename to use. Takes precedence over $FileName. .PARAMETER ScopeTagMap Optional hashtable of scope tag IDs to display names. When provided, translates roleScopeTagIds values before saving. .EXAMPLE Save-BackupItem -Item $policy -Folder "C:\backup" -PresetFileName "MyPolicy" #> function Save-BackupItem { [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Item, [Parameter(Mandatory = $true)] [string]$Folder, [string]$FileName, [string]$PresetFileName, [hashtable]$ScopeTagMap = @{} ) #region Determine Filename $baseFileName = $null # Helper: get a property value from either a PSCustomObject or a hashtable/dictionary $getProp = { param($obj, $key) if ($obj -is [System.Collections.IDictionary]) { $obj[$key] } else { $obj.PSObject.Properties[$key]?.Value } } if ($PresetFileName) { $baseFileName = $PresetFileName } elseif ($FileName) { $baseFileName = $FileName } elseif (& $getProp $Item 'displayName') { $baseFileName = & $getProp $Item 'displayName' } else { throw 'Could not determine filename. Provide $PresetFileName, $FileName, or ensure $Item has a displayName property.' } #endregion Determine Filename #region Append ID to filename # Append __<id> when the item carries a stable 'id' property and no PresetFileName was given if (-not $PresetFileName) { $itemId = & $getProp $Item 'id' if ($itemId) { $baseFileName = "${baseFileName}__${itemId}" } } #endregion Append ID to filename # Sanitize Filename $baseFileName = ConvertTo-SanitizatedFileName -fileName $baseFileName #region Create Folder if (!(Test-Path -Path $Folder -PathType Container)) { New-Item -ItemType Directory -Path $Folder -Force > $null Write-Verbose "Created folder: $Folder" } #endregion Create Folder #region Scope Tag Resolution if ($ScopeTagMap.Count -gt 0) { $Item = Resolve-ScopeTagNames -InputObject $Item -ScopeTagMap $ScopeTagMap } #endregion Scope Tag Resolution #region Save to JSON $filePath = Join-Path -Path $Folder -ChildPath "$baseFileName.json" $normalizedItem = ConvertTo-ObjectSortedProperties -InputObject $Item $jsonContent = $normalizedItem | ConvertTo-Json -Depth 20 Set-Content -LiteralPath $filePath -Value $jsonContent -Encoding UTF8 -Force Write-Verbose "Saved backup item to: $filePath" return $filePath #endregion Save to JSON } Export-ModuleMember -Function Save-BackupItem |