WinRegOps.psm1
#Region './Private/Get-OpenBaseKey.ps1' -1 <# .SYNOPSIS Opens a registry hive on the local computer. .DESCRIPTION This function opens a registry hive on the local computer using the Microsoft.Win32.RegistryKey::OpenBaseKey method. It allows you to specify the registry hive and view (32-bit or 64-bit). By default, it uses the local machine view. .PARAMETER RegistryHive Specifies the registry hive to open (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER). .PARAMETER RegistryView Specifies the registry view to open (32-bit or 64-bit). Defaults to the system's default view (64-bit on a 64-bit OS, 32-bit on a 32-bit OS). .OUTPUTS Microsoft.Win32.RegistryKey The registry key object representing the opened registry hive. .EXAMPLE Get-OpenBaseKey -RegistryHive 'HKEY_LOCAL_MACHINE' Opens the HKEY_LOCAL_MACHINE hive on the local computer using the default registry view. .EXAMPLE Get-OpenBaseKey -RegistryHive 'HKEY_LOCAL_MACHINE' -RegistryView 'RegistryView32' Opens the HKEY_LOCAL_MACHINE hive on the local computer using the 32-bit view of the registry. .NOTES This function is a wrapper around the Microsoft.Win32.RegistryKey::OpenBaseKey method, providing an easier interface for opening registry hives locally. #> function Get-OpenBaseKey { param ( [Microsoft.Win32.RegistryHive]$RegistryHive, [Microsoft.Win32.RegistryView]$RegistryView = [Microsoft.Win32.RegistryView]::Default ) return [Microsoft.Win32.RegistryKey]::OpenBaseKey($RegistryHive, $RegistryView) } #EndRegion './Private/Get-OpenBaseKey.ps1' 39 #Region './Private/Get-OpenRemoteBaseKey.ps1' -1 <# .SYNOPSIS Opens a registry hive on a remote computer. .DESCRIPTION This function opens a registry hive on a remote computer using the Microsoft.Win32.RegistryKey::OpenRemoteBaseKey method. It allows you to specify the registry hive and the remote computer name. The remote computer must have the remote registry service running. .PARAMETER RegistryHive Specifies the registry hive to open (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER). .PARAMETER ComputerName Specifies the name of the remote computer on which the registry hive will be opened. .OUTPUTS Microsoft.Win32.RegistryKey The registry key object representing the opened registry hive on the remote computer. .EXAMPLE Get-OpenRemoteBaseKey -RegistryHive 'HKEY_LOCAL_MACHINE' -ComputerName 'RemotePC' Opens the HKEY_LOCAL_MACHINE hive on the remote computer 'RemotePC'. .NOTES This function is a wrapper around the Microsoft.Win32.RegistryKey::OpenRemoteBaseKey method, providing an easier interface for opening registry hives on remote computers. The remote registry service must be enabled on the target machine. #> function Get-OpenRemoteBaseKey { param ( [Microsoft.Win32.RegistryHive]$RegistryHive, [string]$ComputerName ) return [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RegistryHive, $ComputerName) } #EndRegion './Private/Get-OpenRemoteBaseKey.ps1' 34 #Region './Private/Invoke-RegCommand.ps1' -1 <# .SYNOPSIS Exports a specified registry key to a file using the `reg.exe` utility. .DESCRIPTION The `Invoke-RegCommand` function leverages the `reg.exe` command-line utility to export a specified registry key to a file. It accepts the registry path and export path as parameters, with default values provided by the environment variables `$ENV:Registry_Path` and `$ENV:Export_Path`. The function wraps this behavior in a PowerShell `Invoke-Command` call to execute the `reg.exe` command in the current session. .PARAMETER RegistryPath Specifies the path to the registry key that will be exported. If not provided, the function defaults to the value of the `$ENV:Registry_Path` environment variable. .PARAMETER ExportPath Specifies the file path where the registry export will be saved. If not provided, the function defaults to the value of the `$ENV:Export_Path` environment variable. .EXAMPLE Invoke-RegCommand -RegistryPath "HKCU\Software\MyKey" -ExportPath "C:\Export\mykey.reg" This example exports the registry key `HKCU\Software\MyKey` to the file `C:\Export\mykey.reg`. .EXAMPLE $ENV:Registry_Path = "HKLM\Software\MyApp" $ENV:Export_Path = "D:\Backup\myapp.reg" Invoke-RegCommand This example exports the registry key from the environment variable `Registry_Path` to the file path specified in `Export_Path`. .NOTES - The function requires the `reg.exe` utility, which is available on Windows operating systems by default. - The registry and export paths can be passed as parameters or set via environment variables. - Ensure the correct permissions are available for accessing the registry and writing to the specified output path. #> Function Invoke-RegCommand { param( [string]$RegistryPath = $ENV:Registry_Path, [string]$ExportPath = $ENV:Export_Path ) $Parameters = @{ Operation = 'EXPORT' Path = $RegistryPath OutputFile = $ExportPath } if (-not [string]::IsNullOrEmpty($Parameters.Path) -and -not [string]::IsNullOrEmpty($Parameters.OutputFile)) { $result = Invoke-Command -ScriptBlock { param($Parameters) ® $Parameters.Operation $Parameters.Path $Parameters.OutputFile } -ArgumentList $Parameters return $result } else { throw "Path or OutputFile is null or empty." } } #EndRegion './Private/Invoke-RegCommand.ps1' 60 #Region './Public/Backup-RegistryKey.ps1' -1 <# .SYNOPSIS Backs up a registry key from a specified computer to a backup file. .DESCRIPTION This function allows you to back up a registry key from a local or remote computer. It exports the registry key to a .reg file and saves it in the specified backup directory. It includes error handling for permission issues and remote access failures. .PARAMETER ComputerName The name of the computer from which the registry key will be backed up. Defaults to the local computer. .PARAMETER RegistryPath The full path of the registry key to be backed up. .PARAMETER BackupDirectory The directory where the backup file will be saved. Defaults to "C:\LHStuff\UserProfileTools\RegProfBackup". .EXAMPLE Backup-RegistryKey -RegistryPath 'HKLM\Software\MyApp' -BackupDirectory 'C:\Backups' Backs up the registry key 'HKLM\Software\MyApp' on the local computer to the 'C:\Backups' directory. .EXAMPLE Backup-RegistryKey -ComputerName 'RemotePC' -RegistryPath 'HKLM\Software\MyApp' 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' Backs up the registry key 'HKLM\Software\MyApp' from the remote computer 'RemotePC' to the default backup directory. .OUTPUTS System.Object .NOTES #> function Backup-RegistryKey { [outputType([System.Collections.Hashtable])] [CmdletBinding()] param ( [string]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [string]$RegistryPath, # Now dynamic, can back up any registry path [string]$BackupDirectory = "C:\LHStuff\UserProfileTools\RegProfBackup" ) # Determine if the operation is local or remote $isLocal = $ComputerName -eq $env:COMPUTERNAME # Generate the appropriate backup directory path (local or UNC) $backupDirectoryPath = Get-DirectoryPath -BasePath $BackupDirectory -ComputerName $ComputerName -IsLocal $isLocal # Ensure the backup directory exists locally or remotely Test-DirectoryExistence -Directory $backupDirectoryPath # Generate the backup file path with timestamp $backupPath = New-UniqueFilePath -Directory $backupDirectoryPath -Prefix "RegistryBackup" -Extension ".reg" # Get the full definition of Export-RegistryKey as a script block $exportRegistryFunction = Get-FunctionScriptBlock -FunctionName 'Export-RegistryKey' $scriptBlock = { param ($regExportPath, $registryPath, $exportFunction) # Load the Export-RegistryKey function & $exportFunction # Export the registry key return Export-RegistryKey -RegistryPath $registryPath -ExportPath $regExportPath } try { if ($isLocal) { # Local backup $backupResult = Export-RegistryKey -RegistryPath $RegistryPath -ExportPath $backupPath } else { # Remote backup using Invoke-Command $backupResult = Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock ` -ArgumentList $backupPath, $RegistryPath, $exportRegistryFunction } # Return the result of the backup if ($backupResult.Success) { return @{ Success = $true BackupPath = $backupPath Message = "Registry key backed up successfully." ComputerName = $ComputerName } } else { Write-Error $backupResult.Message return @{ Success = $false BackupPath = $null Message = $backupResult.Message ComputerName = $ComputerName } } } catch { # Handle exceptions and return failure Write-Error "Failed to back up the registry key '$RegistryPath' on $ComputerName. Error: $_" return @{ Success = $false BackupPath = $null Message = "Failed to back up the registry key '$RegistryPath'. Error: $_" ComputerName = $ComputerName } } } #EndRegion './Public/Backup-RegistryKey.ps1' 116 #Region './Public/Export-RegistryKey.ps1' -1 <# .SYNOPSIS Exports a registry key to a .reg file. .DESCRIPTION This function exports a registry key to a specified file path. It can be run on a local or remote computer. The function uses the 'reg export' command to perform the export operation and returns the success status. .PARAMETER RegistryPath The full path of the registry key to be exported. .PARAMETER ExportPath The file path where the exported .reg file will be saved. .PARAMETER ComputerName The name of the computer from which the registry key will be exported. Defaults to the local computer. .EXAMPLE Export-RegistryKey -RegistryPath 'HKCU\Software\MyApp' -ExportPath 'C:\Backups\MyApp.reg' Exports the registry key 'HKCU\Software\MyApp' to 'C:\Backups\MyApp.reg'. .OUTPUTS System.Object .NOTES #> function Export-RegistryKey { param ( [string]$RegistryPath, # The registry path to be exported [string]$ExportPath, # The path where the backup .reg file will be saved [string]$ComputerName = $env:COMPUTERNAME # The name of the computer (local or remote) ) try { #$exportCommand = "reg export `"$RegistryPath`" `"$ExportPath`"" $result = Invoke-RegCommand -RegistryPath $RegistryPath -ExportPath $ExportPath #Invoke-Expression $exportCommand #$exportCommand = ® export $RegistryPath $ExportPath $null = $result if ($LASTEXITCODE -eq 0) { return @{ Success = $true BackupPath = $ExportPath Message = "Registry key '$RegistryPath' successfully backed up to '$ExportPath'." ComputerName = $ComputerName } } else { return @{ Success = $false BackupPath = $null Message = "Failed to export registry key '$RegistryPath'." ComputerName = $ComputerName } } } catch { return @{ Success = $false BackupPath = $null Message = "Error during registry export for key '$RegistryPath'. $_" ComputerName = $ComputerName } } } #EndRegion './Public/Export-RegistryKey.ps1' 77 #Region './Public/Get-RegistryValue.ps1' -1 <# .SYNOPSIS Retrieves a value from a specified registry key. .DESCRIPTION This function retrieves a specific value from a registry key. It returns the value if found, or $null if the value does not exist. .PARAMETER Key The registry key object from which the value will be retrieved. .PARAMETER ValueName The name of the value to retrieve from the registry key. .EXAMPLE $key = Open-RegistryKey -RegistryPath 'HKLM\Software\MyApp' Get-RegistryValue -Key $key -ValueName 'Setting' Retrieves the value 'Setting' from the registry key 'HKLM\Software\MyApp'. .OUTPUTS System.Object .NOTES #> function Get-RegistryValue { [CmdletBinding()] param ( [Microsoft.Win32.RegistryKey]$Key, [string]$ValueName ) try { # Retrieve the specified registry value $value = $Key.GetValue($ValueName, $null) return $value } catch { Write-Error "Failed to retrieve value '$ValueName'. Error: $_" return $null } } #EndRegion './Public/Get-RegistryValue.ps1' 46 #Region './Public/Open-RegistryKey.ps1' -1 <# .SYNOPSIS Opens a registry key on a local or remote computer. .DESCRIPTION This function opens a registry key on a local or remote computer. It returns the registry key object if successful, or $null if the key does not exist or access is denied. .PARAMETER RegistryPath The full path of the registry key to be opened. .PARAMETER RegistryHive The registry hive to open (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER). Defaults to HKEY_LOCAL_MACHINE. .PARAMETER ComputerName The name of the computer where the registry key is located. Defaults to the local computer. .EXAMPLE Open-RegistryKey -RegistryPath 'HKLM\Software\MyApp' Opens the registry key 'HKLM\Software\MyApp' on the local computer. .EXAMPLE Open-RegistryKey -RegistryPath 'Software\MyApp' -RegistryHive 'HKEY_CURRENT_USER' -ComputerName 'RemotePC' Opens the registry key 'Software\MyApp' under HKEY_CURRENT_USER on the remote computer 'RemotePC'. .OUTPUTS Microsoft.Win32.RegistryKey .NOTES This function uses helper functions Get-OpenBaseKey and Get-OpenRemoteBaseKey to abstract the static calls for opening registry keys locally or remotely. #> function Open-RegistryKey { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$RegistryPath, [Parameter(Mandatory = $false)] [Microsoft.Win32.RegistryHive]$RegistryHive = [Microsoft.Win32.RegistryHive]::LocalMachine, [Parameter(Mandatory = $false)] [string]$ComputerName = $env:COMPUTERNAME ) try { # Determine if the operation is local or remote $isLocal = $ComputerName -eq $env:COMPUTERNAME $regKey = if ($isLocal) { Get-OpenBaseKey -RegistryHive $RegistryHive } else { Get-OpenRemoteBaseKey -RegistryHive $RegistryHive -ComputerName $ComputerName } # Open the subkey $openedKey = $regKey.OpenSubKey($RegistryPath, $true) if ($openedKey) { Write-Verbose "Successfully opened registry key at path '$RegistryPath' on '$ComputerName'." return $openedKey } else { Write-Warning "Registry key at path '$RegistryPath' not found on '$ComputerName'." return $null } } catch [System.Security.SecurityException] { Write-Error "Access denied to registry key '$RegistryPath' on '$ComputerName'. Ensure you have sufficient permissions." return $null } catch { Write-Error "Failed to open registry key at path '$RegistryPath' on '$ComputerName'. Error: $_" return $null } } #EndRegion './Public/Open-RegistryKey.ps1' 86 #Region './Public/Open-RegistrySubKey.ps1' -1 <# .SYNOPSIS Opens a subkey under a specified registry key. .DESCRIPTION This function opens a subkey under a specified registry key. If the subkey does not exist, it returns $null. .PARAMETER ParentKey The parent registry key object. .PARAMETER SubKeyName The name of the subkey to open. .EXAMPLE $key = Open-RegistryKey -RegistryPath 'HKLM\Software' Open-RegistrySubKey -ParentKey $key -SubKeyName 'MyApp' Opens the subkey 'MyApp' under the registry key 'HKLM\Software'. .OUTPUTS Microsoft.Win32.RegistryKey .NOTES #> function Open-RegistrySubKey { [outputType([Microsoft.Win32.RegistryKey])] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Microsoft.Win32.RegistryKey]$ParentKey, [Parameter(Mandatory = $true)] [string]$SubKeyName ) try { # Attempt to open the subkey from the parent registry key $subKey = $ParentKey.OpenSubKey($SubKeyName) # Return the opened subkey or $null if it doesn't exist return $subKey } catch { # Log the error and return $null in case of an exception Write-Error "Failed to open subkey '$SubKeyName'. Exception: $_" return $null } } #EndRegion './Public/Open-RegistrySubKey.ps1' 52 #Region './Public/Remove-RegistrySubKey.ps1' -1 <# .SYNOPSIS Removes a subkey from a registry key. .DESCRIPTION This function deletes a subkey from a specified parent registry key. It supports the -WhatIf and -Confirm parameters for safety. .PARAMETER ParentKey The parent registry key object. .PARAMETER SubKeyName The name of the subkey to be deleted. .PARAMETER ComputerName The name of the computer where the registry subkey is located. Defaults to the local computer. .EXAMPLE $key = Open-RegistryKey -RegistryPath 'HKLM\Software' Remove-RegistrySubKey -ParentKey $key -SubKeyName 'MyApp' Deletes the subkey 'MyApp' under the registry key 'HKLM\Software' on the local computer. .EXAMPLE $key = Open-RegistryKey -RegistryPath 'HKLM\Software' Remove-RegistrySubKey -ParentKey $key -SubKeyName 'MyApp' -WhatIf Shows what would happen if the subkey 'MyApp' were deleted, without actually performing the deletion. .OUTPUTS System.Boolean .NOTES #> function Remove-RegistrySubKey { [outputType([system.Boolean])] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true)] [Microsoft.Win32.RegistryKey]$ParentKey, # The parent registry key [string]$SubKeyName, # The subkey to be deleted [string]$ComputerName = $env:COMPUTERNAME # Default to local computer ) try { # Ensure ShouldProcess is used for safety with -WhatIf and -Confirm support if ($PSCmdlet.ShouldProcess("Registry subkey '$SubKeyName' on $ComputerName", "Remove")) { # Proceed with deletion $ParentKey.DeleteSubKeyTree($SubKeyName) Write-Verbose "Successfully removed registry subkey '$SubKeyName' on $ComputerName." return $true } else { # ShouldProcess returned false, so nothing is done Write-Verbose "Operation to remove registry subkey '$SubKeyName' on $ComputerName was skipped." return $false } } catch { Write-Error "Failed to remove the registry subkey '$SubKeyName' on $ComputerName. Error: $_" return $false } } #EndRegion './Public/Remove-RegistrySubKey.ps1' 70 |