{"id":26182,"date":"2016-05-10T00:00:00","date_gmt":"2016-05-10T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/powershell-desired-state-configuration-pull-mode\/"},"modified":"2017-09-27T15:29:05","modified_gmt":"2017-09-27T15:29:05","slug":"powershell-desired-state-configuration-pull-mode","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/powershell-desired-state-configuration-pull-mode\/","title":{"rendered":"PowerShell Desired State Configuration: Pull Mode"},"content":{"rendered":"<div class=\"article-content\">\n<ul class=\"series-articles\">\n<li>PowerShell Desired State Configuration &#8211; Part 1: <a href=\"https:\/\/www.simple-talk.com\/sysadmin\/powershell\/powershell-desired-state-configuration-the-basics\/\">The Basics<\/a><\/li>\n<li>PowerShell Desired State Configuration &#8211; Part 2: <a href=\"https:\/\/www.simple-talk.com\/sysadmin\/powershell\/powershell-desired-state-configuration-lcm-and-push-management-model\/\">LCM and Push Management Model<\/a><\/li>\n<li class=\"series-articles--active\"><span class=\"icon--chevron-right\">PowerShell Desired State Configuration &#8211; Part 3: Pull Mode<\/span><\/li>\n<li>PowerShell Desired State Configuration &#8211; Part 4: <a href=\"https:\/\/www.simple-talk.com\/sysadmin\/powershell\/powershell-desired-state-configuration-automating-and-monitoring-pull-mode\/\">Automating and Monitoring Pull Mode<\/a><\/li>\n<\/ul>\n<p class=\"start\">DSC has two configuration modes: &#8220;Push&#8221; or &#8220;Pull&#8221;. Each mode allows users to ensure that the servers and workstations in their care to acquire and retain the correct configuration. In the terms used by DSC, they allow you to apply a desired configuration-state over a target node. I&#8217;ve already described the Push mode in the first two parts of this series. In the Push mode, the configuration is pushed manually on target nodes and it is unidirectional. In the &#8220;Pull&#8221; mode, however, nodes are configured to get their desired configuration from the &#8216;pull&#8217; server. This mode is better when machines must be created quickly, or if they need to be done &#8216;on demand&#8217; for occasionally-connected nodes such as mobile devices or IOT nodes. I suggest you read both parts in order to understand the basics and decide which DSC mode you need to implement so as to fit your particular requirements.<\/p>\n<h2>Pull mode<\/h2>\n<p>In order to use the pull mode, it is necessary to have a server that has the Windows DSC feature installed. This server is called &#8216;Pull Server&#8217; in the DSC jargon. In my environment, I dedicate a server to host this feature but you can use an existing server equally well.<\/p>\n<p>A pull server must have Windows Management Framework 4 (WMF) installed, but this is the only prerequisite.<\/p>\n<p>So in this article, the technical environment is the following:<\/p>\n<ul>\n<li>DSC01: Pull server<\/li>\n<li>ADM01 and ADM11: Two nodes<\/li>\n<\/ul>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode1.png\" alt=\"2414-pullmode1.png\" \/><\/p>\n<p class=\"caption\">Figure 1: Pull mode<\/p>\n<p>This mode is the most complex to implement, but also the easiest to maintain. One example: In push mode, if a node happens to be offline, then deployment will fail. Sysadmin have to regularly try again to &#8216;push&#8217; the configuration. In the pull mode, the operation is much more dynamic. Whatever the status of the node is, the configuration will be applied when it will be back online.<\/p>\n<h2>What is pull server?<\/h2>\n<p>A pull server is just an Internet Information Services (IIS) Web server that will contain the MOF files for your nodes. It will also respond to requests from each node&#8217;s Local Configuration Manager (LCM) to distribute configurations. Thus, the node requests its configuration file from the pull server (Arrow n\u00c2\u00b01), which then returns with the associated DSC resources. This is the biggest advantage of the pull mode; the DSC resources are downloaded automatically from the pull server on to each node (Arrow n\u00c2\u00b02). Then, at regular intervals, the nodes will send their status to the pull server to check for changes to configuration.<\/p>\n<p>The pull server is a central repository for the MOF files and the DSC resources.<\/p>\n<p>A pull server can distribute the MOF files via two protocols:<\/p>\n<ul>\n<li><strong>Server Message Block (SMB)<\/strong>: This method uses shared folders on a file server. However, if you need to manage machines in several networks separated by a firewall, then your network port management will be more complex. In addition, the security permissions will have to be managed properly. The biggest advantage of this method is redundancy. In order to have high availability, you can use a replication service between two file servers via Distributed File System Replication (DFS-R) protocol. I will not detail this method in this article.<\/li>\n<li><strong>HyperText Transfer Protocol (http\/https)<\/strong>: This is the method we are going to study because it is the easiest way to manage machines located in different networks. It uses http protocol and just requires an IIS server for communications.<\/li>\n<\/ul>\n<h2>Installation of the Pull Server<\/h2>\n<p>To install a Pull server, you will need to add the &#8220;Desired State Configuration&#8221; Windows feature and configure two Web Services. The first web service will allow nodes to download their configuration and the second is called &#8220;Compliance Server&#8221; to avoid configuration-drift on the nodes.<\/p>\n<p>The pull server can be configured with DSC! It is a very good way of learning DSC, so we will use the following PowerShell script:<\/p>\n<div class=\"note\">\n<p>Note: You must install the &#8220;DSC resources kit&#8221; in order to use the resource <strong>xDscWebService<\/strong> contained in the <strong>xPSDesiredStateConfiguration<\/strong> module. For more explanations, I refer you to the first part of the series &#8220;The Basics&#8221;, in &#8220;The DSC resources&#8221; section.<\/p>\n<\/div>\n<pre class=\"lang:ps theme:powershell-ise\">configuration CreatePullServer\r\n{\r\n\tparam\r\n\t(\r\n\t\t[string[]]$ComputerName = 'localhost'\r\n\t)\r\n\r\n\r\nImport-DSCResource -ModuleName xPSDesiredStateConfiguration\r\n\r\n\r\nNode $ComputerName\r\n{\r\n\tWindowsFeature DSCServiceFeature\r\n\t{\r\n\t\tEnsure = \"Present\"\r\n\t\tName   = \"DSC-Service\"\r\n\t}\r\n\r\n\r\n\txDscWebService PSDSCPullServer\r\n\t{\r\n\t\tEnsure = \"Present\"\r\n\t\tEndpointName = \"PSDSCPullServer\" \r\n            \tPort = 8080 \r\n            \tPhysicalPath = \"$env:SystemDrive\\inetpub\\wwwroot\\PSDSCPullServer\" \r\n            \tCertificateThumbPrint = \"AllowUnencryptedTraffic\" \r\n            \tModulePath = \"$env:PROGRAMFILES\\WindowsPowerShell\\DscService\\Modules\" \r\n            \tConfigurationPath = \"$env:PROGRAMFILES\\WindowsPowerShell\\DscService\\Configuration\" \r\n            \tState = \"Started\" \r\n            \tDependsOn = \"[WindowsFeature]DSCServiceFeature\" \r\n        } \r\n\r\n\txDscWebService PSDSCComplianceServer \r\n        { \r\n            Ensure = \"Present\" \r\n            EndpointName = \"PSDSCComplianceServer\" \r\n            Port = 9080 \r\n            PhysicalPath = \"$env:SystemDrive\\inetpub\\wwwroot\\PSDSCComplianceServer\" \r\n            CertificateThumbPrint = \"AllowUnencryptedTraffic\" \r\n            State = \"Started\"\r\n            IsComplianceServer = $true \r\n            DependsOn = (\"[WindowsFeature]DSCServiceFeature\", \r\n                                       \"[xDSCWebService]PSDSCPullServer\") \r\n        } \r\n    } \r\n}\r\n\r\nCreatePullServer\r\n<\/pre>\n<p class=\"caption\">Figure 2: CreatePullServer.ps1<\/p>\n<p>Let&#8217;s take a look at this script to understand its content.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">configuration CreatePullServer \r\n{ \r\n ## PART1\r\n    param \r\n    ( \r\n        [string[]]$ComputerName = 'localhost' \r\n    ) \r\n<\/pre>\n<p>This first section will create a configuration called &#8220;CreatePullServer&#8221;. An array is created to contain the nodes that will be configured.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\"> ## PART2\r\n    Import-DSCResource -ModuleName xPSDesiredStateConfiguration\r\n<\/pre>\n<p>Import-DSCResource is a keyword that is only available within a configuration. This keyword imports DSC resources that will then be used in the configuration. Here we need the xDscWebService resource contained inside the xPSDesiredStateConfiguration module.<\/p>\n<div class=\"note\">\n<p>Note: This is a keyword and not a cmdlet. You will get an error if you use it in a PowerShell console. I will explain in detail in next article.<\/p>\n<\/div>\n<pre class=\"lang:ps theme:powershell-ise\"> ## PART3\r\n    Node $ComputerName \r\n    { \r\n<\/pre>\n<p>Here we use the array mentioned in the beginning of the script.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">## PART4\r\n        WindowsFeature DSCServiceFeature \r\n        { \r\n            Ensure = \"Present\" \r\n            Name   = \"DSC-Service\" \r\n        } \r\n<\/pre>\n<p>The keyword &#8220;<strong>WindowsFeature<\/strong>&#8221; indicates that we want to configure a Windows feature. Yes, I know that it is obvious! Here, we add two properties: <strong>Name<\/strong> followed by &#8220;<em>DSC-Service<\/em>&#8221; which is the name as used in Windows and <strong>Ensure<\/strong> with the value &#8220;Present&#8221; which mean that we want to install it.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\"> ## PART5\r\n        xDscWebService PSDSCPullServer \r\n        { \r\n            Ensure                  = \"Present\" \r\n            EndpointName            = \"PSDSCPullServer\" \r\n            Port                    = 8080 \r\n            PhysicalPath            = \"$env:SystemDrive\\inetpub\\wwwroot\\PSDSCPullServer\" \r\n            CertificateThumbPrint   = \"AllowUnencryptedTraffic\" \r\n            ModulePath              = \"$env:PROGRAMFILES\\WindowsPowerShell\\DscService\\Modules\" \r\n            ConfigurationPath       = \"$env:PROGRAMFILES\\WindowsPowerShell\\DscService\\Configuration\" \r\n            State                   = \"Started\" \r\n            DependsOn               = \"[WindowsFeature]DSCServiceFeature\" \r\n        } \r\n<\/pre>\n<p>This part configures the first Web service through which the nodes will get their configuration. You can change all the values except the last one <strong>DependsOn<\/strong> because DSC feature is mandatory.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">## PART6\r\n        xDscWebService PSDSCComplianceServer \r\n        { \r\n            Ensure                  = \"Present\" \r\n            EndpointName            = \"PSDSCComplianceServer\" \r\n            Port                    = 9080 \r\n            PhysicalPath            = \"$env:SystemDrive\\inetpub\\wwwroot\\PSDSCComplianceServer\" \r\n            CertificateThumbPrint   = \"AllowUnencryptedTraffic\" \r\n            State                   = \"Started\" \r\n            IsComplianceServer      = $true \r\n            DependsOn               = (\"[WindowsFeature]DSCServiceFeature\", \r\n                                       \"[xDSCWebService]PSDSCPullServer\") \r\n        } \r\n    } \r\n}  \r\n<\/pre>\n<p>Finally, part 6 configures the second Web service &#8220;Compliance Server&#8221; which will control drift configuration on target nodes. Several properties are used in this script, here is their description:<\/p>\n<ul>\n<li><strong>Ensure:<\/strong> Name of the web service.<\/li>\n<li><strong>EndpointName:<\/strong> Port used to communicate with the web service.<\/li>\n<li><strong>Port:<\/strong> Defines the content location.<\/li>\n<li><strong>PhysicalPath:<\/strong> Defines the content location.<\/li>\n<li><strong>CertificateThumbPrint:<\/strong> Indicates the thumbprint to use with https protocol. Here, we will indicate that traffic will not be encrypted.<\/li>\n<li><strong>State:<\/strong> Indicates that the web service is active or not.<\/li>\n<li><strong>IsComplianceServer:<\/strong> This property activates the compliance feature.<\/li>\n<li><strong>DependsOn:<\/strong> Indicates which resource is mandatory before creating the web service.<\/li>\n<\/ul>\n<p>Running this configuration generates a &#8220;localhost.mof&#8221; file:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\Users\\Administrator&gt; CreatePullServer -OutputPath C:\\DSC\\CreatePullServer\\\r\n\r\n    Directory: C:\\DSC\\CreatePullServer\r\n\r\nMode                LastWriteTime     Length Name\r\n----                -------------     ------ ----\r\n-a---           3\/6\/2016  3:48 PM       3800 localhost.mof \r\n<\/pre>\n<p>Now, we just have to run the following command to configure our Pull Server:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS&gt; Start-DSCConfiguration -Path \"C:\\DSC\\CreatePullServer\" -Wait -Verbose\r\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode2.png\" alt=\"2414-pullmode2.png\" \/><\/p>\n<p class=\"caption\">Figure 3: Setting up the Pull Server<\/p>\n<p>Let us verify that everything went well. Firstly, is the DSC feature installed?<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\Users\\administrator&gt; Get-WindowsFeature -Name DSC-Service\r\n\r\nDisplay Name                                            Name                       Install State\r\n------------                                            ----                       -------------\r\n    [X] Windows PowerShell Desired State Configurati... DSC-Service                    Installed\r\n<\/pre>\n<p>Secondly, were two Web Services created?<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\Users\\administrator&gt; Get-Website | ft -Autosize\r\n\r\nName                  ID State   Physical Path                            Bindings\r\n----                  -- -----   -------------                            --------\r\nDefault Web Site      1  Started %SystemDrive%\\inetpub\\wwwroot            http *:80:\r\nPSDSCPullServer       2  Started C:\\inetpub\\wwwroot\\PSDSCPullServer       http *:8080:\r\nPSDSCComplianceServer 3  Started C:\\inetpub\\wwwroot\\PSDSCComplianceServer http *:9080:\r\n<\/pre>\n<p>Everything seems fine. Last check using the <strong>Get-DscConfiguration<\/strong> cmdlet that will display the current DSC configuration (remember the &#8220;current.mof&#8221; file. This cmdlet will query this file).<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\Users\\administrator&gt; Get-DscConfiguration\r\n\r\n\r\nCredential           :\r\nDisplayName          : Windows PowerShell Desired State Configuration Service\r\nEnsure               : Present\r\nIncludeAllSubFeature : False\r\nLogPath              :\r\nName                 : DSC-Service\r\nSource               :\r\nPSComputerName       :\r\n\r\nCertificateThumbPrint : AllowUnencryptedTraffic\r\nConfigurationPath     : C:\\Program Files\\WindowsPowerShell\\DscService\\Configuration\r\nDSCServerUrl          : http:\/\/DSC01:8080\/PSDSCPullServer.svc\r\nEndpointName          : PSDSCPullServer\r\nEnsure                : Present\r\nIsComplianceServer    :\r\nModulePath            : C:\\Program Files\\WindowsPowerShell\\DscService\\Modules\r\nPhysicalPath          : C:\\inetpub\\wwwroot\\PSDSCPullServer\r\nPort                  : 8080\r\nState                 : Started\r\nPSComputerName        :\r\n\r\nCertificateThumbPrint : AllowUnencryptedTraffic\r\nConfigurationPath     :\r\nDSCServerUrl          : http:\/\/DSC01:9080\/PSDSCComplianceServer.svc\r\nEndpointName          : PSDSCComplianceServer\r\nEnsure                : Present\r\nIsComplianceServer    :\r\nModulePath            :\r\nPhysicalPath          : C:\\inetpub\\wwwroot\\PSDSCComplianceServer\r\nPort                  : 9080\r\nState                 : Started\r\nPSComputerName        :\r\n<\/pre>\n<p>We can validate the proper functioning of the web service from any node through a web browser: <strong><code>https:\/\/dsc01:8080\/PSDSCPullServer<\/code><\/strong><\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode3.png\" alt=\"2414-pullmode3.png\" \/><\/p>\n<p class=\"caption\">Figure 4: Check the web service<\/p>\n<h2>Manual installation of the Pull Server<\/h2>\n<p>For those who do not wish to use DSC to configure the Pull Server, we&#8217;ll have to start by adding the DSC feature:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS&gt; Add-WindowsFeature -Name DSC-Service<\/pre>\n<p>or<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode4.png\" alt=\"2414-pullmode4.png\" \/><\/p>\n<p class=\"caption\">Figure 5: Add DSC Windows Feature<\/p>\n<p>Then we go to the Web server settings (IIS Manager) to configure the two sites with the same properties listed in the DSC configuration. This requires some basic IIS skills, which is why I recommend using the DSC script.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode5.png\" alt=\"2414-pullmode5.png\" \/><\/p>\n<p class=\"caption\">Figure 6: IIS Sites<\/p>\n<h2>Nodes configuration<\/h2>\n<p>By default, the LCM is configured in Push mode on each node. We have to change this setting.<\/p>\n<div class=\"note\">\n<p>Note: In pull mode, the name of the MOF file will no longer be the name of the node, e.g. &#8220;ADM01.mof&#8221; but it will contain a Globally Unique Identifier (GUID) that we will generate.<\/p>\n<\/div>\n<p>Firstly, we will generate two GUID:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; $guidADM01 = [GUID]::NewGuid()\r\nPS C:\\&gt; $guidADM11 = [GUID]::NewGuid()\r\nPS C:\\&gt; $guidADM01\r\n\r\nGuid\r\n----\r\n18ca85b8-1500-4aca-8f05-fbf61c1f48b0\r\n\r\nPS C:\\&gt; $guidADM11\r\n\r\nGuid\r\n----\r\n4aa09541-82d7-491f-9408-a1fa10757734\r\n<\/pre>\n<p>Then, we will create the metaconfiguration that will be applied to the LCM of ADM01 and ADM11. Please check the previous article for more information about metaconfiguration.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">configuration LCMPullMode \r\n{\r\n    param \r\n    ( \r\n        [string]$ComputerName,\r\n        [string]$GUID\r\n    ) \r\n\r\n    node $ComputerName\r\n    {    \r\n        LocalConfigurationManager \r\n        { \r\n            ConfigurationID                = $GUID\r\n            ConfigurationMode              = 'ApplyAndAutocorrect' \r\n            RefreshMode                    = 'Pull' \r\n            DownloadManagerName            = 'WebDownloadManager' \r\n            DownloadManagerCustomData = @{ \r\n               ServerUrl = 'http:\/\/dsc01:8080\/PSDSCPullServer.svc' \r\n               AllowUnsecureConnection = 'true' } \r\n            RebootNodeIfNeeded             = $true \r\n        } \r\n    } \r\n}\r\n\r\nLCMPullMode -ComputerName ADM01 -GUID 18ca85b8-1500-4aca-8f05-fbf61c1f48b0\r\nLCMPullMode -ComputerName ADM11 -GUID 4aa09541-82d7-491f-9408-a1fa10757734\r\n<\/pre>\n<p>This configuration uses two parameters: The name of the machine to be configured, followed by its GUID. We set the <strong>DownloadManagerName<\/strong> property with the value <em>&#8220;WebDownloadManager&#8221;<\/em>. If you use SMB protocol for your Pull Server, then the value must be replaced by <em>&#8216;DSCFileDownloadManager&#8217;<\/em>. The second <strong>DownloadManagerCustomData<\/strong> property contains the URL to access our server. In SMB mode, this value should contain the path of the shared folder.<\/p>\n<p>Two MOF files are generated:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode6.png\" alt=\"2414-pullmode6.png\" \/><\/p>\n<p class=\"caption\">Figure 7: Two MOF files<\/p>\n<p>Now, we can apply the metaconfiguration on the nodes:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS&gt; Set-DscLocalConfigurationManager -Path .\\LCMPullMode<\/pre>\n<p>What remains is to verify if changes are applied on both nodes. Everything seems ok.<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; $session = New-CimSession -ComputerName ADM01\r\nPS C:\\&gt; Get-DscLocalConfigurationManager -CimSession $session\r\n\r\n\r\nAllowModuleOverwrite           : False\r\nCertificateID                  :\r\nConfigurationID                : 18ca85b8-1500-4aca-8f05-fbf61c1f48b0\r\nConfigurationMode              : ApplyAndAutoCorrect\r\nConfigurationModeFrequencyMins : 30\r\nCredential                     :\r\nDownloadManagerCustomData      : {MSFT_KeyValuePair (key = \"ServerUrl\"), MSFT_KeyValuePair (key =\r\n                                 \"AllowUnsecureConnection\")}\r\nDownloadManagerName            : WebDownloadManager\r\nRebootNodeIfNeeded             : True\r\nRefreshFrequencyMins           : 15\r\nRefreshMode                    : Pull\r\nPSComputerName                 : ADM01\r\n\r\n\r\n\r\nPS C:\\&gt; $sessionADM11 = New-CimSession -ComputerName ADM11\r\nPS C:\\&gt; Get-DscLocalConfigurationManager -CimSession $sessionADM11\r\n\r\n\r\nAllowModuleOverwrite           : False\r\nCertificateID                  :\r\nConfigurationID                : 4aa09541-82d7-491f-9408-a1fa10757734\r\nConfigurationMode              : ApplyAndAutoCorrect\r\nConfigurationModeFrequencyMins : 30\r\nCredential                     :\r\nDownloadManagerCustomData      : {MSFT_KeyValuePair (key = \"ServerUrl\"), MSFT_KeyValuePair (key =\r\n                                 \"AllowUnsecureConnection\")}\r\nDownloadManagerName            : WebDownloadManager\r\nRebootNodeIfNeeded             : True\r\nRefreshFrequencyMins           : 15\r\nRefreshMode                    : Pull\r\nPSComputerName                 : ADM11\r\n<\/pre>\n<p>Let&#8217;s check that the pull server&#8217;s URL is correct:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; (Get-DscLocalConfigurationManager).DownloadManagerCustomData\r\n\r\nkey                                     Value                                   PSComputerName\r\n---                                     -----                                   --------------\r\nServerUrl                               http:\/\/dsc01:8080\/PSDSCPullServer.svc\r\nAllowUnsecureConnection                 true\r\n<\/pre>\n<h2>How to deploy a configuration?<\/h2>\n<p>Now we&#8217;ll use the following example: verify that the audio service is in automatic mode and is started. The nodes were previously configured to correct any unwanted changes. So the service will remain always started.<\/p>\n<p>Here is the configuration that we will be using:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">configuration AudioServiceConfig\r\n{ \r\n    param([string[]] $computerName) \r\n \r\n    node $computerName \r\n    {    \r\n        Service Audio \r\n        { \r\n            Name        = 'Audiosrv' \r\n            StartupType = 'Automatic' \r\n            State       = 'Running' \r\n        }    \r\n    } \r\n} \r\n \r\nAudioServiceConfig -ComputerName ADM01,ADM11 \r\n<\/pre>\n<p>Nothing too complicated here. The keyword &#8220;<strong>Service<\/strong>&#8221; is followed by a friendly name and by these three properties:<\/p>\n<ul>\n<li><strong>Name: <\/strong>Name of the service as used in Windows<\/li>\n<li><strong>StartupType: <\/strong>Corresponds to the startup mode in Windows<\/li>\n<li><strong>State: <\/strong>Status of the service<\/li>\n<\/ul>\n<p>You can get the properties and their values with the following command:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\Users\\administrator&gt; (Get-DscResource -Name Service).Properties | ft -AutoSize\r\n\r\nName           PropertyType   IsMandatory Values\r\n----           ------------   ----------- ------\r\nName           [string]              True {}\r\nBuiltInAccount [string]             False {LocalService, LocalSystem, NetworkService}\r\nCredential     [PSCredential]       False {}\r\nDependsOn      [string[]]           False {}\r\nStartupType    [string]             False {Automatic, Disabled, Manual}\r\nState          [string]             False {Running, Stopped}\r\n<\/pre>\n<p>Two files were generated but we need to rename them with their respective GUID:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS&gt; Rename-Item .\\ADM01.mof 18ca85b8-1500-4aca-8f05-fbf61c1f48b0.mof \r\n \r\nPS&gt; Rename-Item .\\ADM11.mof 18ca85b8-1500-4aca-8f05-fbf61c1f48b0.mof \r\n<\/pre>\n<p>Note: Using the GUID instead of the hostname complicates the management of MOF files a little more. We will see later how to manage them to reduce this disadvantage. In this article, I recommend using a <strong>txt<\/strong> or <strong>csv<\/strong> file and specify the following pair &#8220;<strong>hostname = GUID<\/strong>&#8220;.<\/p>\n<p>The next step is to generate a checksum file to ensure the authenticity and integrity of configurations. If you need to update an existing configuration, it will be mandatory to generate a new checksum file. Otherwise, the configuration will not be applied for security reason. This avoids any unwanted changes. The <strong>New-DSCChecksum<\/strong> cmdlet will automatically create two checksum files:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\dsc\\AudioServiceConfig&gt; dir\r\n\r\n\r\n    Directory: C:\\dsc\\AudioServiceConfig\r\n\r\n\r\nMode                LastWriteTime     Length Name\r\n----                -------------     ------ ----\r\n-a---         3\/12\/2016   3:44 PM       1164 18ca85b8-1500-4aca-8f05-fbf61c1f48b0.mof\r\n-a---         3\/12\/2016   3:44 PM       1164 4aa09541-82d7-491f-9408-a1fa10757734.mof\r\n\r\n\r\nPS C:\\dsc\\AudioServiceConfig&gt; New-DSCCheckSum *\r\nPS C:\\dsc\\AudioServiceConfig&gt; dir\r\n\r\n\r\n    Directory: C:\\dsc\\AudioServiceConfig\r\n\r\n\r\nMode                LastWriteTime     Length Name\r\n----                -------------     ------ ----\r\n-a---         3\/12\/2016   3:44 PM       1164 18ca85b8-1500-4aca-8f05-fbf61c1f48b0.mof\r\n-a---         3\/12\/2016   5:29 PM         64 18ca85b8-1500-4aca-8f05-fbf61c1f48b0.mof.checksum\r\n-a---         3\/12\/2016   3:44 PM       1164 4aa09541-82d7-491f-9408-a1fa10757734.mof\r\n-a---         3\/12\/2016   5:29 PM         64 4aa09541-82d7-491f-9408-a1fa10757734.mof.checksum\r\n<\/pre>\n<p>It is almost over. We need to move the files in the directory that we have indicated in our <strong>CreatePullServer<\/strong> configuration with the following property:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">ConfigurationPath = \"$env:PROGRAMFILES\\WindowsPowerShell\\DscService\\Configuration\"<\/pre>\n<p>These two PowerShell lines allows us to publish them in order to make them available for the nodes:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$destination = 'C:\\Program Files\\WindowsPowerShell\\DscService\\Configuration'\r\nCopy 'C:\\DSC\\AudioServiceConfig\\*.mof*' -Destination $destination \r\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode7.png\" alt=\"2414-pullmode7.png\" \/><\/p>\n<p class=\"caption\">Figure 8: Publish MOF files<\/p>\n<p>Well, it&#8217;s over! The nodes will now get their configuration in the next fifteen minutes. Finally, what have we achieved? I created the following diagram to summarize all the steps:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2414-pullmode8.png\" alt=\"2414-pullmode8.png\" \/><\/p>\n<p class=\"caption\">Figure 9: Step-by-step publishing process<\/p>\n<p>We will discuss in next article how to automate these steps.<\/p>\n<h2>To go further<\/h2>\n<p>Ok, at this time our nodes are configured properly. Several days pass, and you want to ensure that they are still configured properly. How are you going to do that?<\/p>\n<ul>\n<li>Could you log each node? That is tedious!<\/li>\n<li>Can you use <strong>Get-DscConfiguration<\/strong> cmdlet through a CIM session? Yes, but if the configuration is long or complex, then you will have difficulty trying to troubleshoot in this manner.<\/li>\n<\/ul>\n<p>There is a cmdlet dedicated for this purpose: <strong>Test-DscConfiguration<\/strong> that displays True\/False depending on the status. In my example below, I verify the status of my two nodes that are valid, and then I stop the Audio service on ADM01. The <strong>Test-DscConfiguration<\/strong> cmdlet indicates to me that the desired configuration is not applied at that time.<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; $sessionADM01 = New-CimSession -ComputerName ADM01\r\nPS C:\\&gt; $sessionADM11 = New-CimSession -ComputerName ADM11\r\nPS C:\\&gt; Test-DscConfiguration -CimSession $sessionADM01\r\nTrue\r\nPS C:\\&gt; Test-DscConfiguration -CimSession $sessionADM11\r\nTrue\r\nPS C:\\&gt;\r\nPS C:\\&gt;\r\nPS C:\\&gt; Test-DscConfiguration -CimSession $sessionADM01\r\nFalse\r\nPS C:\\&gt;\r\n<\/pre>\n<p>I can now use the <strong>Get-DscConfiguration<\/strong> cmdlet in order to troubleshoot the problem and find that the Audio Service has been stopped manually:<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; Get-DscConfiguration -CimSession $session\r\n\r\n\r\nBuiltInAccount : LocalService\r\nCredential     :\r\nDependencies   : {MMCSS, RpcSs, AudioEndpointBuilder}\r\nDescription    : Manages audio for Windows-based programs.  If this service is stopped, audio devices and effects will\r\n                 not function properly.  If this service is disabled, any services that explicitly depend on it will\r\n                 fail to start\r\nDisplayName    : Windows Audio\r\nName           : Audiosrv\r\nPath           : C:\\Windows\\System32\\svchost.exe -k LocalServiceNetworkRestricted\r\nStartupType    : Automatic\r\nState          : Stopped\r\nStatus         :\r\nPSComputerName : ADM01\r\n<\/pre>\n<p>The LCM present on each node verifies its configuration regularly, thanks to a scheduled task named &#8220;Consistency&#8221;. The execution of this task will check the configuration without waiting for the next cycle.<\/p>\n<pre class=\"lang:ps theme:powershell-output\">PS C:\\&gt; Get-ScheduledTask -TaskPath \"\\Microsoft\\Windows\\Desired State Configuration\\\"\r\n\r\nTaskPath                                       TaskName                          State\r\n--------                                       --------                          -----\r\n\\Microsoft\\Windows\\Desired State Configurat... Consistency                       Ready\r\n\\Microsoft\\Windows\\Desired State Configurat... DSCRestartBootTask                Ready\r\n<\/pre>\n<p>To correct the configuration of ADM01, I run the &#8220;Consistency&#8221; task to apply the desired configuration using the <strong>Start-ScheduledTask<\/strong> cmdlet:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Invoke-Command -ComputerName ADM01 -Command { \r\nStart-ScheduledTask -TaskName '\\Microsoft\\Windows\\Desired State Configuration\\Consistency'\r\n} \r\n<\/pre>\n<h2>Conclusion<\/h2>\n<p>PowerShell&#8217;s Desired State Configuration (DSC) system has two distinct modes of use, the &#8216;push&#8217; mode and the &#8216;pull&#8217; mode. They are both useful, but are intended for different requirements. The &#8216;Pull&#8217; Mode of Desired State Configuration (DSC) is more complex to implement than the &#8216;push&#8217; mode, but is usually far better suited to an environment with many machines to manage. The &#8216;push&#8217; mode is better suited to a scheduled operation, where configuration needs to happen at a particular time, but the &#8216;Pull&#8217; mode is going to be of more general use. Now that you know the two DSC modes that can be implemented, you can now select which of the modes will suit your needs and constraints.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Automated configuration management is simpler with Desired State Configuration (DSC) and Push mode, but what is the best way to use DSC to automate deployments on your machines? &#039;Push&#039; mode or &#039;Pull&#039; mode? How can you reduce configuration-drift over time? Nicolas Prigent describes the second DSC deployment mode: Pull mode.&hellip;<\/p>\n","protected":false},"author":158223,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[35],"tags":[],"coauthors":[6804],"class_list":["post-26182","post","type-post","status-publish","format-standard","hentry","category-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/26182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/158223"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=26182"}],"version-history":[{"count":8,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/26182\/revisions"}],"predecessor-version":[{"id":73414,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/26182\/revisions\/73414"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=26182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=26182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=26182"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=26182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}