Private/Import-ADTModuleDataFile.ps1
#----------------------------------------------------------------------------- # # MARK: Import-ADTModuleDataFile # #----------------------------------------------------------------------------- function Import-ADTModuleDataFile { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [ValidateScript({ if ([System.String]::IsNullOrWhiteSpace($_)) { $PSCmdlet.ThrowTerminatingError((New-ADTValidateScriptErrorRecord -ParameterName BaseDirectory -ProvidedValue $_ -ExceptionMessage 'The specified input is null or empty.')) } if (![System.IO.Directory]::Exists($_)) { $PSCmdlet.ThrowTerminatingError((New-ADTValidateScriptErrorRecord -ParameterName BaseDirectory -ProvidedValue $_ -ExceptionMessage 'The specified directory does not exist.')) } return $_ })] [System.String]$BaseDirectory, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String]$FileName, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [System.String]$UICulture, [Parameter(Mandatory = $false)] [System.Management.Automation.SwitchParameter]$IgnorePolicy ) # Internal function to process the imported data. function Update-ImportedDataValues { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = "This function is appropriately named and we don't need PSScriptAnalyzer telling us otherwise.")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [System.Collections.Hashtable]$DataFile, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.Collections.Hashtable]$NewData ) # Process the provided default data so we can add missing data to the data file. foreach ($section in $NewData.GetEnumerator()) { # Recursively process hashtables, otherwise just update the value. if ($section.Value -is [System.Collections.Hashtable]) { if (!$DataFile.ContainsKey($section.Key) -or ($DataFile.($section.Key) -isnot [System.Collections.Hashtable])) { $DataFile.($section.Key) = @{} } & $MyInvocation.MyCommand -DataFile $DataFile.($section.Key) -NewData $section.Value } else { $DataFile.($section.Key) = $section.Value } } } # Establish directory paths for the specified input. $moduleDirectory = $Script:ADT.Directories.Defaults.([regex]::Replace($BaseDirectory, '^.+\\', [System.String]::Empty)) $callerDirectory = $BaseDirectory # If we're running a release module, ensure the psd1 files haven't been tampered with. if (($badFiles = Test-ADTReleaseBuildFileValidity -LiteralPath $moduleDirectory)) { $naerParams = @{ Exception = [System.InvalidOperationException]::new("The module's default $FileName file has been modified from its released state.") Category = [System.Management.Automation.ErrorCategory]::InvalidData ErrorId = 'ADTDataFileSignatureError' TargetObject = $badFiles RecommendedAction = "Please re-download $($MyInvocation.MyCommand.Module.Name) and try again." } $PSCmdlet.ThrowTerminatingError((New-ADTErrorRecord @naerParams)) } # Import the default data first and foremost. $null = $PSBoundParameters.Remove('IgnorePolicy') $PSBoundParameters.BaseDirectory = $moduleDirectory $importedData = Import-LocalizedData @PSBoundParameters # Validate we imported something from our default location. if (!$importedData.Count) { $naerParams = @{ Exception = [System.InvalidOperationException]::new("The importation of the module's default $FileName file returned a null or empty result.") Category = [System.Management.Automation.ErrorCategory]::InvalidOperation ErrorId = 'ADTDataFileImportFailure' TargetObject = [System.IO.Path]::Combine($PSBoundParameters.BaseDirectory, $FileName) RecommendedAction = "Please ensure that this module is not corrupt or missing files, then try again." } $PSCmdlet.ThrowTerminatingError((New-ADTErrorRecord @naerParams)) } # Super-impose the caller's data if it's different from default. if (!$callerDirectory.Equals($moduleDirectory)) { $PSBoundParameters.BaseDirectory = $callerDirectory Update-ImportedDataValues -DataFile $importedData -NewData (Import-LocalizedData @PSBoundParameters) } # Super-impose registry values if they exist. if (!$IgnorePolicy -and ($policySettings = Get-ChildItem -LiteralPath "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PSAppDeployToolkit\$([System.IO.Path]::GetFileNameWithoutExtension($FileName))" -ErrorAction Ignore | Convert-RegistryKeyToHashtable)) { Update-ImportedDataValues -DataFile $importedData -NewData $policySettings } # Return the built out data to the caller. return $importedData } |