What do we mean by "pushing DSC configurations locally"? When we apply a DSC configuration to the computer we are logged into, we are applying or pushing the DSC configuration onto the computer. We call it "pushing" because we are actively copying the MOF file and triggering an execution on the target node; we are active participants in the whole process. The Start-DscConfiguration
Cmdlet does the work for us, but we are actively requesting the operations to be performed. This is clear when we contrast this with a DSC Pull Server. The DSC engine on the target node pulls the DSC configuration when an execution run is scheduled, whereas we push the DSC configuration to the target node when we want to execute it interactively using Start-DscConfiguration
.
The Start-DscConfiguration
Cmdlet syntax we will be using is this:
Start-DscConfiguration [-Path] <System.String> [-Wait] [-Force] [<CommonParameters>] -CimSession <CimSession[]>
It is a modified version of what you would see if you used the Get-Help
Cmdlet because we have omitted extra parameters to better illustrate what we are doing in this chapter. This is significantly simpler than what we will be dealing with when we push DSC configuration files remotely, so it is a good place to start.
Start-DscConfiguration
accepts a -Path
variable where the MOF file will be and a Boolean
parameter called -Wait
, along with CommonParameters
such as Verbose
and Debug
. The Wait
parameter is the indication that we want the job to run in front of us and only return when the DSC execution is completed. Any errors during execution will be presented to us during the execution run, but no other information. For this reason, when using Wait
it is commonplace to use Verbose
as well, so that the running output from the DSC configuration is presented to you as it happens. We'll be using this combination as we proceed for this very reason, but we may not include all the output text as it can become quite verbose (pun intended).
Our focus in this chapter is on how to push DSC configurations and not how to use DSC configurations, so our example configuration is simple and short. This reduces the amount of code we are working with and the amount of logging we output, which allows us to fit the DSC configurations in our chapter without having pages of printouts.
At this point, you should be familiar with compiling DSC configuration scripts into MOF files. In this chapter, we make the assumption that you have a good grasp of DSC Configuration
block syntax and use and how to author DSC configuration scripts. If you are skipping around or feel fuzzy on these concepts, please refer back to these chapters before you continue.
In our example script, we will create a text file on the primary drive with dummy contents. Again, we are purposely not fancy here in order to focus on how to push DSC configurations and not the DSC configurations themselves:
###begin script#### Configuration SetupAllTheThings { Node "localhost" { File CreateFile { Ensure = "Present" DestinationPath = "c: est.txt" Contents = "Wakka" } } } SetupAllTheThings -OutputPath ([IO.Path]::Combine($PSScriptRoot, "SetupAllTheThings")) ###end script####
Compiling the preceding DSC configuration script gives us a valid MOF file that we can use on the local computer. This should all be straightforward for you by now, and you should see the following results from the compiling of the MOF file:
PS C:UsersAdministrator> C:vagrantSetupAllTheThings.ps1 Directory: C:vagrantSetupAllTheThings Mode LastWriteTime Length Name ---- ------------- ------ ---- ----- 7/01/2015 3:19 PM 1276 localhost.mof
If that doesn't compile correctly, look at your syntax and ensure it's the same as what we have laid out here. It may help if you add the Verbose
parameter to your DSC configuration function to see what is going on as the MOF is compiled. If you are still having trouble, or want to see even more information, then you can set your $DebugPreference
to Continue
and receive even more diagnostic information. Example output is as shown:
DEBUG: MSFT_PackageResource: ResourceID = [Package]InstallTheThing DEBUG: MSFT_PackageResource: Processing property 'DependsOn' [ DEBUG: MSFT_PackageResource: Processing completed 'DependsOn' ] DEBUG: MSFT_PackageResource: Processing property 'Ensure' [ DEBUG: MSFT_PackageResource: Processing completed 'Ensure' ] DEBUG: MSFT_PackageResource: Processing property 'Name' [ DEBUG: MSFT_PackageResource: Canonicalized property 'Name' = 'The Thing' DEBUG: MSFT_PackageResource: Processing completed 'Name' ] DEBUG: MSFT_PackageResource: Processing property 'Path' [ DEBUG: MSFT_PackageResource: Canonicalized property 'Path' = 'c:allthethings hing.msi' DEBUG: MSFT_PackageResource: Processing completed 'Path' ] DEBUG: MSFT_PackageResource: Processing property 'ProductId' [ DEBUG: MSFT_PackageResource: Canonicalized property 'ProductId' = '{8f665668-7679-4f53-acde-06cf7eab5d73}'
If we examine the localhost.mof
file, we will see that the file resource laid out applies to a target node named localhost
. This means that, although we compile this MOF file on the computer we are sitting on, this MOF file can be pushed to any computer, whether locally or remotely, because localhost
applies to any computer. If we wanted to restrict which target nodes used specific MOF files, we would need to specify their host names in the Node
block. We will cover this when we deal with pushing DSC configurations remotely shortly.
Now that we have the MOF file compiled, we can apply it to our local computer using Start-DscConfiguration
. We will use the Verbose
, Wait
, and Force
parameters to indicate that we want it to execute interactively and output verbose information to our shell. We use Force
to tell DSC to apply the MOF file regardless of the current state of the target node (whether it has a pending MOF file or not):
PS C:UsersAdministrator> Start-DscConfiguration -Path C:vagrantSetupAllTheThings -Verbose -Wait -Force VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'. VERBOSE: An LCM method call arrived from computer BOX1 with user sid S-1-5-21-1953236517-242735908-2433092285-500. VERBOSE: [BOX1]: LCM: [ Start Set ] VERBOSE: [BOX1]: LCM: [ Start Resource ] [[File]CreateaFile] VERBOSE: [BOX1]: LCM: [ Start Test ] [[File]CreateaFile] VERBOSE: [BOX1]: [[File]CreateaFile] The system cannot find the file specified. VERBOSE: [BOX1]: [[File]CreateaFile] The related file/directory is: c: est.txt. VERBOSE: [BOX1]: LCM: [ End Test ] [[File]CreateaFile] in 0.0320 seconds. VERBOSE: [BOX1]: LCM: [ Start Set ] [[File]CreateaFile] VERBOSE: [BOX1]: [[File]CreateaFile] The system cannot find the file specified. VERBOSE: [BOX1]: [[File]CreateaFile] The related file/directory is: c: est.txt. VERBOSE: [BOX1]: LCM: [ End Set ] [[File]CreateaFile] in 0.0000 seconds. VERBOSE: [BOX1]: LCM: [ End Resource ] [[File]CreateaFile] VERBOSE: [BOX1]: LCM: [ End Set ] VERBOSE: [BOX1]: LCM: [ End Set ] in 0.0790 seconds. VERBOSE: Operation 'Invoke CimMethod' complete. VERBOSE: Time taken for configuration job to complete is 0.16 seconds PS C:UsersAdministrator> PS C:UsersAdministrator> Test-Path C: est.txt True
We get a lot of information back, so let's go over what we are seeing. It initially tells us that it's performing a DSC operation and the methods it's using to invoke. This is where we see that the Start-DscConfiguration
Cmdlet is just a wrapper over the CIM methods that actually execute the DSC functions. You won't need to know these CIM methods for everyday use, but it's interesting to see the inner workings shown here. The next line is telling us that all the subsequent lines come from our target node box1
and were initiated by a user with this SID. It doesn't look so important here as we're running on the same box we've compiled the MOF on; however, when we deal with remote pushes and note which target node had which operations occur on it, it becomes very important. The rest of the lines tell us that the file did not exist and that DSC had to create it. Not so hard, is it?