只是另一种工具:通过所需状态配置了解服务配置 

期望状态配置(DSC)是服务器配置管理工具。使用它,您可以配置服务器(更改注册表,复制文件,安装和删除组件),监视设置的当前状态并快速回滚到基本设置。

对于那些遵循DevOps方法的人来说,DSC很有趣。该工具非常适合作为代码范式的“基础结构”:开发人员可以将其需求添加到配置中并将其包含在版本控制系统中,并且团队可以在不使用“手动”流程的情况下部署代码。

加上斯坦尼斯拉夫·布尔达科夫Raiffeisenbank我们将我们的经验与DSC引擎结合起来,分为两篇文章。首先,我们将分析工作的基本原理,并在实际示例中熟悉使用功能:

  • 使用DSC引擎“打开包装箱”,查看默认情况下有哪些资源,并显示从何处获取其他资源;
  • 让我们看看如何描述DSC中的配置。 
  • 我们将学习内置代理本地配置管理器如何在服务器上应用配置,展示如何使用元配置对其进行配置;
  • 让我们继续进行更复杂的配置案例:部分配置和存根配置。



DSC是一种轻量级且快速的引擎。例如,使用它,您可以更快地在虚拟机上安装.NET Framework 3.5。以下是帮助他加快服务配置过程的方法:

  • « » Windows PowerShell. 
    DSC PowerShell Windows Management Framework. Linux . , PowerShell. 
  • , . 
    , , , . DSC. 
  • , .
    DSC , . .

配置始终按顺序执行,没有条件和分支。因此,简单来说,DSC操作算法如下所示:

  1. 配置本地配置管理器(LCM)这是内置代理,负责将配置应用到服务器。我们告诉他声明的配置应如何工作以及以什么顺序工作。 
  2. 如果需要其他资源,请事先安装并连接它们。
  3. 我们以声明的形式编写配置顺序。 
  4. 我们以MOF文件的格式广播配置。
  5. 我们将配置发送到新部署的目标服务器或现有服务器。
  6. LCM接收配置(MOF文件)以及有关设置LCM本身的说明。
  7. 该配置将立即由我们的团队应用。


DSC体系结构的简化图。

我们将通过研究预定义的资源来开始与引擎相识。接下来,尝试编写配置。

DSC资源 


DSC资源类似于PowerShell模块。任何Windows服务器已经具有一组预定义的DSC资源;它们与PowerShell模块在同一目录中。可以通过Get-DscResourse cmdlet获取该列表。在Windows 10 1809上,此列表如下所示:
 
PS C:\windows\system32> Get-DscResource | Sort-Object -Property Name | ft ImplementedAs, Name -a
 
ImplementedAs Name
------------- ----
   PowerShell Archive
   PowerShell Environment
       Binary File
   PowerShell Group
    Composite GroupSet
       Binary Log
   PowerShell Package
   PowerShell PackageManagement
   PowerShell PackageManagementSource
    Composite ProcessSet
   PowerShell Registry
   PowerShell Script
   PowerShell Service
    Composite ServiceSet
       Binary SignatureValidation
   PowerShell User
   PowerShell WaitForAll
   PowerShell WaitForAny
   PowerShell WaitForSome
   PowerShell WindowsFeature
    Composite WindowsFeatureSet
   PowerShell WindowsOptionalFeature
    Composite WindowsOptionalFeatureSet
   PowerShell WindowsPackageCab
   PowerShell WindowsProcess

资源的名称使他们了解它们的工作方式: 

  • 存档-包含打包和解压缩存档;
  • 环境-具有环境变量;
  • 文件-带有文件;
  • 组-具有本地用户组;
  • 日志-带有日志;
  • 软件包-带有软件包;
  • 注册表-带有注册表项及其状态;
  • 服务-提供服务及其状态;
  • 用户-具有本地用户帐户;
  • WindowsFeature — Windows Server;
  • WindowsProcess — Windows;
  • Script —  PowerShell- . 3 : SetScript — -, TestScript — , , GetScript — .

通常,开箱即用的DSC资源是不够的。在这种情况下,您可以为标准模块之外的所有内容编写自己的脚本。为了不浪费时间,您可以使用其他开发人员编写的DSC资源。例如,从此处https://github.com/PowerShell/DscResources或从PSGallery。 
 
如何安装其他资源。我们使用Install-Module cmdlet 。安装资源只是沿$ env:PSModulePath环境变量中的路径之一复制资源文件。安装的资源在编译过程中不会自动连接,因此以后我们将在配置本身中另外连接它们。

要使用资源,您需要在本地和目标服务器上安装它。在本地基础结构中,安全策略通常禁止对服务器的Internet访问。在这种情况下,DSC服务器将无法从外部源加载其他资源。要发布包含模块的档案,我们部署了本地的NuGet存储库或常规的Web服务器。您可以通过将模块解压缩到C:\ Program Files \ WindowsPowerShell \ Modules \目录中来为Web服务器安装其他资源,
这正是Install-Module cmdlet所做的。

在第二篇文章中,我们将仔细研究“推”和“拉”模式的设置之间的差异。 

简单的配置解析


配置是服务器需要完成的简单,一致的描述。简单的DSC配置如下所示: 

Configuration EnvironmentVariable_Path
{
param ()
Import-DscResource -ModuleName 'PSDscResources'
Node localhost
    {
        Environment CreatePathEnvironmentVariable
        {
            Name = 'TestPathEnvironmentVariable'
            Value = 'TestValue'
            Ensure = 'Present'
            Path = $true
            Target = @('Process', 'Machine')
        }
    }
}
EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"

对于她的示例,让我们看看配置的组成。Configuration

是PowerShell函数的一种特殊类型,它描述了我们想要获得的东西。  块内包含: 



  • 参数具有可以在内部使用的参数; 
  • 通过其他PowerShell调用进行阻止。在配置开始时,我们总是运行Import-Resource来连接其他资源。
  • 使用特定Node $ servername 服务器的设置阻止。 

Node块内,我们指示将在特定服务器上配置哪些资源。在上面的示例中,这是使用常规环境资源创建环境变量的。

让我们更深入地看一下,并通过Get-DscResource -Name Environment -Syntax命令查看特定资源的语法:
 

PS C:\windows\system32> Get-DscResource -Name Environment -Syntax
Environment [String] #ResourceName
{
    Name = [string]
    [DependsOn = [string[]]]
    [Ensure = [string]{ Absent | Present }]
    [Path = [bool]]
    [PsDscRunAsCredential = [PSCredential]]
    [Value = [string]]
}

在此示例中: 

  • 名称 -环境变量的名称。
  • DependsOn中,我们指定对其他资源的依赖关系。重要的是要记住,直到完成此处指定的资源,该操作才会执行。 
  • 在“ 确保”中,我们指定配置条件。如果没有这样的变量,那么我们将创建它。如果存在,则不会配置此资源。
  • 路径指定是否在环境变量中包含的路径。 
  • PsDscRunAsCredential中指定凭据。
  • -环境变量的值。 
  • 目标可以以相对于向其应用配置的指示。

如何开始编译我们只是通过带有必要参数的名称来调用配置。结果将是一个mof文件,DSC引擎会进一步使用该文件来配置特定的服务器:
 
PS C:\windows\system32> EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       25.02.2020     14:05           2172 localhost.mof

配置本地配置管理器


本地配置管理器负责应用我们编译成mof文件的配置。是他监视配置中定义的状态的保留。如果系统离开此状态,则LCM会调用资源中的代码以恢复指定的状态。 

让我们通过Get-DscLocalConfigurationManager查看本地配置管理器设置:
 
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
ActionAfterReboot              : ContinueConfiguration
AgentId                        : 1FB3A2EE-57C9-11EA-A204-58A023EF3A48
AllowModuleOverWrite           : False
CertificateID                  :
ConfigurationDownloadManagers  : {}
ConfigurationID                :
ConfigurationMode              : ApplyAndMonitor
ConfigurationModeFrequencyMins : 15
Credential                     :
DebugMode                      : {NONE}
DownloadManagerCustomData      :
DownloadManagerName            :
LCMCompatibleVersions          : {1.0, 2.0}
LCMState                       : Idle
LCMStateDetail                 :
LCMVersion                     : 2.0
StatusRetentionTimeInDays      : 10
SignatureValidationPolicy      : NONE
SignatureValidations           : {}
MaximumDownloadSizeMB          : 500
PartialConfigurations          :
RebootNodeIfNeeded             : False
RefreshFrequencyMins           : 30
RefreshMode                    : PUSH
ReportManagers                 : {}
ResourceModuleManagers         : {}
PSComputerName                 :

  • RefreshMode包含LCM操作模式-推或拉。我们将在第二篇文章中进一步讨论模式。
  • ConfigurationMode显示当前配置应用程序模式。在我们的例子中,它是ApplyAndMonitor-应用和跟踪更改。ApplyOnly模式也可用(LCM将不跟踪配置更改)和ApplyAndAutocorrect模式(LCM不仅将跟踪更改,还将其回滚到基本配置)。
  • RebootNodeIfNeeded-可以在配置完成后重新引导服务器,必要时可以应用设置。 
  • ConfigurationModeFrequencyMins-修正LCM多久检查一次配置更改。

在元配置中更改LCM设置。这是她的例子:
 

Configuration LCMConfiguration
{
   Node Localhost
   {
       LocalConfigurationManager
       {
           RebootNodeIfNeeeded = $True
       }
   }
}
LCMConfiguration

与最新版本的WMF相同,但带有注释:


 
[DSCLocalConfigurationManager()]
Configuration LCMConfiguration
{
   param
   (
       [string[]]$Server = "localhost"
   )

 

#  LCM:
#  ,  
# : PUSH
#    30 
   Node $Server
   {
       Settings
       {
           RebootNodeIfNeeded = $True
           RefreshMode        = 'Push'
           RefreshFrequencyMins = 30
       }
   }
}


#   
LCMConfiguration -Server "localhost" -OutputPath "C:\DSC\MetaConfigurations\EnvironmentVariable_Path\"

具有元配置功能在编写元配置时,我们使用与常规DSC配置相同的块。例外是LocalConfigurationManager(v4)内部块或特定服务器的DSCLocalConfigurationManager(v5)属性。它们描述了所有必要的设置。 

元配置也被编译到mof文件中,但是要使用它,将使用Set-DSCLocalConfigurationManager cmdlet,而不使用Start-DSCConfiguration。
 
PS C:\windows\system32> LCMConfiguration -OutputPath C:\EnvironmentVariable_Path\
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       26.02.2020     20:05           1016 Localhost.meta.mof

 

PS C:\windows\system32> Set-DscLocalConfigurationManager -Path C:\EnvironmentVariable_Path\
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
RebootNodeIfNeeded             : True

从理论上讲,没有什么可以阻止我们将LCM的配置和常规资源合并到同一配置中。但为简单起见,建议将配置和元配置的拼写和应用程序分开。

部分配置 


部分配置-几个配置,一个接一个地执行。当几个团队从事这项服务时,它们很有用。每个命令都指示其服务部分的设置,然后部分配置将顺序应用所有设置。在LCM设置中,我们在PartialConfigurations中指定部分配置。 

在部分配置中,我们必须考虑简单的DSC逻辑。引擎不允许分支,因此需要额外的资源来满足各种条件。我们将通过一些示例对此进行分析。 

假设我们要确保将配置交付给服务器,并根据以下算法进行操作:

  1. 首先,检查服务器上是否安装了必要的模块。
  2. 我们执行配置,这将使服务器进入所需状态。

这是内部包含多个连续配置的元配置的外观:


#   
[DSCLocalConfigurationManager()]
configuration MetaPushConfig
{
param
   (
       [ValidateNotNullOrEmpty()]
       [string] $NodeName = 'localhost'
   )

 

   Node $NodeName
   {
 	
 #      LCM,    
       PartialConfiguration ModulesDownloadConfig
       {
               Description = 'Download and install modules'
               RefreshMode = 'Push'
       }

 

       #        
       PartialConfiguration ServerOSConfig
       {
               DependsOn = "[PartialConfiguration]ModulesDownloadConfig"
               Description = 'Configuration'
               RefreshMode = 'Push'
       }

 

       #   LCM
       Settings
       {
               RefreshMode        = 'Push'
               RefreshFrequencyMins = 30
               RebootNodeIfNeeded = $true
       }
   }
}

 
 

#  
MetaPushConfig -NodeName "NewServer.contoso.com" -OutputPath c:\DSC\MetaConfigurations

 

#      
$cred = (Get-Credential -UserName Administrator -Message "Enter admin credentials")

 

#  LCM   
Set-DscLocalConfigurationManager -ComputerName "NewServer.contoso.com" -Credential $cred -Path "c:\DSC\MetaConfigurations" -Verbose -Force

 

#  
Publish-DscConfiguration c:\DSC\Configurations\ModulesDownloadConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force
Publish-DscConfiguration c:\DSC\Configurations\ServerOSConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force

 

#    
Start-DscConfiguration -UseExisting -ComputerName "NewServer.contoso.com" -Credential $cred -Force -Verbose

配置的第一部分显示“ 下载并安装模块”:下载并安装必要的资源。ServerOSConfig的第二部分将服务器置于所需状态。DSC直接性的细微差别在这里: 

  1. 如果配置的第一部分最初返回FALSE并完全完成,则LCM将不会进入第二配置。根据DSC逻辑,首先需要将服务器置于所述的第一个状态。 
    如何看待:运行配置两次或在脚本中自动执行整个过程。
  2. 如果服务器在安装任何组件后都需要重新启动,则在我们自己重新启动服务器之前,配置将不会继续进行。即使我们告诉LCM RebootNodeIfNeeeded = $ True,代理也会在配置期间等待我们的解决方案。
    如何处理:xPendingReboot资源可用于救援,该资源在重新引导时控制注册表项。此资源为我们重新启动服务器。

这是服务器无法访问Internet时在“血腥企业”方案中下载和安装资源的示例配置。它假定存在一个Web服务器,在该服务器中,可以通过http协议向所有人提供预下载的资源。


Configuration ModulesDownloadConfig
{
   param
   (
       [string[]]$Server
   )

 

   #   
   Import-DscResource -ModuleName "PSDesiredStateConfiguration"

 

   #  
   Node $Server
   {
       #  IE Security
       Registry DisableIEESC-Admin {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = 0
           ValueType = "DWORD"
       }

 

       Registry DisableIEESC-User {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = "0"
           ValueType = "DWORD"
       }

 

	
 #    ,    
       File CreateDistribDir {
           Ensure          = "present"
           DestinationPath = "C:\Install\PSModules"
           Type            = "Directory"
       }

 

	
 #   NetworkingDsc (<a href="https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004">https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004</a>),      
       Script NetworkingDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/NetworkingDsc.zip" -OutFile "C:\Install\PSModules\NetworkingDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\NetworkingDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\NetworkingDsc" }
       }

 

 #   NetworkingDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackNetworkingDsc {
           Ensure = "Present"
           DependsOn = "[Script]NetworkingDscDownLoad"
           Path = "C:\Install\PSModules\NetworkingDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

 #   ComputerManagementDsc (<a href="https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001">https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001</a>),      
       Script ComputerManagementDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/ComputerManagementDsc.zip" -OutFile "C:\Install\PSModules\ComputerManagementDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\ComputerManagementDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\ComputerManagementDsc" }
       }

 

	
 #   ComputerManagementDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackComputerManagementDsc {
           Ensure = "Present"
           DependsOn = "[Script]ComputerManagementDscDownLoad"
           Path = "C:\Install\PSModules\ComputerManagementDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

	
 #   xPendingReboot (<a href="https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0">https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0</a>),      
       Script xPendingRebootDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/xPendingReboot.zip" -OutFile "C:\Install\PSModules\xPendingReboot.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\xPendingReboot.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\xPendingReboot" }
       }

 

	
 #   xPendingReboot  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackxPendingReboot {
           Ensure = "Present"
           DependsOn = "[Script]xPendingRebootDownLoad"
           Path = "C:\Install\PSModules\xPendingReboot.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }
   }
}

关于安全


DSC的缺点是缺乏运行方式帐户。该机制以用户名+“密码的盐哈希”的形式安全地存储帐户,并将其移交给负责身份验证的服务。没有它,DSC无法代表其他服务管理帐户。而且,如果我们需要在具有特殊特权的帐户下进行身份验证,则自动化过程将非常复杂。例如,将服务器输入域时就是这种情况。

我们掌握的一切:

  • 凭据存储在纯文本中,
  • 加密凭证仅在生成凭证的PC上起作用。

实际上,有几种解决方案。 


当必须确保服务器行为的可预测性时,“存根”是很好的。
如果使用以下几种情况,我们会在几种情况下对服务器进行配置后的“存根”:

  • 重新启动(xPendingReboot资源) 
  • 凭证转移 
  • 与计划外的重新启动或安全性有关的可能影响服务器性能的其他资源。

为此,请创建并重新发布不包含包含xPendingReboot资源的配置块的配置以及带有凭据的配置。

该方法仅适用于“推”情况,因为“推”是相当简单的操作,并不意味着动态更改配置。在下一篇文章中布尔达科夫我们将仔细研究“推”和“推”模式下的设置和功能。

在5月28日Raiffeisenbank DGTL Communications社区的第一次在线会议上,还将讨论DSC技术的细微差别及其应用的范围。在会议上,我们还将讨论如何结交ELK和Exchange朋友,以及Microsoft Endpoint Manager在设备管理中可以做什么。这是mitap的注册

All Articles