Skip to content

Commit

Permalink
cleaned up test and reformated readme (#8)
Browse files Browse the repository at this point in the history
* cleaned up test and reformated readme

* updated references to `Test-DirectoryExistence`
  • Loading branch information
LarryWisherMan committed Sep 11, 2024
1 parent 7754510 commit 52216c0
Show file tree
Hide file tree
Showing 16 changed files with 416 additions and 67 deletions.
14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added

- Added module icon and Psd1 private data
- Quality Tests for functions and comment based help

### Changed

- Updated Icon png
- Changed `WisherTools.Helpers` to a RequiredModule module vs a nested module

Expand All @@ -27,7 +30,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added unit test skeletons for all public functions in the WinRegOps

### Changed

- Added 'WisherTools.Helpers' to Nested Modules
- Updated `build.yaml` to exclude `Modules/WisherTools.Helpers` from code coverage analysis.
- ### Changed
- Refactored `Open-RegistryKey` function to use new helper functions `Get-OpenBaseKey` and `Get-OpenRemoteBaseKey` to abstract static method calls for opening registry keys locally or remotely. This improves testability and modularity of the code.

- Updated `build.yaml` to exclude `Modules/WisherTools.Helpers` from code
coverage analysis.

- Refactored `Open-RegistryKey` function to use new helper functions `Get-OpenBaseKey`
and `Get-OpenRemoteBaseKey` to abstract static method calls for opening registry
keys locally or remotely. This improves testability and modularity of the code.
160 changes: 147 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,154 @@
# WinRegOps

The WinRegOps module provides a comprehensive set of PowerShell functions to interact with the Windows registry, offering a simplified interface for common operations such as reading, writing, and deleting registry keys and values. It acts as a wrapper around the Microsoft.Win32.RegistryKey .NET class, extending its functionality for both local and remote registry operations.
<p align="center">
<img src="https://raw.githubusercontent.com/LarryWisherMan/ModuleIcons/main/WinRegOps.png"
alt="WinRegOps Icon" width="400" />
</p>

The module is designed to handle tasks like retrieving specific registry values, exporting registry keys, managing subkeys, and removing keys with enhanced error handling. It allows for seamless interaction with the Windows registry across various environments and use cases, such as system configuration, profile management, and application settings.
The **WinRegOps** module provides a comprehensive set of PowerShell functions to
interact with the Windows registry, offering a simplified interface for common
operations such as reading, writing, deleting, and exporting registry keys and
values. It extends the functionality of the `Microsoft.Win32.RegistryKey` .NET
class and enables local and remote registry operations with enhanced error
handling.

This module can be used independently or as a dependency for higher-level management modules, offering flexibility and reliability in registry operations.
This module is designed to handle registry tasks such as retrieving specific
values, managing subkeys, and exporting registry keys. Whether performing
configuration management tasks on local machines or managing registry settings
across multiple remote systems, **WinRegOps** simplifies interaction with the
Windows registry.

Key features:
The module can be used independently or as a dependency for higher-level system
configuration or management modules, providing flexibility and reliability in
registry management operations.

- Open registry keys (local and remote).
- Query and retrieve registry values.
- Create, delete, and backup registry keys and subkeys.
- Built-in error handling for permission issues and remote access.
- Works with multiple registry hives (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER).
---

Typical use cases include:
- Simplifying registry access in complex automation tasks.
- Providing a reliable registry management layer for other modules like ProfileManagement.
- Managing the lifecycle of registry keys during system configuration changes.
## **Key Features**

- **Open registry keys** on both local and remote machines using
`Get-OpenBaseKey` and `Get-OpenRemoteBaseKey`.
- **Query and retrieve registry values** using `Get-RegistryValue`.
- **Create, delete, and backup registry keys** and their subkeys with functions
like `New-RegistryKey`, `Remove-RegistrySubKey`, and `Backup-RegistryKey`.
- **Export registry keys** to files using the `reg.exe` utility, with the
`Export-RegistryKey` and `Invoke-RegCommand` functions.
- **Enhanced error handling** for permission issues and remote registry access.
- **Support for multiple registry hives**, such as `HKEY_LOCAL_MACHINE` and
`HKEY_CURRENT_USER`.

---

### **Typical Use Cases**

- **Automating system configuration**: Easily modify or retrieve registry
settings during system setup or maintenance tasks.
- **Profile and application management**: Use the module to configure profile
settings or manage application-specific registry values.
- **Registry backup and recovery**: Export critical registry keys before making
changes, ensuring that backups are available if needed.
- **Remote registry management**: Seamlessly access and modify registry keys on
remote systems without needing manual intervention.

---

### **Installation**

To install **WisherTools.Helpers**, you have two options:

1. **Install from PowerShell Gallery**
You can install the module directly from the [PowerShell Gallery](https://www.powershellgallery.com/packages/WinRegOps)
using the `Install-Module` command:

```powershell
Install-Module -Name WinRegOps
```

1. **Install from GitHub Releases**
You can also download the latest release from the [GitHub Releases page](https://github.com/LarryWisherMan/WinRegOps/releases).
Download the `.zip` file of the release, extract it, and place it in one of
your `$PSModulePath` directories.

---

### **Usage**

#### Example 1: Opening a Local Registry Key

Use the `Get-OpenBaseKey` function to open a registry hive on the local machine:

```powershell
$registryKey = Get-OpenBaseKey -RegistryHive 'HKEY_LOCAL_MACHINE'
```

This opens the `HKEY_LOCAL_MACHINE` hive on the local machine.

#### Example 2: Exporting a Registry Key

The `Export-RegistryKey` function allows you to export a registry key to a file
for backup purposes:

```powershell
Export-RegistryKey -RegistryPath "HKCU\Software\MyApp" -ExportPath "C:\Backup\MyApp.reg"
```

This exports the registry key `HKCU\Software\MyApp` to the file `C:\Backup\MyApp.reg`.

#### Example 3: Opening a Remote Registry Key

Use the `Get-OpenRemoteBaseKey` function to open a registry key on a remote
computer:

```powershell
$registryKey = Get-OpenRemoteBaseKey -RegistryHive 'HKEY_LOCAL_MACHINE' -ComputerName 'RemotePC'
```

This opens the `HKEY_LOCAL_MACHINE` hive on the remote computer `RemotePC`.

#### Example 4: Removing a Registry Subkey

You can remove a registry subkey using `Remove-RegistrySubKey`:

```powershell
$key = Open-RegistryKey -RegistryPath 'HKLM\Software'
Remove-RegistrySubKey -ParentKey $key -SubKeyName 'MyApp' -WhatIf
```

This will show what would happen if the `MyApp` subkey were deleted without
actually performing the deletion.

#### Example 5: Backing Up a Registry Key

The `Backup-RegistryKey` function allows you to back up a registry key to a
specified backup directory:

```powershell
Backup-RegistryKey -RegistryPath 'HKLM\Software\MyApp' -BackupDirectory 'C:\Backups'
```

This backs up the registry key `HKLM\Software\MyApp` to the `C:\Backups` directory.

---

### **Key Functions**

- **`Get-OpenBaseKey`**: Opens a registry hive on the local computer. Supports
both 32-bit and 64-bit views.
- **`Get-OpenRemoteBaseKey`**: Opens a registry hive on a remote computer.
Requires the remote registry service to be running.
- **`Get-RegistryValue`**: Retrieves a specific value from a registry key.
- **`Export-RegistryKey`**: Exports a registry key to a `.reg` file.
- **`Invoke-RegCommand`**: Executes a registry-related command using the `reg.exe`
utility. This function is used internally for registry exports and other commands.
- **`Backup-RegistryKey`**: Backs up a registry key from a local or remote
computer to a specified backup file.
- **`Remove-RegistrySubKey`**: Removes a subkey from a specified parent registry
key, supporting `-WhatIf` and `-Confirm` for safety.

---

### **Contributing**

Contributions are welcome! Feel free to fork this repository, submit pull
requests, or report issues. You can contribute by adding new features, improving
the existing code, or enhancing the documentation.
5 changes: 3 additions & 2 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Pester:
# Excludes one or more paths from being used to calculate code coverage.
ExcludeFromCodeCoverage:
- Modules/WisherTools.Helpers
- Holding/*

# If no scripts are defined the default is to use all the tests under the project's
# tests folder or source folder (if present). Test script paths can be defined to
Expand All @@ -103,8 +104,8 @@ Pester:
# - tests/Integration
ExcludeTag:
# - helpQuality
- FunctionalQuality
- TestQuality
#- FunctionalQuality
#- TestQuality
Tag:
CodeCoverageThreshold: 85 # Set to 0 to bypass
#CodeCoverageOutputFile: JaCoCo_$OsShortName.xml
Expand Down
89 changes: 89 additions & 0 deletions source/Holding/Invoke-RegCommandOld.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
function Invoke-RegCommand {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateSet("QUERY", "ADD", "DELETE", "COPY", "SAVE", "LOAD", "UNLOAD", "COMPARE", "EXPORT", "IMPORT", "RESTORE", "BACKUP", "RESTORE", "FLAGS")]
[string]$Operation,

[Parameter(Mandatory = $true)]
[string]$Path,

[string]$ValueName,

[string]$ValueData,

[ValidateSet("REG_SZ", "REG_DWORD", "REG_BINARY", "REG_MULTI_SZ", "REG_EXPAND_SZ")]
[string]$ValueType,

[string]$OutputFile,

[string]$ComputerName = $null,

[Switch]$PassThru
)

# Build argument list based on operation
$arguments = "$Operation `"$Path`""

if ($Operation -eq "EXPORT") {
if (-not $OutputFile) {
throw "You must specify an output file when using the EXPORT operation."
}
$arguments += " `"$OutputFile`" /y"
}
elseif ($ValueName) {
$arguments += " /v `"$ValueName`""
}

if ($ValueData) {
$arguments += " /d `"$ValueData`""
}

if ($ValueType) {
$arguments += " /t $ValueType"
}

# Local execution using Start-Process
if (-not $ComputerName) {
try {
Write-Verbose "Executing locally"
$processInfo = Start-Process -FilePath "reg.exe" -ArgumentList $arguments -NoNewWindow -PassThru -Wait
if ($processInfo.ExitCode -eq 0) {
Write-Host "Command executed successfully."
}
else {
Write-Error "Failed to execute reg command. Exit code: $($processInfo.ExitCode)"
}
}
catch {
Write-Error "Failed to execute reg command locally: $_"
}
}
else {
# Remote execution using Invoke-Command
try {
Write-Verbose "Executing remotely on $ComputerName"
$result = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
param($operation, $path, $valueName, $valueData, $valueType, $outputFile)
$arguments = "$operation `"$path`""
if ($operation -eq "EXPORT") {
$arguments += " `"$outputFile`" /y"
}
elseif ($valueName) {
$arguments += " /v `"$valueName`""
}
if ($valueData) {
$arguments += " /d `"$valueData`""
}
if ($valueType) {
$arguments += " /t $valueType"
}

Start-Process -FilePath "reg.exe" -ArgumentList $arguments -NoNewWindow -Wait -PassThru
} -ArgumentList $Operation, $Path, $ValueName, $ValueData, $ValueType, $OutputFile
}
catch {
Write-Error "Failed to execute reg command on $ComputerName`: $_"
}
}
}
59 changes: 59 additions & 0 deletions source/Private/Invoke-RegCommand.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<#
.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)
&reg $Parameters.Operation $Parameters.Path $Parameters.OutputFile
} -ArgumentList $Parameters

return $result
}
else
{
throw "Path or OutputFile is null or empty."
}
}
Loading

0 comments on commit 52216c0

Please sign in to comment.