Конфигурация и адаптивные скрипты
Play ITЗагрузка интерактивного демо…
Зачем выносить данные из кода
Жёстко прошитые пути, списки серверов и пороги в .ps1 заставляют править код при каждом изменении инфраструктуры. Адаптивный скрипт читает данные конфигурации и применяет одну и ту же логику к разным окружениям (dev/stage/prod, филиалы, клиенты).
Разделение:
| Слой | Содержимое | Где хранить |
|---|---|---|
| Код | Алгоритм, проверки, обработка ошибок | .ps1, .psm1 в Git |
| Конфиг | Пути, списки, пороги, имена секретов (не сами секреты) | JSON/YAML рядом или в share |
| Секреты | Пароли, ключи | Секреты и безопасная автоматизация — SecretManagement |
JSON-конфигурация
Файл config.json рядом со скриптом:
{
"LogFolder": "C:\\App\\logs",
"ArchiveFolder": "D:\\Archives",
"OlderThanDays": 30,
"ArchivePrefix": "logs_",
"SecretNameSql": "SqlMonitor",
"NotifyEmail": "ops@example.com"
}
Загрузка и валидация:
Код ITЗагрузка примера кода…
| Практика | Зачем |
|---|---|
$PSScriptRoot для пути к конфигу | Работает из планировщика с -WorkingDirectory |
-Encoding utf8 | Кириллица в путях и письмах |
| Явная проверка обязательных ключей | Ранний понятный сбой вместо $null в середине |
Отдельный config.prod.json | Параметр -ConfigPath при деплое |
Секреты в JSON не кладут — только имя в SecretStore: "SecretNameSql": "SqlMonitor".
Data-driven функции
Одна функция обрабатывает запись конфигурации — объект или hashtable:
Код ITЗагрузка примера кода…
Конфиг со списком серверов:
{
"Servers": [
{ "Name": "web-01", "Host": "web-01.corp.local", "Port": 443 },
{ "Name": "db-01", "Host": "db-01.corp.local", "Port": 1433 }
]
}
Оркестратор:
$config = Get-Content "$PSScriptRoot\servers.json" -Raw | ConvertFrom-Json
$report = foreach ($srv in $config.Servers) {
Test-ServerHealth -Server $srv
}
$report | Where-Object { -not $_.Ok } | ForEach-Object { Write-Warning "$($_.Name): $($_.Detail)" }
Классы PowerShell
Для стабильной структуры данных в PowerShell 5+ / 7 можно объявить class:
class ServerRecord {
[string]$Name
[string]$HostName
[int]$Port = 443
[bool] TestPort() {
(Test-NetConnection -ComputerName $this.HostName -Port $this.Port -WarningAction SilentlyContinue).TcpTestSucceeded
}
}
$s = [ServerRecord]@{ Name = 'web-01'; HostName = 'web-01.corp.local' }
$s.TestPort()
Классы удобны в модулях с большим числом полей; для простых скриптов достаточно pscustomobject и JSON.
Конфиг внутри модуля
Константы уровня модуля (паттерн из практики работы с SQL через dbatools):
# Inside MyModule.psm1
$_SqlInstance = 'SRV-SQL\SQLEXPRESS'
$_Database = 'PoshAssetMgmt'
function Get-ModuleDatabase {
[CmdletBinding()]
param()
@{ SqlInstance = $_SqlInstance; Database = $_Database }
}
Имена с префиксом $script: или $_ показывают, что это настройки модуля, а не параметры каждого вызова. Для мультисредовых деплоев конфиг модуля генерируют при установке (DSC, Ansible, setup.ps1).
Чего не кладут в конфиг
| Неприемлемо | Альтернатива |
|---|---|
Invoke-Sqlcmd как строка в JSON | Имя функции + switch в коде или отдельные ключи Action: "SqlCheck" |
| Пароль в JSON | SecretName → Get-Secret |
| Произвольный PowerShell в JSON | Расширяемый набор известных действий в коде |
Конфиг описывает что делать; код — как.
Идempotency и повторный запуск
Скрипт идемпотентен, если повторный запуск не ломает состояние: второй раз создаёт тот же результат, а не дубликаты.
Приёмы:
Test-Path/Get-ServiceпередNew-Item/Start-Service;Ensure = 'Present'в DSC — см. Экосистема автоматизации на PowerShell;- возобновляемость с файлом прогресса — Рекомендации по написанию PowerShell-скриптов.
Конфиг vs база данных
| JSON / YAML | SQL |
|---|---|
| Мало записей, редкие правки, один админ | Много объектов, concurrent update, отчёты |
| Версионирование в Git | Центральный реестр серверов, CMDB |
PowerShell + SQL (модуль dbatools) — для инвентаризации и отчётов; теория SQL — 3.07. Для десятков серверов в JSON хватает; для тысяч — БД или API.
Пример структуры проекта
Deploy-App/
├── Deploy-App.ps1 # оркестратор
├── config.json # пути, флаги (в Git)
├── config.local.json # переопределения (в .gitignore)
└── lib/
└── AppTools.psm1 # функции из [125]
Запуск:
.\Deploy-App.ps1 -ConfigPath .\config.local.json
Чек-лист
| # | Вопрос |
|---|---|
| 1 | Секреты только по имени, не по значению в конфиге? |
| 2 | Конфиг валидируется при старте? |
| 3 | Повторный запуск безопасен (идемпотентность)? |
| 4 | Окружения различаются файлом конфига, а не правкой .ps1? |
| 5 | В JSON нет исполняемого кода? |
Дальше
| Тема | Материал |
|---|---|
| Ошибки, таймауты служб | Обработка ошибок и стратегии отладки |
| Azure Automation + конфиг в переменных | Экосистема автоматизации на PowerShell |
| Возобновляемые длинные задачи | Рекомендации по написанию PowerShell-скриптов |
| Pester для конфига | фаза 4 — статья 129 |