Public/Set-specRegistryKeyAndValue.ps1

function Set-SpecRegistryKeyAndValue {
    <#
    .SYNOPSIS
    Sets or updates a registry key and value.
 
    .DESCRIPTION
    The Set-SpecRegistryKeyAndValue function ensures that a specified registry key exists and sets or updates its associated value. If the registry key does not exist, it will be created. The value can be updated with the provided data. The value type can be either `String` or `DWord`.
 
    .PARAMETER KeyPath
    The full path to the registry key. This is a mandatory parameter.
 
    .PARAMETER ValueName
    The name of the registry value to set or update. This is a mandatory parameter.
 
    .PARAMETER ValueData
    The data to assign to the registry value. This is a mandatory parameter.
 
    .PARAMETER ValueType
    Specifies the type of the registry value. Valid options are 'String' or 'DWord'. This is a mandatory parameter.
 
    .EXAMPLE
    Set-SpecRegistryKeyAndValue -KeyPath 'HKCU:\Software\MyApp' -ValueName 'Setting1' -ValueData 'Enabled' -ValueType 'String'
 
    Sets or updates a String value named 'Setting1' with data 'Enabled' under the registry key 'HKCU:\Software\MyApp'.
 
    .EXAMPLE
    # Define an array of custom objects representing registry key/value pairs
    $registryItems = @(
        [PSCustomObject]@{ KeyPath = 'HKCU:\Software\MyApp'; ValueName = 'Setting1'; ValueData = 'Enabled'; ValueType = 'String' },
        [PSCustomObject]@{ KeyPath = 'HKCU:\Software\MyApp'; ValueName = 'MaxUsers'; ValueData = '150'; ValueType = 'DWord' },
        [PSCustomObject]@{ KeyPath = 'HKLM:\Software\AnotherApp'; ValueName = 'InstallPath'; ValueData = 'C:\Program Files\AnotherApp'; ValueType = 'String' }
    )
 
    # Pipe the array of custom objects into the function
    $registryItems | Set-SpecRegistryKeyAndValue
 
    Sends an array of custom objects to the Set-SpecRegistryKeyAndValue function to create or update the registry key/value pairs. Any errors that occur are displayed in the console and the function continues processing the remaining items.
 
    .EXAMPLE
    try {
        Set-SpecRegistryKeyAndValue -KeyPath 'HKLM:\SOFTWARE\OHTesting' -ValueName 'owen1' -ValueData 'test3' -ValueType String -ea stop
    } catch {
        Write-Host "An error occurred! $_" -ForegroundColor Magenta
    }
 
    Attempts to set or update a registry key and value. If an error occurs, the error is caught and displayed in the console.
 
    .NOTES
    Author: owen.heaume
    Version: - 1.0.0 - Initial release
                - 1.0.1 - Fix issue when creating DWord values
                - 1.0.2 - Allow blank ValueData
    #>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [String]$KeyPath,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [String]$ValueName,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [String]$ValueData,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('String', 'DWord')]
        [String]$ValueType
    )

    Begin {
        Write-Host 'Starting Set-SpecRegistryKeyAndValue function' -ForegroundColor DarkCyan
    }

    Process {
        Write-Host "Processing key path: $KeyPath" -ForegroundColor DarkCyan

        try {
            if (!(Test-Path -Path $KeyPath -ErrorAction Stop)) {
                Write-Host "Key path does not exist. Creating key: $KeyPath" -ForegroundColor DarkGray
                New-Item -Path $KeyPath -Force -ErrorAction Stop | Out-Null
            } else {
                Write-Host "Key path exists: $KeyPath. Skipping creation." -ForegroundColor DarkGray
            }
        } catch {
            Write-Error "Failed to create $KeyPath. $_"
            continue
        }

        try {
            # Set or update the registry value with the correct type
            if ($ValueType -eq 'String') {
                New-ItemProperty -Path $KeyPath -Name $ValueName -Value $ValueData -PropertyType 'String' -Force -ea stop | Out-Null
            } elseif ($ValueType -eq 'DWord') {
                # Ensure ValueData is cast to an unsigned 32-bit integer
                $intValueData = [uint32]$ValueData
                New-ItemProperty -Path $KeyPath -Name $ValueName -Value $intValueData -PropertyType 'DWord' -Force -ea stop | Out-Null
            }
            Write-Host "Value $ValueName updated with data $ValueData" -ForegroundColor DarkGray
        } catch {
            Write-Error "An error occurred updating the value $ValueName with data $ValueData. $_"
        }
    }

    End {
        Write-Host 'Completed processing: Set-SpecRegistryKeyAndValue' -ForegroundColor DarkGreen
    }
}