PowerShell DSC: управление конфигурацией серверов

Что такое PowerShell DSC и зачем он нужен

PowerShell Desired State Configuration (DSC) — это декларативная платформа управления конфигурацией, встроенная прямо в Windows. Идея простая: вместо того чтобы писать длинные императивные скрипты в духе «установи это, потом настрой то, потом проверь третье», вы описываете, каким должен быть сервер — а DSC сам разбирается, как туда добраться и как удержать систему в этом состоянии.

Что реально решает DSC на практике:

  • Установка ролей и компонентов Windows — IIS, DNS, DHCP и всё что угодно из стандартного набора
  • Управление файлами, реестром, службами — то, с чем приходится возиться на каждом сервере
  • Настройка сетевых параметров без ручной беготни по серверам
  • Тихая установка пакетов MSI и EXE без интерактивных диалогов
  • Управление пользователями и группами — особенно удобно при типовых развёртываниях
  • Контроль соответствия корпоративным стандартам: сервер либо в нужном состоянии, либо DSC вас об этом предупредит

DSC работает на всех версиях Windows Server начиная с 2012 R2 — то есть покрывает практически весь актуальный парк. В PowerShell 7+ появился DSC v3, но если вы обслуживаете Windows-серверы, на практике используется DSC v2, встроенный в Windows PowerShell 5.1. Это и есть основная рабочая лошадка.

Написание первой конфигурации DSC

Конфигурация DSC — это блок PowerShell-кода, в котором вы объявляете желаемое состояние системы. Покажу на конкретном примере: поднимаем веб-сервер IIS с нужным сайтом.

Configuration WebServerSetup {
    # Импорт необходимых DSC-ресурсов
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xWebAdministration

    Node "WEB01" {
        # Установка роли IIS
        WindowsFeature IIS {
            Name   = "Web-Server"
            Ensure = "Present"
        }

        WindowsFeature IISManagement {
            Name      = "Web-Mgmt-Tools"
            Ensure    = "Present"
            DependsOn = "[WindowsFeature]IIS"
        }

        WindowsFeature ASPNet45 {
            Name      = "Web-Asp-Net45"
            Ensure    = "Present"
            DependsOn = "[WindowsFeature]IIS"
        }

        # Создание каталога сайта
        File SiteDirectory {
            DestinationPath = "C:\inetpub\mysite"
            Type            = "Directory"
            Ensure          = "Present"
        }

        # Настройка сайта IIS
        xWebsite MainSite {
            Name         = "MainSite"
            PhysicalPath = "C:\inetpub\mysite"
            State        = "Started"
            BindingInfo  = @(
                MSFT_xWebBindingInformation {
                    Protocol = "HTTP"
                    Port     = 80
                }
            )
            DependsOn = "[File]SiteDirectory", "[WindowsFeature]IIS"
        }

        # Остановка Default Web Site
        xWebsite DefaultSite {
            Name   = "Default Web Site"
            State  = "Stopped"
            Ensure = "Present"
            DependsOn = "[WindowsFeature]IIS"
        }
    }
}

# Компиляция конфигурации в MOF-файл
WebServerSetup -OutputPath "C:\DSC\WebServerSetup"

Команда WebServerSetup компилирует конфигурацию в MOF-файл (Managed Object Format) в указанной директории. MOF — это промежуточный формат. Именно его понимает движок DSC, который называется Local Configuration Manager.

Применение конфигурации к серверам

Есть два способа применять конфигурации: Push и Pull. Оба рабочие, но подходят для разных ситуаций.

Push-режим — администратор сам, руками, отправляет конфигурацию на нужный сервер:

# Применение MOF к локальному серверу
Start-DscConfiguration -Path "C:\DSC\WebServerSetup" -Wait -Verbose -Force

# Применение к удалённому серверу
Start-DscConfiguration -Path "C:\DSC\WebServerSetup" `
  -ComputerName "WEB01" -Credential $cred -Wait -Verbose

# Проверка текущего состояния
Get-DscConfigurationStatus
Test-DscConfiguration -Detailed

Pull-режим — серверы сами периодически ходят на центральный Pull Server и забирают актуальную конфигурацию. Если у вас больше десятка машин — это единственный вменяемый вариант. Руками не напушишь.

Настройка Local Configuration Manager

LCM — это агент DSC, который живёт на каждом сервере. Именно его настройки определяют, как сервер будет себя вести:

[DSCLocalConfigurationManager()]
Configuration LCMConfig {
    Node "WEB01" {
        Settings {
            RefreshMode          = "Push"    # или Pull
            ConfigurationMode    = "ApplyAndAutoCorrect"  # автоисправление дрейфа
            RebootNodeIfNeeded   = $true
            RefreshFrequencyMins = 30        # проверка каждые 30 мин
            ActionAfterReboot    = "ContinueConfiguration"
            AllowModuleOverwrite = $true
        }
    }
}

LCMConfig -OutputPath "C:\DSC\LCMConfig"
Set-DscLocalConfigurationManager -Path "C:\DSC\LCMConfig" -Verbose

Режим ApplyAndAutoCorrect — пожалуй, самая ценная фича DSC. Если кто-то зайдёт на сервер и руками поменяет настройку, LCM при следующей проверке просто вернёт всё обратно. Это и есть защита от «дрейфа конфигурации» — явления, от которого у администраторов начинается нервный тик после пары лет работы с большим парком серверов.

Работа с параметрами и конфигурационными данными

Жёстко вписывать имена серверов и параметры прямо в конфигурацию — это путь в никуда. Через месяц вы получите 50 почти одинаковых файлов. DSC решает это через разделение кода и данных с помощью Configuration Data:

# Файл ConfigData.psd1
$ConfigData = @{
    AllNodes = @(
        @{
            NodeName                    = "*"
            PSDscAllowPlainTextPassword = $false
            CertificateFile             = "C:\Certs\DscPublicKey.cer"
        },
        @{
            NodeName = "WEB01"
            Role     = "WebServer"
            SiteName = "Portal"
            SitePath = "C:\inetpub\portal"
            Port     = 443
        },
        @{
            NodeName = "WEB02"
            Role     = "WebServer"
            SiteName = "API"
            SitePath = "C:\inetpub\api"
            Port     = 8443
        }
    )
}

# Использование данных в конфигурации
Configuration WebServers {
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xWebAdministration

    Node $AllNodes.Where({$_.Role -eq "WebServer"}).NodeName {
        WindowsFeature IIS {
            Name   = "Web-Server"
            Ensure = "Present"
        }

        File SiteDir {
            DestinationPath = $Node.SitePath
            Type            = "Directory"
            Ensure          = "Present"
        }

        xWebsite Site {
            Name         = $Node.SiteName
            PhysicalPath = $Node.SitePath
            State        = "Started"
            BindingInfo  = MSFT_xWebBindingInformation {
                Protocol = "HTTPS"
                Port     = $Node.Port
            }
        }
    }
}

WebServers -ConfigurationData $ConfigData -OutputPath "C:\DSC\WebServers"

Один раз написали конфигурацию — и она спокойно работает на десятках серверов. Меняете только данные, код не трогаете.

Популярные DSC-ресурсы

Встроенные ресурсы DSC закрывают базовые задачи. Как только сценарии становятся сложнее — идите в PowerShell Gallery, там есть готовые модули на все случаи жизни:

МодульНазначениеУстановка
PSDesiredStateConfigurationFile, Registry, Service, Script, WindowsFeatureВстроен
NetworkingDscIP-адреса, DNS, firewall, маршрутыInstall-Module NetworkingDsc
ComputerManagementDscИмя компьютера, домен, планировщик, часовой поясInstall-Module ComputerManagementDsc
SqlServerDscУстановка SQL Server, настройка БД, AGInstall-Module SqlServerDsc
xWebAdministrationIIS сайты, пулы, привязкиInstall-Module xWebAdministration
ActiveDirectoryDscСоздание домена, OU, пользователейInstall-Module ActiveDirectoryDsc

Вот как выглядит настройка сети через NetworkingDsc — один из самых востребованных модулей в нашей практике:

Configuration NetworkSetup {
    Import-DscResource -ModuleName NetworkingDsc

    Node "SRV01" {
        IPAddress StaticIP {
            InterfaceAlias = "Ethernet"
            AddressFamily  = "IPv4"
            IPAddress      = "10.0.1.50/24"
        }

        DefaultGatewayAddress Gateway {
            InterfaceAlias = "Ethernet"
            AddressFamily  = "IPv4"
            Address        = "10.0.1.1"
        }

        DnsServerAddress DNS {
            InterfaceAlias = "Ethernet"
            AddressFamily  = "IPv4"
            Address        = "10.0.1.10", "10.0.1.11"
        }

        Firewall AllowRDP {
            Name      = "AllowRDP"
            Direction = "Inbound"
            Action    = "Allow"
            Protocol  = "TCP"
            LocalPort = "3389"
            Ensure    = "Present"
        }
    }
}

Настройка Pull Server

Pull Server — это централизованный веб-сервис, который раздаёт конфигурации и модули DSC-ресурсов. Серверы опрашивают его по расписанию и сами применяют то, что получили. Никакой ручной работы после первоначальной настройки.

# Установка Pull Server
Configuration PullServer {
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xPSDesiredStateConfiguration

    Node "DSC-PULL" {
        WindowsFeature IIS {
            Name   = "Web-Server"
            Ensure = "Present"
        }

        WindowsFeature DSCService {
            Name   = "DSC-Service"
            Ensure = "Present"
        }

        xDscWebService PullSvc {
            EndpointName            = "PSDSCPullServer"
            Port                    = 8080
            PhysicalPath            = "$env:SystemDrive\inetpub\PSDSCPullServer"
            CertificateThumbPrint   = $cert.Thumbprint
            ModulePath              = "$env:ProgramFiles\WindowsPowerShell\DscService\Modules"
            ConfigurationPath       = "$env:ProgramFiles\WindowsPowerShell\DscService\Configuration"
            RegistrationKeyPath     = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys"
            UseSecurityBestPractices = $true
        }
    }
}

# Регистрация ключа
"e37a45d2-9c71-4b8f-a1e5-3f2c89d4a6b7" | Out-File `
  "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys\RegistrationKeys.txt"

Клиент регистрируется на Pull Server через настройку LCM:

[DSCLocalConfigurationManager()]
Configuration RegisterPull {
    Node "WEB01" {
        Settings {
            RefreshMode = "Pull"
        }
        ConfigurationRepositoryWeb PullSvc {
            ServerURL          = "https://DSC-PULL:8080/PSDSCPullServer.svc"
            RegistrationKey    = "e37a45d2-9c71-4b8f-a1e5-3f2c89d4a6b7"
            ConfigurationNames = @("WebServerSetup")
        }
    }
}

Отчётность и мониторинг дрейфа

DSC записывает результат каждой проверки. Для централизованной отчётности можно поднять DSC Reporting Server, а можно просто собирать данные скриптом через PowerShell — что проще и работает без лишней инфраструктуры:

# Проверка состояния конфигурации на нескольких серверах
$servers = "WEB01", "WEB02", "SQL01", "DC01"
$results = Invoke-Command -ComputerName $servers -ScriptBlock {
    $status = Get-DscConfigurationStatus
    $test = Test-DscConfiguration -Detailed
    [PSCustomObject]@{
        Server         = $env:COMPUTERNAME
        Status         = $status.Status
        InDesiredState = $test.InDesiredState
        DriftedResources = ($test.ResourcesNotInDesiredState |
          Select-Object ResourceId).ResourceId -join "; "
        LastRun        = $status.StartDate
    }
}

$results | Format-Table -AutoSize

# Экспорт отчёта
$results | Export-Csv -Path "C:\Reports\DSC-Compliance.csv" -NoTypeInformation

Повесьте этот отчёт на Task Scheduler и настройте отправку письма, когда обнаружится сервер с InDesiredState = $false. На практике это экономит часы, которые иначе уходят на ручную проверку — особенно когда таких серверов под сотню.

Интеграция с Azure Automation DSC

Если среда гибридная — часть серверов в Azure, часть on-premise — посмотрите на Azure Automation State Configuration. По сути это облачный Pull Server с нормальным веб-интерфейсом. Регистрация сервера выглядит так:

# Установка агента и регистрация
$params = @{
    RegistrationUrl = "https://xxx.agentsvc.eus.azure-automation.net/accounts/xxx"
    RegistrationKey = "base64key=="
    ConfigurationMode = "ApplyAndAutoCorrect"
    RefreshFrequencyMins = 30
    NodeConfigurationName = "WebServerSetup.WEB01"
}
Register-AzAutomationDscNode @params

Azure Automation DSC бесплатен для первых 5 узлов, а взамен вы получаете графические дашборды с отчётами о соответствии конфигураций. Для небольшой гибридной инфраструктуры — честная сделка.

Часто задаваемые вопросы

DSC встроен в Windows и в Push-режиме не требует ни агентов, ни внешних серверов — просто включаете и работаете. Ansible и Chef, конечно, мощнее в гетерогенных средах, где вперемешку Linux и Windows. Но DSC глубже интегрирован с Windows и Active Directory — вещи, которые в корпоративной среде решают многое. Если у вас чисто Windows-инфраструктура, DSC — это очевидный выбор без лишних зависимостей.

Пароли в открытом виде в MOF-файлах — категорическое нет. Видел, как люди так делали. Заканчивается плохо. Используйте сертификаты: укажите CertificateFile в ConfigData, и DSC зашифрует все PSCredential открытым ключом прямо при компиляции MOF-файла. Агент на целевом сервере расшифрует их закрытым ключом — и нигде по пути пароль не болтается в открытом виде. Альтернатива — Azure Key Vault integration, если уже работаете в облаке.

DSC и GPO могут спокойно управлять одними и теми же параметрами — и это источник неожиданных конфликтов. GPO отрабатывает каждые 90 минут и молча перезапишет всё, что сделал DSC. Решение простое: жёстко разделите зоны ответственности ещё на берегу. Например, GPO занимается политиками безопасности, DSC — установкой ролей и приложений. Никакого пересечения, никаких сюрпризов.

Да, Linux DSC существует — через пакет omi-server и PowerShell DSC for Linux с nx-модулями. Но если честно, поддержка там ограничена самым базовым набором: файлы, пакеты, службы, скрипты. Для полноценного управления Linux-серверами лучше сразу смотреть в сторону Ansible или Puppet — там экосистема несравнимо богаче.

DSC сохраняет предыдущую конфигурацию — это реально выручает. Откат делается одной командой: Restore-DscConfiguration -Verbose. Она просто применит предыдущий MOF-файл, без лишних движений. Если же нужно убрать всё подчистую — сначала Remove-DscConfigurationDocument -Stage Current, Pending, Previous, потом перезапускаете LCM. Мы так делали после нескольких неудачных экспериментов с конфигурациями — работает чисто.

Нужна помощь с настройкой?

Если не хочется разбираться во всём этом самостоятельно — команда АйТи Фреш внедрит и настроит DSC под вашу инфраструктуру. Больше 15 лет в деле, обслуживание от 15 000 ₽/мес.

📞 Связаться с нами
#PowerShell DSC#Desired State Configuration#управление конфигурацией#Pull Server#MOF#DSC ресурсы#конфигурация серверов#автоматизация
Комментарии 0

Оставить комментарий

загрузка...