src/public/System/New-AitherWindowsRegistryFile.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Generate Windows registry import file (.reg) .DESCRIPTION Creates a .reg file with registry settings from config.windows.psd1. .PARAMETER ConfigPath Path to Windows configuration file .PARAMETER OutputPath Output directory for generated file .EXAMPLE New-AitherWindowsRegistryFile -ConfigPath ./config.windows.psd1 Generate registry file from Windows configuration .OUTPUTS String - Path to generated file, or null if generation is disabled .NOTES Requires config.windows.psd1 with Windows.Registry section. Generation can be disabled in configuration. .LINK New-AitherDeploymentArtifact New-AitherWindowsUnattendXml #> function New-AitherWindowsRegistryFile { [CmdletBinding()] param( [Parameter(Mandatory=$false)] [string]$ConfigPath, [string]$OutputPath = './artifacts/windows', [Parameter(HelpMessage = "Show command output in console.")] [switch]$ShowOutput ) begin { # Manage logging targets for this execution $originalLogTargets = $script:AitherLogTargets if ($ShowOutput) { if ($script:AitherLogTargets -notcontains 'Console') { $script:AitherLogTargets += 'Console' } } else { # Ensure Console is NOT in targets if ShowOutput is not specified $script:AitherLogTargets = $script:AitherLogTargets | Where-Object { $_ -ne 'Console' } } if (-not [System.IO.Path]::IsPathRooted($OutputPath)) { $moduleRoot = Get-AitherModuleRoot $OutputPath = Join-Path $moduleRoot $OutputPath } } process { try { # During module validation, skip execution if ($PSCmdlet.MyInvocation.InvocationName -eq '.') { return $null } $hasWriteAitherLog = Get-Command Write-AitherLog -ErrorAction SilentlyContinue if ($hasWriteAitherLog) { Write-AitherLog -Message "Generating Windows registry file from $ConfigPath" -Level Information -Source 'New-AitherWindowsRegistryFile' } # Load configuration if (-not (Get-Command Get-AitherConfigs -ErrorAction SilentlyContinue)) { Write-AitherLog -Level Warning -Message "Get-AitherConfigs is not available. Cannot generate registry file." -Source 'New-AitherWindowsRegistryFile' return $null } $config = Get-AitherConfigs -ConfigFile $ConfigPath if (-not $config.Windows.DeploymentArtifacts.RegistryExport.Generate) { if ($hasWriteAitherLog) { Write-AitherLog -Message "Registry export is disabled in configuration" -Level Warning -Source 'New-AitherWindowsRegistryFile' } else { Write-AitherLog -Level Warning -Message "Registry export is disabled in configuration" -Source 'New-AitherWindowsRegistryFile' } return $null } $registryConfig = $config.Windows.Registry $outputFileName = $config.Windows.DeploymentArtifacts.RegistryExport.FileName # Start registry file content $regContent = @('Windows Registry Editor Version 5.00', '') # Process all registry categories foreach ($category in $registryConfig.Keys | Where-Object { $_ -ne 'AutoApply' -and $_ -ne 'BackupBeforeChanges' }) { $regContent += ""; $regContent += "; $category Settings" foreach ($settingKey in $registryConfig[$category].Keys) { $setting = $registryConfig[$category][$settingKey] if ($setting.Enabled -and $setting.Path -and $setting.Name) { # Convert PowerShell path to registry path $regPath = $setting.Path -replace 'HKLM:', 'HKEY_LOCAL_MACHINE' -replace 'HKCU:', 'HKEY_CURRENT_USER' $regContent += "[$regPath]" # Determine registry value type $valueType = switch ($setting.Type) { 'DWord' { 'dword' } 'String' { '' } 'QWord' { 'qword' } 'Binary' { 'hex' } 'MultiString' { 'hex(7)' } 'ExpandString' { 'hex(2)' } default { 'dword' } } if ($valueType -eq '') { # String value $regContent += "`"$($setting.Name)`"=`"$($setting.Value)`"" } else { # Other types $value = $setting.Value if ($valueType -eq 'dword' -and $value -is [bool]) { $value = if ($value) { 1 } else { 0 } } $regContent += "`"$($setting.Name)`"=$valueType`:$([string]$value)" } if ($setting.Description) { $regContent += "; $($setting.Description)" } $regContent += "" } } } # Ensure output directory exists if (-not (Test-Path $OutputPath)) { New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null } # Save registry file $outputFile = Join-Path $OutputPath $outputFileName $regContent | Out-File -FilePath $outputFile -Encoding ASCII -Force if ($hasWriteAitherLog) { Write-AitherLog -Message "Generated registry file: $outputFile" -Level Information -Source 'New-AitherWindowsRegistryFile' } return $outputFile } catch { if ($hasWriteAitherLog) { Write-AitherLog -Message "Error generating registry file: $($_.Exception.Message)" -Level Error -Source 'New-AitherWindowsRegistryFile' -Exception $_ } else { Write-AitherLog -Level Error -Message "Error generating registry file: $($_.Exception.Message)" -Source 'New-AitherWindowsRegistryFile' -Exception $_ } throw } finally { # Restore original log targets $script:AitherLogTargets = $originalLogTargets } } } |