Public/Get-ModuleConfig.ps1
|
<# .SYNOPSIS Retrieves the configuration for a PowerShell module in the tcs suite. .DESCRIPTION The Get-ModuleConfig function finds the module that owns CommandPath (by walking up to the nearest module manifest) and returns its configuration as a hashtable. The configuration is built from: 1. The tcs.core defaults (Config/Module.Defaults.json in tcs.core). 2. The calling module's own Config/Module.Defaults.json, if it has one. 3. The user's settings file: <ApplicationData>/PowerShell/Config/<ModuleName>/Module.Config.json (the TCS_CONFIG_ROOT environment variable overrides the root folder). The settings file is created with the defaults the first time a module is loaded so users can edit it. After that it is only read; change settings with Set-ModuleConfig. The returned hashtable also contains ModuleName, ModulePath, ModuleVersion, ModuleConfigPath and ModuleConfigFilePath. .PARAMETER CommandPath The path of the calling script or module file, normally $PSCommandPath. When omitted, the path of the calling script is used. .INPUTS None This function does not accept pipeline input. .OUTPUTS System.Collections.Hashtable .EXAMPLE $config = Get-ModuleConfig -CommandPath $PSCommandPath Retrieves the configuration for the module that contains the calling script. .EXAMPLE if ((Get-ModuleConfig).UpdateWarning) { 'Update warnings are on' } Uses the calling script's path automatically. .NOTES Author: Nigel Tatschner Company: TheCodeSaiyan If the settings file cannot be written (for example a read-only profile), defaults are used for the session and a verbose message is written. .LINK Set-ModuleConfig #> function Get-ModuleConfig { [CmdletBinding()] [OutputType([hashtable])] param ( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [string]$CommandPath ) if (-not $PSBoundParameters.ContainsKey('CommandPath')) { $CommandPath = (Get-PSCallStack)[1].ScriptName if ([string]::IsNullOrEmpty($CommandPath)) { throw 'CommandPath was not supplied and the caller has no script path. Pass -CommandPath $PSCommandPath.' } } Write-Verbose "CommandPath: $CommandPath" $manifest = Find-ModuleManifestFile -StartPath $CommandPath if (-not $manifest) { throw "No module manifest (.psd1) was found in or above '$CommandPath'." } $moduleName = $manifest.BaseName $modulePath = $manifest.DirectoryName $moduleVersion = (Import-PowerShellDataFile -LiteralPath $manifest.FullName).ModuleVersion $moduleConfigPath = Join-Path -Path (Get-ModuleConfigRoot) -ChildPath $moduleName $moduleConfigFilePath = Join-Path -Path $moduleConfigPath -ChildPath 'Module.Config.json' Write-Verbose "Module '$moduleName' $moduleVersion at '$modulePath'; config file '$moduleConfigFilePath'" $defaults = Get-DefaultModuleConfig -ModulePath $modulePath $config = @{} foreach ($key in $defaults.Keys) { $config[$key] = $defaults[$key] } if (Test-Path -LiteralPath $moduleConfigFilePath) { try { $userConfig = Read-JsonFileAsHashtable -Path $moduleConfigFilePath foreach ($key in $userConfig.Keys) { $config[$key] = ConvertTo-ConfigValueType -Value $userConfig[$key] -DefaultValue $defaults[$key] } } catch { Write-Warning "The settings file '$moduleConfigFilePath' could not be read and defaults are being used. Fix or remove the file, or run 'Set-ModuleConfig -ModuleName $moduleName -Reset'. Error: $($_.Exception.Message)" } } else { try { Write-JsonFile -Path $moduleConfigFilePath -Data $defaults if ($config['Telemetry'] -eq $true -and $env:TCS_TELEMETRY_OPTOUT -notin @('1', 'true', 'yes')) { Write-Information -MessageData ("$moduleName collects anonymous usage telemetry (command name, duration, success and PowerShell/OS version; no user, machine or path details). " + "Turn it off with 'Set-ModuleConfig -ModuleName $moduleName -Telemetry `$false' or by setting the TCS_TELEMETRY_OPTOUT environment variable to 1.") -InformationAction Continue } } catch { Write-Verbose "Could not create '$moduleConfigFilePath'; using defaults for this session. $($_.Exception.Message)" } } # Values derived from the loaded module always win over anything stored in the file $config['ModuleName'] = $moduleName $config['ModulePath'] = $modulePath $config['ModuleVersion'] = $moduleVersion $config['ModuleConfigPath'] = $moduleConfigPath $config['ModuleConfigFilePath'] = $moduleConfigFilePath $script:ModuleConfigCache[$moduleName] = $config return $config } |