Главная

Tuesday, 9 March 2021

Desired State Configuration и с чем ее едят.

Всем привет.

Сегодня во многом работа системного администратора – это повторяющиеся операции, которые сводятся к созданию, удалению, изменению настроек, установки и настройки ролей и компонентов системы. Абсолютно естественным и правильным будет желание максимально автоматизировать такие задачи. Одним из инструментов, спешащих на помощь администратору, является PowerShell Desired State Configuration, которая впервые была представлена в Windows Server 2012 R2. О том, что это такое и как это может облегчить жизнь IT-специалиста рассказано в статье. Используя PowerShell DSC, вы описываете как хотите, чтобы ваша система выглядела в конечном итоге, и далее происходит ее автоматическая настройка в соответствии с заданными требованиями.

PowerShell Desired State Configuration – это очень мощный инструмент, который может значительно облегчить вам процесс настройки системы. PowerShell Desired State Configuration используется в двух осноных режимах: Push и Pull в зависимости от того кто является инциатором опроса сервера требуемых конфигураций. Более универсальным и безопасным является Pull-режим о котором и пойдет речь ниже. В этом случае клиент сам периодически "бегает" на сервер за требуемой конфигурацией для себя. Ниже схематически показаны клиенты ADM01 и ADM11 и их взаимодействие  с сервером DSC01.


Как  же это реализовать?

1. Подготовим материальную базу.

Прежде всего надо добавить на наш DSC-сервер модуль xPSDesiredStateConfiguration. Если наш сервер имеет доступ в интернет через прокси, тогда необходимо в мой профиль добавить учетные данные использовать для доступа  в интернет.

# INTERNET via PROXY

Читаем что у нас в текущем профиле:

$profile

Устанавливаем учетные данные для прокси:

[System.Net.WebRequest]::DefaultWebProxy.Credentials= [System.Net.CredentialCache]::DefaultCredentials

Устанавливаем регистрацию репозитория по умолчанию:

Register-PSRepository -Default

Register-PSRepository -Default -Name 'PSGallery' –SourceLocation 'https://www.powershellgallery.com/api/v2/' -Proxy 'https://clust01.forza.com:9090'

Читаем репозиторий:

Get-PSRepository

Проверяем наличие модуля xPSDesiredStateConfiguration:

Find-Module -Name xPSDesiredStateConfiguration

Инсталируем модуль xPSDesiredStateConfiguration:

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Verbose -Force

Сохраняем его в D:\Reports для дальнейшего использования:

Save-Module -Name xPSDesiredStateConfiguration -Path D:\Reports


Если на сервере нет интернета по технологическим причинам, то надо определить место где можно разместить файлы модуля xPSDesiredStateConfiguration вручную:

# NO INTERNET

$env:PSModulePath

Get-Module -ListAvailable

Если у вас сервер Windows Server 2012  R2, как был у меня, то для использования технологии DSC ему надо доставить серию патчей для фреймворка NET 5.1:

$PSVersionTable.PSVersion

Windows8.1-KB2883200-x64.msu

Windows8.1-KB2894029-x64.msu

Windows8.1-KB2894179-x64.msu

Windows8.1-KB2919355-x64.msu

Win8.1AndW2K12R2-KB3191564-x64.msu

Get-Module -ListAvailable


И, разумеется, поднять службу WinRM:

# WinRM start up

winrm quickconfig

Enable-PSRemoting -Force

Set-Item WSMan:\localhost\Client\TrustedHosts -Value *

Get-Item WSMan:\localhost\Client\TrustedHosts

Get-ExecutionPolicy


2. Разворачиваем наш DSC-сервер по Pull-схеме.

Этот этап можно рассматривать из двух частей: создание самого Pull Server  и создание Host Configuration для конкретного хоста.

##############################################

Section 1: execute this section on DSC Server только 1 раз!

##############################################

configuration Sample_xDscWebServiceRegistration
{
    param
    (
        [string[]]$NodeName = 'localhost',

        [ValidateNotNullOrEmpty()]
        [string] $certificateThumbPrint,

        [Parameter(HelpMessage='This should be a string with enough entropy (randomness) to protect the registration of clients to the pull server.  We will use new GUID by default.')]
        [ValidateNotNullOrEmpty()]
        [string] $RegistrationKey   # A guid that clients use to initiate conversation with pull server
    )

    Import-DSCResource -ModuleName PSDesiredStateConfiguration
    Import-DSCResource -ModuleName xPSDesiredStateConfiguration

    Node $NodeName
    {
        WindowsFeature DSCServiceFeature
        {
            Ensure = "Present"
            Name   = "DSC-Service"
        }

        xDscWebService PSDSCPullServer
        {
            Ensure                  = "Present"
            EndpointName            = "PSDSCPullServer"
            Port                    = 8080
            PhysicalPath            = "$env:SystemDrive\inetpub\PSDSCPullServer"
            CertificateThumbPrint   = $certificateThumbPrint
            ModulePath              = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
            ConfigurationPath       = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
            State                   = "Started"
            DependsOn               = "[WindowsFeature]DSCServiceFeature"
            RegistrationKeyPath     = "$env:PROGRAMFILES\WindowsPowerShell\DscService"
            AcceptSelfSignedCertificates = $true
            UseSecurityBestPractices     = $true
            Enable32BitAppOnWin64   = $false
        }

        File RegistrationKeyFile
        {
            Ensure          = 'Present'
            Type            = 'File'
            DestinationPath = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt"
            Contents        = $RegistrationKey
        }
    }
}

[guid]::newGuid()
# b0cad761-d079-4bdc-83c8-f9f68e8bd041

# To find the Thumbprint for an installed SSL certificate for use with the pull server list all certificates in your local store and then copy the thumbprint for the appropriate  certificate by reviewing the certificate subjects

Get-ChildItem -Path Cert:LocalMachine\MY
dir Cert:\LocalMachine\my

# Then include this thumbprint when running the configuration
Sample_xDscWebServiceRegistration -certificateThumbprint '9f9853d90be711ca2ca2825afbaf49d511a35432' -RegistrationKey 'b0cad761-d079-4bdc-83c8-f9f68e8bd041' -OutputPath c:\CreatePullServer

# Run the compiled configuration to make the target node a DSC Pull Server
Start-DscConfiguration -Path c:\CreatePullServer -Wait -Verbose
Get-DscConfiguration 

Sample_MetaConfigurationToRegisterWithLessSecurePullServer -RegistrationKey $RegistrationKey -OutputPath c:\CreatePullServer\TargetNodes

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

Test-DscConfiguration -Verbose

# Быстрая проверка что наш DSC-сервер работает правильно

http://log01.forza.com:8080/PSDSCPullServer.svc/



#############################################

Section 2: создаем задачу AddFile до управляемого хоста под именем WS31155. Ее можно менять и пересоздавать повторно много раз. Или создавать другие конфигурации для одного клиента.

#############################################

# Host Configuration

Configuration AddFile {

# Parameters, accepts a string value computername or defaults to localhost

    Param

    (

    [Parameter(Mandatory=$true)]

    [string[]]$ComputerName

    )

Import-DscResource –ModuleName PSDesiredStateConfiguration


    # Target Node

    Node $ComputerName {

        File TestFile {

        Ensure = 'Present'

        Type = 'File'

        DestinationPath = 'C:\TestFolder\TestFile111.txt'

        Contents = 'Radisson Impreza'

        Force = $true

        }

    }

}

# Generate the .MOF files

AddFile -ComputerName 'WS31155'

# Create a Checksum for the file listed above

$Guid = New-Guid | Select-Object -ExpandProperty Guid

$SourceMof = 'C:\Users\Username\AddFile\WS31155.mof'

$DestinationMof = 'C:\Program Files\WindowsPowerShell\DscService\Configuration\'+$Guid+'.mof'

Copy-Item $SourceMof $DestinationMof

New-DscChecksum $DestinationMof


3. Активируем наш DSC-клиент по Pull-схеме.

Конгфигурация клиента может быть по Имени конфигурации или по ID.

# Вариант PullClientConfig по имени

[DSCLocalConfigurationManager()]

configuration PullClientConfigNames

{

    Node localhost

    {

        Settings

        {

            RefreshMode = 'Pull'

            RefreshFrequencyMins = 30

            RebootNodeIfNeeded = $true

        }

        ConfigurationRepositoryWeb log01.forza.com

        {

            ServerURL = 'https://log01.forza.com:8080/PSDSCPullServer.svc'

            RegistrationKey = 'b0cad761-d079-4bdc-83c8-f9f68e8bd041'

            ConfigurationNames = @('AddFile')

        }

        ReportServerWeb log01.forza.com

        {

            ServerURL = 'https://log01.forza.com:8080/PSDSCPullServer.svc'

            RegistrationKey = 'b0cad761-d079-4bdc-83c8-f9f68e8bd041'

        }

    }

}


PullClientConfigNames

Set-DSCLocalConfigurationManager –ComputerName localhost –Path .\PullClientConfigNames –Verbose -Force

Get-DSCLocalConfigurationManager 

Update-DSCConfiguration -ComputerName localhost

Test-DSCConfiguration

# Вариант PullClientConfig по ID

Генерация  самого ID:

[System.Guid]::NewGuid()

который используется как ConfigurationID.

[DSCLocalConfigurationManager()]

configuration PullClientConfigID

{

    Node localhost

    {

        Settings

        {

            RefreshMode = 'Pull'

            ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'

            RefreshFrequencyMins = 30

            RebootNodeIfNeeded = $true

        }

        ConfigurationRepositoryWeb log01.forza.com

        {

            ServerURL = 'https://log01.forza.com:8080/PSDSCPullServer.svc'

        }

        ResourceRepositoryWeb log01.forza.com

        {

            ServerURL = 'https://log01.forza.com:8080/PSDSCPullServer.svc'

        }

        ReportServerWeb log01.forza.com

        {

            ServerURL = 'https://log01.forza.com:8080/PSDSCPullServer.svc'

        }

    }

}

PullClientConfigID

Set-DSCLocalConfigurationManager –ComputerName localhost –Path .\PullClientConfigID –Verbose

Get-DSCLocalConfigurationManager 

Update-DSCConfiguration -ComputerName localhost

Test-DSCConfiguration

Проверить состояние конкретной задачи можно зная ID = '330CD891-45E4-11EB-8517-B88584B86E93'

и выполнив с ним такой запрос в web-браузере:

https://log01.forza.com:8080/PSDSCPullServer.svc/Nodes(AgentId='330CD891-45E4-11EB-8517-B88584B86E93')/Reports

4. Читаем статистику по работе DSC-сервера.

function GetReport

{

    param

    (

        $AgentId = "$((glcm).AgentId)",

        $serviceURL = "https://log01.forza.com:8080/PSDSCPullServer.svc"

    )

    $requestUri = "$serviceURL/Nodes(AgentId= '$AgentId')/Reports"

    $request = Invoke-WebRequest -Uri $requestUri  -ContentType "application/json;odata=minimalmetadata;streaming=true;charset=utf-8" `

               -UseBasicParsing -Headers @{Accept = "application/json";ProtocolVersion = "2.0"} `

               -ErrorAction SilentlyContinue -ErrorVariable ev

    $object = ConvertFrom-Json $request.content

    return $object.value

}


$reports = GetReport

$reports[1]

$reportsByStartTime = $reports | Sort-Object {$_."StartTime" -as [DateTime] } -Descending

$reportMostRecent = $reportsByStartTime[0]

$statusData = $reports[1].Errors | ConvertFrom-Json

$statusData.ErrorMessage

$statusData = $reportMostRecent.StatusData | ConvertFrom-Json

$statusData

$statusData.ResourcesInDesiredState

$statusData

Таким образом технология DSC весьма интересная и выступает Microsoft-альтернативой таким инструментам как Ansible, Puppet или Chef. Насколько успешно, не берусь судить. На мой взгляд она на сегодня не совсем очевидна в настройке. Все свои файлы проведенного эксперимента я оставил здесь. Там же находится и электронная книга "The DSC Book". Но документация на сайте Microsoft обновляется чаще.

Успехов.

No comments:

Post a Comment

А что вы думаете по этому поводу?