Public/Invoke-ATMDRegistryUpdate.ps1
function Invoke-ATMDRegistryUpdate { <# .SYNOPSIS Обновляет значения в реестре Windows. .DESCRIPTION Обновляет значение в реестре на основании представленных параметрв в виде объектов / хеш таблиц (см. пример). .PARAMETER RegistryValues Объект с описание ключей реестра (см. пример). .PARAMETER PassThru Используйте параметр -PassThru, чтобы получить список обработаных ключей реестра и код завершения операций. .EXAMPLE $Registry = @{ keysToRemove = @('HKCU:\SOFTWARE\FluffyBeaver\keyToRemove1') keysToClear = @('HKCU:\SOFTWARE\ATMD\Script Operations\Network Places') keysToCreate = @('HKCU:\SOFTWARE\FluffyBeaver\keyToCreate1', 'HKCU:\SOFTWARE\FluffyBeaver\keyToCreate2') propertiesToRemove = @{ key = 'HKCU:\SOFTWARE\FluffyBeaver' propertyName = 'propertiesToRemove1' } propertiesToClear = @{ key = 'HKCU:\SOFTWARE\FluffyBeaver' propertyName = 'propertiesToClear1' } propertiesToSet = @( @{ key = 'HKCU:\SOFTWARE\ATMD\Environment Settings' propertyName = 'RecycleBinAge' propertyType = 'DWord' value = '3' description = 'Количество дней, которые файлы хранятся в Корзине' }, { key = 'HKCU:\SOFTWARE\ATMD\Environment Settings' propertyName = 'DownloadsAge' propertyType = 'DWord' value = '7' description = 'Количество дней, которые файлы хранятся в папке "Загрузки"' }, { key = 'HKCU:\SOFTWARE\ATMD\Environment Settings' propertyName = 'DesktopWallpaperImagePath' propertyType = 'String' value = 'C:\Tools\_aux\pic\Wallpaper.jpg' description = 'Путь к файлу картинке Рабочего стола' }, { key = 'HKCU:\SOFTWARE\ATMD\Environment Settings' propertyName = 'BgInfoSettingsPath' propertyType = 'String' value = 'C:\Tools\BGInfo\BGInfo.bgi' description = 'Путь к файлу параметров Backgroud Info (BGInfo)' }, { key = 'HKCU:\Keyboard Layout\Preload' propertyName = '1' propertyType = 'String' value = '00000419' description = 'Раскладка клавиатуры №419' }, { key = 'HKCU:\Keyboard Layout\Preload' propertyName = '2' propertyType = 'String' value = '00000409' description = 'Раскладка клавиатуры №409' } ) } Invoke-ATMDRegistryUpdate -RegistryValues $Registry -PassThru -Verbose .INPUTS Перечень ключей и значний реестра, которые необходимо модифицировать .OUTPUTS Функция возвращает объект, содержащий перечень удалнных, обнавленных и созданных ключей реестра и их параметров, если указан параметр -PassThru .NOTES Цель написания этой функции - возможность быстро править ключи реестра на основании описания, которое будте храниться в JSON-файле. Фактически, данная функция просто собирает вместе несколько командлетов Powershell, и ряд стандартный проверок, вроде Test-Path и т.п. Возвращаемый результат и коды ошибок описаны следующим образом: $RESULT_REMOVE_REGKEY_EXCEPTION = 128 #Ошибка при удалении ключа реестра. $RESULT_CLEAR_REGKEY_EXCEPTION = 64 #Ошибка при очистки ключа реестра. $RESULT_CREATE_REGKEY_EXCEPTION = 32 #Ошибка при создании ключа реестра. $RESULT_REMOVE_REGPROPERTY_EXCEPTION = 16 #Ошибка при удалении значений ключа реестра. $RESULT_CLEAR_REGPROPERTY_EXCEPTION = 8 #Ошибка при очистки значений ключа реестра. $RESULT_SET_REGPROPERTY_EXCEPTION = 4 #Ошибка при установки значений ключа реестра. $RESULT_NO_ERROR = 0 #Ошибок нет. $Result = [PSCustomObject]@{ RemovedKeys = @() CleanedKeys = @() CreatedKeys = @() RemovedProperties = @() CleanedProperties = @() SetProperties = @() ProblemItems = @() ExitCode = $RESULT_NO_ERROR } В массив $Result.ProblemItems попадают элементы, при работе с которыми возникли исключения. Остальные названия, думаю, понятны. Коды ошибок объединяются бинарными операциями. То есть, значение 96 указывает, что произошли ошибки при очистки ключа реестра и при создании ключа реестра: ($RESULT_CLEAR_REGKEY_EXCEPTION -bor $RESULT_CREATE_REGKEY_EXCEPTION) рабно 96. #> [CmdletBinding()] [OutputType([System.Object])] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [System.Object] $RegistryValues, [Parameter(Mandatory = $false, ValueFromPipeline = $false, Position = 1)] [switch] $PassThru = $false ) begin { # Для удобства чтения - коды ошибок в виде переменных с мнемоническими названиями. $RESULT_REMOVE_REGKEY_EXCEPTION = 128 #Ошибка при удалении ключа реестра. $RESULT_CLEAR_REGKEY_EXCEPTION = 64 #Ошибка при очистки ключа реестра. $RESULT_CREATE_REGKEY_EXCEPTION = 32 #Ошибка при создании ключа реестра. $RESULT_REMOVE_REGPROPERTY_EXCEPTION = 16 #Ошибка при удалении значений ключа реестра. $RESULT_CLEAR_REGPROPERTY_EXCEPTION = 8 #Ошибка при очистки значений ключа реестра. $RESULT_SET_REGPROPERTY_EXCEPTION = 4 #Ошибка при установки значений ключа реестра. $RESULT_NO_ERROR = 0 #Ошибок нет. $Result = [PSCustomObject]@{ RemovedKeys = @() CleanedKeys = @() CreatedKeys = @() RemovedProperties = @() CleanedProperties = @() SetProperties = @() ProblemItems = @() ExitCode = $RESULT_NO_ERROR } } process { try { if ($IsLinux) { throw [System.Configuration.ConfigurationException]::New('This operation system does not supported.') } #region Удаляем ключи foreach ($Key in $RegistryValues.keysToRemove) { try { if (Test-Path -Path $Key) { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Удаляем ключ $Key" Remove-Item -Path $Key -Recurse -ErrorAction Stop $Result.RemovedKeys += $Key } } catch { Write-Error -Message "При удалении ключа реестра $Key произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $Key $Result.ExitCode = $Result.ExitCode -bor $RESULT_REMOVE_REGKEY_EXCEPTION } } #endregion Удаляем ключи #region Очищаем ключи foreach ($Key in $RegistryValues.keysToClear) { try { if (Test-Path -Path $Key) { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Очищаем ключ $Key" Clear-Item -Path $Key -ErrorAction Stop $Result.CleanedKeys += $Key } } catch { Write-Error -Message "При очистки ключа реестра $Key произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $Key $Result.ExitCode = $Result.ExitCode -bor $RESULT_CLEAR_REGKEY_EXCEPTION } } #endregion Очищаем ключи #region Создаем ключи foreach ($Key in $RegistryValues.keysToCreate) { try { if (-not(Test-Path -Path $Key)) { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Создаем ключ $Key" New-Item -Path $Key -Force -ErrorAction Stop $Result.CreatedKeys += $Key } } catch { Write-Error -Message "При создании ключа реестра $Key произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $Key $Result.ExitCode = $Result.ExitCode -bor $RESULT_CREATE_REGKEY_EXCEPTION } } #endregion Создаем ключи #region Удаляем значения foreach ($Property in $RegistryValues.propertiesToRemove) { try { $CurrentValue = Get-ItemProperty -Path $Property.key -Name $Property.propertyName -ErrorAction SilentlyContinue if ($CurrentValue) { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Удаляем значение $($Property.propertyName) ключа $($Property.key)" Remove-ItemProperty -Path $Property.key -Name $Property.propertyName -ErrorAction Stop } else { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Значение $($Property.propertyName) ключа $($Property.key) не существует." } $Result.RemovedProperties += $($Property.key, $Property.propertyName -join '\') } catch { Write-Error -Message "При удалении значения $($Property.propertyName) ключа реестра $($Property.key) произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $($Property.key, $Property.propertyName -join '\') $Result.ExitCode = $Result.ExitCode -bor $RESULT_REMOVE_REGPROPERTY_EXCEPTION } } #endregion Удаляем значения #region Очищаем значения foreach ($Property in $RegistryValues.propertiesToClear) { try { $CurrentValue = Get-ItemProperty -Path $Property.key -Name $Property.propertyName -ErrorAction SilentlyContinue if ($CurrentValue) { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Очищаем значение $($Property.propertyName) ключа $($Property.key)" Clear-ItemProperty -Path $Property.key -Name $Property.propertyName -ErrorAction Stop } else { Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Значение $($Property.propertyName) ключа $($Property.key) не существует." } $Result.CleanedProperties += $($Property.key, $Property.propertyName -join '\') } catch { Write-Error -Message "При очистки значения $($Property.propertyName) ключа реестра $($Property.key) произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $($Property.key, $Property.propertyName -join '\') $Result.ExitCode = $Result.ExitCode -bor $RESULT_CLEAR_REGPROPERTY_EXCEPTION } } #endregion Очищаем значения #region Устанавливаем значения foreach ($Property in $RegistryValues.propertiesToSet) { try { $CurrentValue = Get-ItemProperty -Path $Property.key -Name $Property.propertyName -ErrorAction SilentlyContinue Write-Verbose -Message "<Invoke-ATMDRegistryUpdate> Устанавливаем значение $($Property.propertyName) ключа $($Property.key) в значение $($Property.value)" # Тут будет подготовка значения для записи в реестр. # Пока необходимость выявлена только для типа Binary switch ($Property.propertyType) { 'Binary' { $ValueToSet = $null $Property.value -split ',' | ForEach-Object -Process { $ValueToSet += [byte[]]($PSItem) } break } Default { $ValueToSet = $Property.value } } if (-not($CurrentValue)) { if (-not(Test-Path -Path $Property.key)) { New-Item -Path $Property.key -Force } New-ItemProperty -Path $Property.key -Name $Property.propertyName -PropertyType $Property.propertyType -Value $ValueToSet -ErrorAction Stop } else { Set-ItemProperty -Path $Property.key -Name $Property.propertyName -Value $ValueToSet -ErrorAction Stop } $Result.SetProperties += $($Property.key, $Property.propertyName -join '\') } catch { Write-Error -Message "При установкезначения $($Property.propertyName) ключа реестра $($Property.key) произшла ошибка $($PSItem.Exception.Message)" $Result.ProblemItems += $($Property.key, $Property.propertyName -join '\') $Result.ExitCode = $Result.ExitCode -bor $RESULT_SET_REGPROPERTY_EXCEPTION } } #endregion Устанавливаем значения } catch { # $PSCmdlet.ThrowTerminatingError($PSitem) Write-Error -Exception $PSItem.Exception } } end { if ($PassThru) { return $Result } } } # $Configuration = Get-Content -Path 'E:\Git\IaC\environment-config\LogonScripts\Atmd-LogonScript.json' -ErrorAction Stop | ConvertFrom-Json # #$FileDeployment = ($Configuration | Where-Object { ($_.optionClass -eq 'UserSpecific') -and ($_.userName -eq 'ATMD\ilichev') }).options.registry # $FileDeployment = ($Configuration | Where-Object { ($_.optionClass -eq 'general')}).options.registry # Invoke-ATMDRegistryUpdate -RegistryValues $FileDeployment -PassThru -Verbose |