UserRegistryDSC.psm1
################## ## UserRegistry ## ################## <# .SYNOPSIS Returns the current value of a registry setting in all HKUSER hives. .PARAMETER Key Registry key where the setting is located. .PARAMETER ValueName Name of the value to get. #> function Get-UserRegistry { Param( [Parameter(Mandatory)][string]$Key, [Parameter(Mandatory)][string]$ValueName ) $UserProfileList = [System.Collections.Generic.List[PSCustomObject]]::new() $UserProfiles = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*" | Where-Object {$_.PSChildName -match "S-1-5-..-.*"} | Select-Object @{Name = 'SID' ; Expression = {$_.PSChildName}}, @{Name = 'UserHive'; Expression = {"$($_.ProfileImagePath)\NTuser.dat"}} | ForEach-Object {$UserProfileList.Add($_) | Out-Null} $DefaultUser = [PSCustomObject]@{ SID = 'DEF' UserHive = "$((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList").Default)\NTuser.dat" } $UserProfileList.Add($DefaultUser) $get = foreach ($UserProfile in $UserProfileList) { if (Test-Path $($UserProfile.UserHive)) { $Loaded = Test-Path "Registry::HKEY_USERS\$($UserProfile.SID)" if (-not $Loaded) { reg.exe LOAD "HKU\$($UserProfile.SID)" "$($UserProfile.UserHive)" | Out-Null } $UserKey = $Key.Replace('HKEY_CURRENT_USER',"Registry::HKEY_USERS\$($UserProfile.SID)") try { $Value = (Get-ItemProperty -Path $UserKey -Name $ValueName -ErrorAction Stop).$ValueName } catch { $Value = $null } [PSCustomObject]@{ SID = $($UserProfile.SID) UserHive = $($UserProfile.UserHive) ValueData = $Value } } } return $get } <# .SYNOPSIS Tests the current value of a registry setting in all HKUSER hives against the desired value and returns a boolean. If one or more users don't have the desired value the function will return $false. .PARAMETER Key Registry key where the setting is located. .PARAMETER ValueName Name of the value to get. .PARAMETER ValueData Desired value of the setting. #> function Test-UserRegistry { Param( [Parameter(Mandatory)][string]$Key, [Parameter(Mandatory)][string]$ValueName, [Parameter(Mandatory)][string]$ValueData ) $get = Get-UserRegistry -Key $this.Key -ValueName $this.ValueName foreach ($entry in $get) { if ($entry.ValueData -eq $ValueData) { $test = $true } else { $test = $false break } } if ($test -eq $true) { Write-Verbose -Message "$(Join-Path -Path $Key -ChildPath $ValueName) is in desired state" } return $test } <# .SYNOPSIS Changes the value of a registry setting in all necessary HKUSER hives to the desired value. .PARAMETER Key Registry key where the setting is located. .PARAMETER ValueName Name of the value to get. .PARAMETER ValueData Desired value of the setting. #> function Set-UserRegistry { Param( [Parameter(Mandatory)][string]$Key, [Parameter(Mandatory)][string]$ValueName, [Parameter(Mandatory)][string]$ValueType, [Parameter(Mandatory)][string]$ValueData ) $get = Get-UserRegistry -Key $this.Key -ValueName $this.ValueName $set = $get | Where-Object {$_.ValueData -ne $ValueData} foreach ($UserProfile in $set) { $UserKey = $Key.Replace('HKEY_CURRENT_USER',"Registry::HKEY_USERS\$($UserProfile.SID)") $Loaded = Test-Path "Registry::HKEY_USERS\$($UserProfile.SID)" if (-not $Loaded) { reg.exe LOAD "HKU\$($UserProfile.SID)" "$($UserProfile.UserHive)" | Out-Null } if ( -not (Test-Path $UserKey) ) { New-Item $UserKey -Force | Out-Null } try { Write-Verbose -Message "Changing Value for $(Join-Path -Path $UserKey -ChildPath $ValueName) from $($UserProfile.ValueData) to $ValueData" Set-Itemproperty -Path $UserKey -Name $ValueName -Value $ValueData -Type $ValueType -Force -ErrorAction Stop | Out-Null } catch { Write-Verbose -Message "Creating $(Join-Path -Path $Key -ChildPath $ValueName) with value $ValueData" New-ItemProperty -LiteralPath $UserKey -Name $ValueName -Value $ValueData -Type $ValueType -Force | Out-Null } if (-not $Loaded) { reg.exe UNLOAD "HKU\$($UserProfile.SID)" | Out-Null } } } <# .SYNOPSIS Class-based DSC resource to modify registry settings for all users in the HKEY_USERS hive. .PARAMETER Key Registry key where the setting is located. .PARAMETER ValueName Name of the value to get. .PARAMETER ValueData Desired value of the setting. #> [DscResource()] class UserRegistry { [DSCProperty(Key)] [string]$Key [DSCProperty(Key)] [string]$ValueName [DSCProperty(Mandatory)] [string]$ValueType [DSCProperty(Mandatory)] [string]$ValueData [DSCProperty(NotConfigurable)] [string]$SID [DSCProperty(NotCOnfigurable)] [string]$UserHive [UserRegistry] Get () { $get = Get-UserRegistry -Key $this.Key -ValueName $this.ValueName # The get method cannot return an array of UserReistry objects as UserRegistry object # This return construction is to ensure the get method shows if all keys are in desired state or not # If not, the value of the first item not in desired state is shown if (($get.ValueData | Select-Object -Unique) -ne $this.ValueData) { return [UserRegistry]@{ UserHive = '' SID = '' ValueData = $($get.ValueData | Where-Object {$_ -ne $this.ValueData})[0] } } else { return [UserRegistry]@{ UserHive = '' SID = '' ValueData = $($get.ValueData | Select-Object -Unique) } } } [void] Set () { $set = Set-UserRegistry -Key $this.Key -ValueName $this.ValueName -ValueType $this.ValueType -ValueData $this.ValueData } [bool] Test () { $test = Test-UserRegistry -Key $this.Key -ValueName $this.ValueName -ValueData $this.ValueData return $test } } |