Tests/Unit/MSFT_xRegistryResource.TestHelper.psm1
<#
.SYNOPSIS Retrieves a registry key. .PARAMETER KeyPath The path to the registry key to be opened. Must include the registry hive. .PARAMETER WriteAccess Indicates that the registry key should be retrieved with write access. If this switch parameter is not provided, the key will be opened in read-only mode. #> function Get-RegistryKey { [CmdletBinding()] [OutputType([Microsoft.Win32.RegistryKey])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath, [switch] $WriteAccess ) $driveName = Split-Path -Path $KeyPath -Qualifier Write-Verbose -Message "Get-RegistryKey - Drive name: $driveName" $subKey = Split-Path -Path $KeyPath -NoQualifier Write-Verbose -Message "Get-RegistryKey - Subkey: $subKey" $drive = Get-Item -LiteralPath "${driveName}:\" Write-Verbose -Message "Get-RegistryKey - Drive: $drive" return $drive.OpenSubKey($subKey, $WriteAccess) } <# .SYNOPSIS Tests if a registry key exists. .PARAMETER KeyPath The path to the registry key to test for existence. Must include the registry hive. #> function Test-RegistryKeyExists { [CmdletBinding()] [OutputType([Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) return Test-Path -Path $KeyPath } <# .SYNOPSIS Tests if a registry key value exists. .PARAMETER KeyPath The path to the registry key that should contain the value to test for existence. Must include the registry hive. .PARAMETER ValueName The name of the value to test for existence. .PARAMETER ValueData The data the existing value should contain. .PARAMETER ValueType The value type that the registry value should have. #> function Test-RegistryValueExists { [CmdletBinding()] [OutputType([Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath, [Parameter(Mandatory = $true)] [ValidateNotNull()] [AllowEmptyString()] [String] $ValueName, [String] $ValueData, [ValidateNotNullOrEmpty()] [String] $ValueType ) try { $registryValue = Get-ItemProperty -Path $KeyPath -Name $ValueName -ErrorAction 'SilentlyContinue' Write-Verbose -Message "Test-RegistryValueExists - Registry key value: $registryKeyValue" $registryValueExists = $null -ne $registryValue Write-Verbose -Message "Test-RegistryValueExists - Registry value is not null: $registryValueExists" if (-not $registryValueExists) { return $false } $registryValue = $registryValue.$ValueName if ($PSBoundParameters.ContainsKey('ValueType')) { Write-Verbose -Message "Test-RegistryValueExists - Registry value type: $($registryValue.GetType().Name)" if ($ValueType -eq 'Binary') { $registryValueExists = $registryValueExists -and ($registryValue.GetType().Name -eq 'Byte[]') $registryValue = Convert-ByteArrayToHexString -Data $registryValue } else { $registryValueExists = $registryValueExists -and ($registryValue.GetType().Name -eq $ValueType) } } if ($PSBoundParameters.ContainsKey('ValueData')) { Write-Verbose -Message "Test-RegistryValueExists - Registry value data: $registryValue" $registryValueExists = $registryValueExists -and ($ValueData -eq $registryValue) } return $registryValueExists } catch { return $false } } <# .SYNOPSIS Creates a registry key. .PARAMETER KeyPath The path to the registry key to be created. Must include the registry hive. #> function New-RegistryKey { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $parentPath = Split-Path -Path $KeyPath -Parent if (-not (Test-RegistryKeyExists -KeyPath $parentPath)) { New-RegistryKey -KeyPath $parentPath } Write-Verbose -Message "New-RegistryKey - Creating new registry key at: $KeyPath" $null = New-Item -Path $KeyPath } <# .SYNOPSIS Creates a registry key. .PARAMETER KeyPath The path to the registry key to be created. Must include the registry hive. .PARAMETER ValueName The name of the value to add .PARAMETER ValueData The data of the value to add. .PARAMETER ValueType The type of the value to add. #> function New-RegistryValue { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath, [Parameter(Mandatory = $true)] [ValidateNotNull()] [AllowEmptyString()] [String] $ValueName, [Object] $ValueData, [ValidateNotNullOrEmpty()] [String] $ValueType ) if (-not (Test-Path -Path $KeyPath)) { New-RegistryKey -KeyPath $KeyPath } if ($ValueType -ieq 'Binary') { $convertedValueData = @() if (($ValueData.Length % 2) -eq 1) { $ValueData = '0' + $ValueData } for($index = 0; $index -lt $ValueData.Length - 1; $index += 2) { $convertedValueData += [Convert]::ToInt32($ValueData.Substring($index, 2), 16) } $ValueData = [Byte[]] $convertedValueData Write-Verbose -Message "New-RegistryValue - Binary data: $ValueData" } $null = New-ItemProperty -Path $KeyPath -Name $ValueName -Value $ValueData -PropertyType $ValueType } <# .SYNOPSIS Removes a registry key. .PARAMETER KeyPath The path to the registry key to remove Must include the registry hive. #> function Remove-RegistryKey { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $null = Remove-Item -Path $KeyPath -Recurse -Force } <# .SYNOPSIS Removes a registry value. .PARAMETER KeyPath The path to the registry key that contains the value to remove. Must include the registry hive. .PARAMETER ValueName The name of the value to remove. #> function Remove-RegistryValue { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath, [Parameter(Mandatory = $true)] [ValidateNotNull()] [AllowEmptyString()] [String] $ValueName ) $null = Remove-ItemProperty -Path $KeyPath -Name $ValueName -Force } <# .SYNOPSIS Removes the default registry value of a registry key. .PARAMETER KeyPath The path to the registry key to remove the default value of. #> function Remove-DefaultRegistryValue { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $registryKey = Get-RegistryKey -KeyPath $KeyPath -WriteAccess $registryKey.DeleteValue('') } <# .SYNOPSIS Mounts the registry drive of the given registry key path. .PARAMETER KeyPath The registry key path that contains the registry drive to mount. #> function Mount-RegistryDrive { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $driveName = (Split-Path -Path $KeyPath -Qualifier).TrimEnd(':') Write-Verbose -Message "Mount-RegistryDrive - Drive name: $driveName" $registryDriveRootMappings = @{ 'HKCR' = 'HKEY_CLASSES_ROOT' 'HKUS' = 'HKEY_USERS' 'HKCC' = 'HKEY_CURRENT_CONFIG' 'HKCU' = 'HKEY_CURRENT_USER' 'HKLM' = 'HKEY_LOCAL_MACHINE' } if ($registryDriveRootMappings.ContainsKey($driveName)) { # Abbreviated name was given. Use this as the new PSDrive name and the elongated name as the root $null = New-PSDrive -Name $driveName -Root $registryDriveRootMappings[$driveName] -PSProvider 'Registry' -Scope 'Script' } elseif ($registryDriveRootMappings.ContainsValue($driveName)) { $mappingKey = $null # Find the abbreviated key that goes with the given registry drive path foreach ($key in $registryDriveRootMappings.Keys) { if ($registryDriveRootMappings[$key] -ieq $driveName) { $mappingKey = $key break } } # Mount the PSDrive with the abbreviated name as the Name and the elongated name as the root $null = New-PSDrive -Name $mappingKey -Root $driveName -PSProvider 'Registry' -Scope 'Script' } else { throw "Mount-RegistryDrive - Invalid registry drive in key path provided: $KeyPath" } } <# .SYNOPSIS Removes a registry drive. .PARAMETER KeyPath The registry key path that contains the registry drive to remove. #> function Dismount-RegistryDrive { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $driveName = Split-Path -Path $KeyPath -Qualifier Write-Verbose -Message "Dismount-RegistryDrive - Drive name: $driveName" $null = Remove-PSDrive -Name $driveName -PSProvider 'Registry' -Scope 'Script' -Force } <# .SYNOPSIS Tests if the registry drive of he given registry key path is mounted. .PARAMETER KeyPath The registry key path that contains the registry drive to test. #> function Test-RegistryDriveMounted { [CmdletBinding()] [OutputType([Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $KeyPath ) $driveName = Split-Path -Path $KeyPath -Qualifier Write-Verbose -Message "Test-RegistryDriveMounted - Drive name: $driveName" $psDriveNames = (Get-PSDrive).Name.ToUpperInvariant() return $psDriveNames -icontains $driveName } <# .SYNOPSIS Helper function to convert a byte array to its hex string representation .PARAMETER Data Specifies the byte array to be converted. #> function Convert-ByteArrayToHexString { param ( [Parameter(Mandatory = $true)] [ValidateNotNull()] [System.Object] $Data ) $hexString = '' $Data | ForEach-Object { $hexString += ('{0:x2}' -f $_) } return $hexString } Export-ModuleMember -Function ` 'Get-RegistryKey', ` 'Test-RegistryKeyExists', ` 'Test-RegistryValueExists', ` 'New-RegistryKey', ` 'New-RegistryValue', ` 'Remove-RegistryKey', ` 'Remove-RegistryValue', ` 'Remove-DefaultRegistryValue', ` 'Mount-RegistryDrive', ` 'Dismount-RegistryDrive', ` 'Test-RegistryDriveMounted' |