Проект PowerShell, где поставить глобальные настройки?
Мы создаем более крупный проект с помощью PowerShell (набор скриптов / функций, который помогает нам настраивать некоторые среды / арендаторы SharePoint).
Многие функции должны повторно использовать настройки, которые хранятся в одном центральном месте.
Я не смог найти "наилучшую практику" того, как такой файл / местоположение настроек лучше всего создавать и структурировать.
Моя идея состоит в том, чтобы хранить глобальные настройки в отдельном файле (файле модуля), например Settings.psm1 с таким содержимым:
# Set vars
$global:scriptEnvironment = "SP2016HOSTINGDEV"
$global:logFileName = "z_Migration_to_SP2016.log"
$global:languageMapping = @{
"en-US" = 1;
"de-DE" = 2;
}
$global:oldWsps = @(
[WspFile]@{ Filename = "comapany.solution.wsp"; IsDeployable = $true; IsGloballyDeployable = $false; FullTrustBinDeployment = $false },
[WspFile]@{ Filename = "company.solution2.server.wsp"; IsDeployable = $true; IsGloballyDeployable = $false; FullTrustBinDeployment = $false }
)
...
А в других модулях / сценариях я всегда мог включить эти настройки следующим образом:
# Set vars
$scriptDirectory = Split-Path -parent $PSCommandPath
# Module import
Import-Module (Join-Path $scriptDirectory Settings.psm1) -Force -ErrorAction Stop
Import-Module (Join-Path $scriptDirectory Functions.psm1) -Force -ErrorAction Stop
# Functions
...
Так что это позволило бы мне использовать такие глобальные настройки в функциях внутри других файлов скриптов:
Function WriteLog
{
param
(
[System.String]$LogString = "",
[System.String]$LogLevel = ""
)
WriteLogToPath -LogFileName $global:logFileName -LogString $LogString -LogLevel $LogLevel
}
Это хороший подход? Или я не должен использовать файлы модулей для этого, и если нет, то какие файлы я должен использовать вместо этого?
3 ответа
Я, вероятно, собрал бы все ваши скрипты / функции в модуле и использовал бы реестр для хранения глобальных настроек. Прочитайте значения из реестра, когда модуль загружен, и имейте переменные со значениями по умолчанию для каждого параметра в вашем модуле, чтобы вы могли записать пропущенные значения в реестр.
Что-то вроде этого:
$modulename = Split-Path $PSScriptRoot -Leaf
$default_foo = 'something'
$default_bar = 'or other'
...
function Get-RegistrySetting($name) {
$path = "HKCU:\Software\${script:modulename}"
if (-not (Test-Path -LiteralPath $path)) {
New-Item -Path $path -Force | Out-Null
}
try {
Get-ItemProperty $path -Name $name -ErrorAction Stop |
Select-Object -Expand $name
} catch {
$val = Get-Variable -Scope script -Name "default_${name}" -ValueOnly -ErrorAction Stop
Set-ItemProperty $path -Name $name -Value $val
$val
}
}
$global:foo = Get-RegistrySetting 'foo'
$global:bar = Get-RegistrySetting 'bar'
...
Для переменных, которые вы используете только внутри вашего модуля, вы можете использовать script
сфера вместо global
объем.
Я бы не стал использовать реестр лично. Я согласен с использованием модулей, хотя. Мой подход заключается в том, чтобы использовать модуль манифеста (т.е. использовать файл.psd1, который по сути является хеш-таблицей значения ключа, содержащего метаданные о модуле), и указывать "корневой" модуль с ключом RootModule.
Область действия модуля теперь задается этим RootModule, и вы можете определить свои переменные там.
Вы можете разделить свои функции на "вложенные" модули (другой ключ файла манифеста), и они автоматически загружаются PowerShell в область действия корневого модуля, поэтому они должны иметь доступ к этим переменным.
Вы даже можете контролировать, какие переменные и функции экспортируются, используя ключи в этом файле манифеста.
Проверьте модуль Get-Configuration Powershell. Концепция проста, модуль добавляет переменную среды, в которой (в JSON) сохраняется определение типа и источника.
(dir env:PSGetConfiguration).Value
{
"Mode": "Xml",
"XmlPath": "C:\\Managers\\PSGetConfiguration.xml"
}
Файл конфигурации очень прост и содержит только элементы ключа и значения
cat $(Get-ConfigurationSource).XmlPath
<Configuration>
<conf key="ExampleKey" value="ExampleValue" />
<conf key="key" value="Value123" />
<conf key="remove" value="remove" />
</Configuration>
Модуль предоставляет две основные функции: Get-Configuration и Set-Configuration.
Set-Configuration -Key k1 -Value v1
Get-Configuration -Key k1
v1
При запуске модуль сохраняет XML в каталоге модуля, его можно изменить, изменив вручную переменную среды или используя команду Set-XmlConfigurationSource
Конфигурация SQL
По умолчанию модуль использует XML для хранения данных, но второй вариант - хранить данные в SQL. Настройка конфигурации довольно проста:
Set-SqlConfigurationSource -SqlServerInstance ".\sql2017" -SqlServerDatabase "ConfigDatabase" -SqlServerSchema "config" -SqlServerTable "Configuration"
После этого наш конфиг будет храниться в таблице SQL.
Код также доступен в github.