main/util.ps1
# Pretty print function Print { [CmdletBinding()] param( [Parameter()] [ValidateNotNullOrEmpty()] [string] $Header = [string]::Empty, [Parameter(Mandatory)] [string] $Message, [Parameter()] [System.ConsoleColor] $Accent = (GetConfig('Module.AccentColor')), [Parameter()] [System.ConsoleColor] $MessageColor, [Parameter()] [switch] $NoNewLine = $false ) Write-Host '[' -NoNewline $caller = '<ScriptBlock>' if ($Header -ne [string]::Empty) { Write-Host $Header -ForegroundColor $Accent -NoNewline } else { Write-Host (GetConfig('Module.BaseName')) -ForegroundColor $Accent -NoNewline $caller = (Get-PSCallStack)[1].FunctionName if ($caller -ne '<ScriptBlock>') { Write-Host '.' -NoNewline Write-Host $caller -ForegroundColor $Accent -NoNewline } } $p = @{ 'Object' = "] $Message" 'NoNewLine' = $NoNewLine } if ($MessageColor -ne $null) { Write-Host '] ' -NoNewline $p['Object'] = $Message $p['ForegroundColor'] = $MessageColor } Write-Host @p } # Pretty warn function Warn { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Message ) $p = @{ 'Accent' = 'Yellow' 'MessageColor' = 'Yellow' 'Message' = 'Warning: ' 'NoNewLine' = $true } $caller = (Get-PSCallStack)[1].FunctionName if ($caller -ne '<ScriptBlock>') { $header = GetConfig('Module.BaseName') $header = "{0}.{1}" -f $header, $caller $p['Header'] = $header } Print @p Write-Host $Message } # Gets temp path according to the host function Get-TempPath { [CmdletBinding()] param( [Parameter()] [switch] $BasePath = $false ) $location = '' if (isWindows) { $location = $env:TEMP } else { $location = $env:TMPDIR if ($location -eq $null -or -not (Test-Path $location)) { $location = '/tmp' } } if ($BasePath) { Write-Output $location } else { $baseName = GetConfig('Module.BaseName') $location = Join-Path -Path $location -ChildPath $baseName if (-not (Test-Path $location)) { New-Item -ItemType Directory -Path $location | Write-Verbose } Write-Output $location } } # Returns the app data directory for each OS function GetAppDataPath { [CmdletBinding()] param( [Parameter()] [switch] $BasePath = $false ) $location = '' if (isWindows) { $location = $env:LOCALAPPDATA } else { $location = '~/Library/Preferences/' if ($location -eq $null -or -not (Test-Path $location)) { $location = '~/.local/share/' } } if (-not $BasePath) { $baseName = 'ConfigHive' $location = Join-Path -Path $location -ChildPath $baseName if (-not (Test-Path $location)) { New-Item -ItemType Directory -Path $location | Write-Verbose } } Write-Output $location } # Gets the path of the Hive Metadata function Get-HiveMetaPath { [CmdletBinding()] param() $localAppData = GetAppDataPath $metasDirectory = 'HiveMeta' $metasPath = Join-Path -Path $localAppData -ChildPath $metasDirectory if (-not (Test-Path $metasPath)) { New-Item -ItemType Directory -Path $metasPath | Write-Verbose } Write-Output $metasPath } # Gets Program Data folder function Get-ProgramDataPath { [CmdletBinding()] param() $ErrorActionPreference = 'Stop' $location = '' if (isWindows) { $location = $env:ProgramData if ($location -eq $null) { $location = Join-Path -Path $env:HOMEDRIVE -ChildPath 'ProgramData' } } else { $location = '/var/lib/' } $baseName = 'ConfigHive' $location = Join-Path -Path $location -ChildPath $baseName if (-not (Test-Path $location)) { New-Item -ItemType Directory -Path $location | Write-Verbose } Write-Output $location } # Gets the location of the implemented stores function Get-StorePath { [CmdletBinding()] param() $ErrorActionPreference = 'Stop' $appData = GetAppDataPath $storePathFolder = GetConfig('Module.StorePath.BaseName') $storesPath = Join-Path -Path $appData -ChildPath $storePathFolder if (-not (Test-Path $storesPath)) { New-Item -ItemType Directory -Path $storesPath | Write-Verbose } Write-Output $storesPath } # Utils to determine the OS function isWindows { [CmdletBinding()] param() if ($null -eq $PSVersionTable.OS -or $PSVersionTable.OS.Contains('Windows')) { Write-Output $true } else { Write-Output $false } } function isLinux { [CmdletBinding()] param() if ($PSVersionTable -eq $null) { Write-Output $false return } if ($PSVersionTable.OS -match 'Linux') { Write-Output $true return } Write-Output $false } # Module configuration reader function GetConfig { [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [ValidateNotNullOrEmpty()] [string] $Key ) $ErrorActionPreference = 'Stop' # Check first on non-overridable defaults $constConfig = [HashTable] $Script:DefaultConfig if ($constConfig.Keys -contains $Key) { Write-Output $constConfig[$Key] } elseif ($Script:ModuleLoadComplete -eq $true) { # Use service if we have user configurable options if available Write-Output (Get-ConfigValue -Key $Key -HiveName 'ConfigHive') } else { # otherwise use default overridable options $baseConfig = [HashTable] $Script:BaseConfigOverridable Write-Output $baseConfig[$Key] } } # Loads a configuration hive from metadata function LoadHive { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $HiveName ) $ErrorActionPreference = 'Stop' $hivesMeta = Get-HiveMetaPath $targetHiveMeta = Join-Path -Path $hivesMeta -ChildPath ("{0}.xml" -f $HiveName) if (-not (Test-Path $targetHiveMeta)) { $m = "Config Hive with name '{0}' was not found" -f $HiveName $err = New-Object ConfigHiveError -ArgumentList 'HiveMetaNotFound', $m throw($err) } #$policy = New-RetryPolicy -Policy Random -Milliseconds 5000 -Retries 3 #$hiveMeta = [HashTable] (Invoke-ScriptBlockWithRetry -Context { Import-Clixml -Path $targetHiveMeta } -RetryPolicy $policy) $hiveMeta = Import-Clixml -Path $targetHiveMeta # Validate existing properties $metaStructure = @( 'HiveName', 'OriginName', 'OriginData', 'SystemName', 'SystemData', 'UserName', 'UserData', 'SessionName', 'SessionData') $metaStructure | ForEach-Object { $prop = $_ if ($hiveMeta.Keys -notcontains $prop) { $m = "Hive metadata is not in the expected format, missing property: '{0}'" -f $prop $err = New-Object ConfigHiveError -ArgumentList 'CorrupedHiveMetadata', $m throw($err) } } if ($hiveMeta['HiveName'] -ne $HiveName) { $m = "Attempted to retrieve config hive metadata for '{0}' but got '{1}'" -f $HiveName, $hiveMeta['HiveName'] $err = New-Object ConfigHiveError -ArgumentList 'CorruptedHiveMetadata', $m throw($err) } $instanceHiveMeta = @{ 'HiveName' = $HiveName 'Origin' = (New-DataStore -StoreName $hiveMeta['OriginName'] -SerializedStoreData $hiveMeta['OriginData']) 'System' = (New-DataStore -StoreName $hiveMeta['SystemName'] -SerializedStoreData $hiveMeta['SystemData']) 'User' = (New-DataStore -StoreName $hiveMeta['UserName'] -SerializedStoreData $hiveMeta['UserData']) 'Session' = (New-DataStore -StoreName $hiveMeta['SessionName'] -SerializedStoreData $hiveMeta['SessionData']) } $Script:ActiveConfigHives[$HiveName] = [PSCustomObject] $instanceHiveMeta } # Describes the levels at which stores can operate, this helps the stores to differentiate each other within the same # Config Hive definition as well as to take specific actions for different levels i.e. System Level files vs User level enum CacheStoreLevel { Origin System User Session } |