配置本地配置管理器

  在前面我们搭建一个pull服务器时,包含了一个修改目标节点的本地配置管理器(LCM)的简短例子。在任何机器上,你都可以运行Get-DscLocalConfigurationManager来检查这个机电的LCM设置。它们包含这些:

  • AllowModuleOverwrite.当它设为 $True时, 表示允许新的模块(从pull server下载的) 覆盖旧的模块。.
  • CertificateID. 节点证书的指纹. 这个证书必须被储存在节点本机上,并且它将用于解密那些包含在配置文件内的加密数据. 比如,DSC让你在MOF文件中包含PSCredential这个对象, 但需要它们是加密的. 该书的下一段落我们就会涉及这一方面。
  • ConfigurationID. 节点从它的pull server山拉回配置文件时用到的GUID.
  • ConfigurationMode. LCM工作的方式。ApplyOnly DSC仅应用一次配置除非监测到pull server上有新的配置。(原文是ApplyOnce only applies a configuration one time。但与实际情况不符). ApplyAndMonitor 应用该配置,并且在之后间断性重复检查它。变化会被记录在日志内。 ApplyAndAutoCorrect 自动地重复应用配置。
  • ConfigurationModeFrequencyMins. LCM 重复检查配置的间隔分钟数。它必须是RefreshFrequencyMinutes倍数。 如果你写的参数不是其倍数,那你的值就会最终取与其最近的倍数。该属性的最小值为30分钟。
  • Credential. 用于获取远程Resource的证书。正常情况下,LCM是已SYSTEM这个用户来运行的,它访问非本地的资源时只有很有限的权限。比如,如果你打算让你的LCM从一个SMB的pull server上拉取配置,你就一定需要给提供一个合法地 证书,才可以实现这个。
  • DownloadManagerCustomData. 被传递到所选的下载管理器的属性。例如,WebDownloadManager需要一个URI,且要设置成为支持HTTP.
  • DownloadManagerName. 必须是WebDownloadManager 或DscFileDownloadManager.
  • RebootNodeIfNeeded. 如果它为$True。目标节点会在需要的时候自动重启。默认值为$False,这就意味着配置操作需要重启就无法实现了,除非有人手动重启了这个节点。微软选择默认为$False ,因为这更安全–当设为$True时,一旦DSC认为有必要重启,那重启就会立马发生。在产品环境里的一台服务器上,你就会发现这可能是个问题。
  • RefreshFrequencyMins. 在pull模式里,指定多久从pull server上检查一次新的配置。 该属性的最小值为15分钟.
  • ReFresgMode: 只能是Push 或Pull。你必须指定一个DownloadManagerName属性。 注意LCM只会处理单个配置。如果你推送了一个新的配置,LCM将会使用这个配置来替换以前的那个。在pull模式里,它只会拉回一个配置。你可以使用组合的配置(前文介绍过)来把多个配置联合成一个。

  当你生成了相应的MOF文件时,你需要运行Set-DscLoaclConfiguration指令而不是Start-DscConfigutration来应用它。而且配置脚本应该只包含LocalConfigurationManager这个配置项,不应该包含任何其他的配置项。

  更多LCM配置的信息,请看http://blogs.msdn.com/b/PowerShell/archive/2013/12/09/understanding-meta-configuration-in-Windows-PowerShell-desired-state-configuration.aspx。在写这本书时,http://technet.microsoft.com/en-us/library/dn249922.aspx 上的一些内容是不准确的。

在配置中加入证书(Credentials)

  很多次,你都需要在你的配置中加入证书。在配置脚本中,你可以简单的传递进去一个PSCredential的对象作为参数,并且使用Get-Credential来创建这个PSCredential这个对象。当这个配置脚本运行的时候,这个PSCredential对象也会被连载进入这个MOF文件,然后被传送(通过push或者pull模式)到目标节点上去。当然,你是肯定不想你的证书以明文的形式传递过去吧?

正确的方式

  为了能够让认证正常工作,证书必须在所有的目标节点(特别是在本地机器库里)上都有。在节点的LCM配置中必须指定这个证书的指纹(具体见前文)。同样的证书也必须要安装在你将要生成MOF文件来执行配置的电脑。当你创建这个配置的时候,你应该把证书的指纹作为配置数据的一部分传入。我们接下来讨论如何实现这个。

  具体实现可以看PowerShell团队的博客: http://blogs.msdn.com/b/PowerShell/archive/2014/01/31/want-to-secure-credentials-in-Windows-PowerShell-desired-state-configuration.aspx 这里你可以看到更多细节。

  这儿有一个快速学习的例子,其中加入了PSCredential:

configuration CredentialEncryptionExample
 {
     param(
         [Parameter(Mandatory=$true)]
         [ValidateNotNullorEmpty()]
         [PsCredential] $credential
         ) 

     Node $AllNodes.NodeName
     {
         File exampleFile
         {
             SourcePath = "\\Server\share\path\file.ext"
             DestinationPath = "C:\destinationPath"
             Credential = $credential
         }
     }
 }

  这个配置脚本在运行的时候,会提示你需要PSCredential的用户名和密码。你可以注意到FIle这个Resource被用作从一个UNC路径拷贝一个文件。假设这个UNC路径需要一个非匿名的连接,我们就将需要提供一个证书---并且我们还要传递这个PSCredential。

  这个配置里所用到的方法就是从$AllNode变量中取。下面就是我们的实现:

$ConfigData = @{
  AllNodes = @(
    @{
       # The name of the node we are describing 
       NodeName = "SERVER2"
       # The path to the .cer file containing the
       # public key of the Encryption Certificate                
       # used to encrypt credentials for this node
       CertificateFile = "C:\publicKeys\targetNode.cer"

       # The thumbprint of the Encryption Certificate
       # used to decrypt the credentials on target node
       Thumbprint = "AC23EA3A9E291A75757A556D0B71CBBF8C4F6FD8"
     };
   );
}

  所以我们在$ConfigData创建了一个哈希表。这个哈希表只有一个关键字,名字为AllNodes,并且它的值是一个只有一项的数组。这一项本身也是一个有三个关键字(NodeNumber,CertificateFile,以及Thumbprint)的哈希表。这个证书没有安装在这台电脑上,但是它可以用一个导出的.cer文件代替。但是,这个证书必须要安装在任何我们即将应用这些配置的节点上。我们还要设置这些目标节点的LCM的CertificateId属性值为它的指纹。

  因此,我们创建了这个配置。并且把这个配置数据块也要传进去它里面,并且这一块包含了这个证书的细节。现在我们需要在运行这个配置时传入这个配置数据:

CredentialEncryptionExample –ConfigurationData $ConfigData

  注意我们从来没有定义–ConfigurationData这个作为这个配置的参数,它是一个所有配置都自动支持的内置参数。PowerShell会在这个MOF文件中自动加密这个证书,因为PowerShell被设计用于识别PSCredential这个对象并且对它们加密。目标节点会识别这些加密的数据,并且使用这些证书的拷贝然后解密。   需要注意的是,我们创建MOF文件的节点使用这个证书的公共密钥,而目标节点使用私钥用于解密。

更简单,更少权限的方式

  当然,证书有时候不是那么方便,有时候你也不需要这种安全。比如,假设你正在搭建一个实验环境,并且你的所有密码都是Pa$$w0rd。谁还在乎加密?

  在这种情况下,你可以强制PowerShell在MOF文件中用明文的、未加密的密码。这儿就是一个在实验环境中搭建3台机器的例子:

Configuration LabSetup {
    Param(
        [Parameter(Mandatory=$True)]
        [PSCredential]$DomainCredential,

        [Parameter(Mandatory=$True)]
        [PSCredential]$ SafeModeCredential,

        [Parameter(Mandatory=$True)]
        [string]$EthernetInterfaceAlias
    )

    # Ensure KB2883200 is installed on all computers
    # Expecting Windows 8.1 and Windows Server 2012 R2

    # Run this script on each computer to produce
    # MOF files and start configuration

    # You should do DC1 first, then the other two

    # You will be prompted for two credentials
    # For the first, provide DOMAIN\Administrator and Pa$$w0rd
    # For the second, provide Administrator and Pa$$w0rd

    # This assumes that the Student Materials files are at
    # E:\AllFiles

    # Computers must have the following downloaded and installed
    # into C:\Program Files\WindowsPowerShell\Modules:
    # - http://gallery.technet.microsoft.com/xActiveDirectory-f2d573f3
    # - http://gallery.technet.microsoft.com/scriptcenter/xComputerManagement-Module-3ad911cc
    # - http://gallery.technet.microsoft.com/scriptcenter/xNetworking-Module-818b3583

    Import-DscResource -ModuleName  ActiveDirectory,xNetworking,xComputerManagement

    Node 'DC1' {
        WindowsFeature ADDSInstall {
            Ensure = 'Present'
            Name = 'AD-Domain-Services'
        }

        xIPAddress IP {
            IPAddress = '10.0.0.10'
            InterfaceAlias = $EthernetInterfaceAlias
            DefaultGateway = '10.0.0.1'
            SubnetMask = 24
            AddressFamily = 'IPv4'
        }

        xDNSServerAddress DNS {
            Address = '127.0.0.1'
            InterfaceAlias = $EthernetInterfaceAlias
            AddressFamily = 'IPv4'
        }

        xComputer Computer {
            Name = 'DC1'
        }

        xADDomain Adatum {
            DomainName = domain.pri'
            DomainAdministratorCredential = $domaincredential
            SafemodeAdministratorPassword =  $SafeModeCredential
            DependsOn =  '[WindowsFeature]ADDSInstall',
                         '[xIPAddress]IP',
                         '[xDNSServerAddress]DNS',
                         '[xComputer]Computer'
        }

    }

    Node 'CL1' {
        xIPAddress IP {
            IPAddress = '10.0.0.30'
            InterfaceAlias = $EthernetInterfaceAlias
            DefaultGateway = '10.0.0.1'
            SubnetMask = 24
            AddressFamily = 'IPv4'
        }

        xDNSServerAddress DNS {
            Address = '10.0.0.10'
            InterfaceAlias = $EthernetInterfaceAlias
            AddressFamily = 'IPv4'
        }

        xComputer Computer {
            Name = 'CL1'
            DomainName = 'DOMAIN'
            Credential = $DomainCredential
            DependsOn = '[xIPAddress]IP','[xDNSServerAddress]DNS'
        }

        Environment Env {
            Name = 'PSModulePath'
            Ensure = 'Present'
            Path = $true
            Value = 'E:\AllFiles\Modules'
        }
    }

    Node 'SRV1' {
        xIPAddress IP {
            IPAddress = '10.0.0.20'
            InterfaceAlias = $EthernetInterfaceAlias
            DefaultGateway = '10.0.0.1'
            SubnetMask = 24
            AddressFamily = 'IPv4'
        }

       xDNSServerAddress DNS {
            Address = '10.0.0.10'
            InterfaceAlias = $EthernetInterfaceAlias
            AddressFamily = 'IPv4'
        }

        xComputer Computer {
            Name = 'SRV1'
            DomainName = 'DOMAIN'
            Credential = $DomainCredential
            DependsOn = '[xIPAddress]IP','[xDNSServerAddress]DNS'
        }
    }

}

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName='LON-DC1'
            PSDscAllowPlainTextPassword=$true
        }
        @{
            NodeName='LON-SRV1'
            PSDscAllowPlainTextPassword=$true
        }
        @{
            NodeName='LON-CL1'
            PSDscAllowPlainTextPassword=$true
        }
    )
}

LabSetup -OutputPath C:\LabSetup -ConfigurationData $ConfigurationData `
         -EthernetInterfaceAlias 'Ethernet0'

Start-DscConfiguration -Path C:\LabSetup -ComputerName $env:COMPUTERNAME

  这确实是一个非常酷的例子---有几个事情需要注意:

  • 我们加入了超过一个的NODE段落。所以,我们使用单个配置脚本来搭建整个环境。当我们执行这个的时候,会生成三个MOF文件。
  • 发现PSDscAllowPlainTextPassword 在配置数据内?那就是为什么MOF可以合法的包含未加密的密码的原因。注意我们是如何在Param() 块加入两个证书的,以及之后使用这些证书完成这个配置。 我们参数化了以太网接口的别称,因为有时候它并不是“Ethernet0” 。参数化它有利于在未来的步骤中更加容易改变。
  • 在一台试验机器上执行该脚本会生成全部三个MOF文件,但是只有本地机器的MOF是真的执行了的。我们假设这台“空的”电脑已经是正确的机器名了,要关注的就是我们最开始基于的镜像。很明显不是所有的机器都会那样启动,但是我们的机器会。

results matching ""

    No results matching ""