One of the more exciting things happening to Windows Server is that the way it’s managed is being rapidly changed. With the modern datacenter and it’s focus on scale and agility, the “old guard” of GUI and wizards has taken a back seat to scripts that can be saved and repeated en-masse to the hundreds and thousands of servers in a farm as needed. Few years back, Microsoft started pushing PowerShell as the primary interface to your Windows servers, and in 2013 they finally released Desired State Configuration, which is an open framework to enable true Infrastructure as a Code.
Infrastructure as Code isn’t actually a brand new concept, Puppet and Chef have been doing this for years. The key difference between DSC and something like Puppet is that the later is a complete management stack and thus can more completely maintain node information and draw reports which makes it more like SCCM. DSC, on the other hand, is just a framework and interface to allow Windows servers to accept standardized configurations so they can be more easily managed by said management stacks. Both Puppet and Chef have announced planned support for DSC in their products in the future, so in that aspect alone DSC has a long future ahead of it. But what if you’re a Windows shop and don’t want to invest in any 3rd product suite? Can you still leverage declarative scripts to push your configurations to your servers? The answer is yes, but it’s not without it’s headaches as, again … DSC is a framework without a full management toolset. While DSC is essentially “baked in” with WMF 4.0, complete with it’s own agent and pull server roles, by default it lacks in any method of organizing and tracking the various variables needed to to push configurations to your nodes, leaving that completely up-to the admin.
So I wrote my own functions to solve that problem.
The resulting project doubles as a training exercise for myself and thus I think is pretty ideal for anyone trying to get their feet wet in DSC as a concept. The entire release includes sample composite configurations and and simple install script to build a rather “folder heavy” structure to help navigate the various “parts” of DSC. I’m putting this up in hopes that others can ramp themselves up quickly as if you’re coming from a pure Windows world … a lot of these concepts are extremely foreign.
While I tried to make the module as flexible as possible, the default paths, if not specified, all search in the same basic location: C:\DSC-Manager. So if you grab the zip file from the release, that’s where you want all the contents. Once done, installation is pretty straight forward:
- If this is a fresh computer, run C:\dsc-manager\install-pullserver.ps1 to get everything setup. Just make sure you have a thumbprint for a cert ready to use. It will try to grab missing modules using PowerShellGet if it can, and tell you what modules are missing if it can’t.
- If you are just “enhancing” and existing pull server, simply add C:\dsc-manager\module to your $env:PSModulePath (or copy the modules into an existing path) and run Install-DSCMCertStores.
So what does a complete setup look like? Pretty simple really. The main DSC-Manager directory from the download plus the function creates three new folders in %programfiles%\WindowsPowerShell\DSCService folder: “AgentRegistration”, “Management”, and “NodeCertificates”. The Management folder actually contains the meat of why I started the little project: the dscnodes.csv file. If configurations are created using the functions provided, every node defined in your configuration data will have It’s GUID generated and tracked by this simple flat file. It will also track certificates needed for encryption (more on that later). Basically the “core” of what I tried to do with all of my functions is to constantly check/update this little file so that people can concentrate on making declarative configurations and not waste time looking up GUIDs or Thumbprints. As it’s a simple plain-text file, it’s probably something you don’t want to expose with a share and be wary of your NTFS security on the folder, unless until I feel ready to graduate to using a WID or SQL. Later version perhaps
For nodes, there’s also a C:\DSC-Manager\Initialize\install-node.ps1 designed to … well … install and configure an agent. Unlike a straight install, this script “acts” a little different. On first run it will dump a text file on the pull server saying it wants to “join” DSC. an admin can use add-xDSCMAgent –NodeName <computername> to answer that request it’s new GUID. Re-running the install-node script will then finish the install using the supplied GUID and delete the request. More on that on another part.
Installing the first Pull Server
Was a single bullet not enough info on setting up a Pull Server? Well lets do better here. In order to be a good multi-part blog, The Pull server will ultimately contain all the configurations of all your servers, much like a PuppetMaster or Primary Site Server in SCCM. There are a few ways to do this, but honestly I’m partial to using an IIS server with a certificate to use HTTPS. I think from a security perspective its just a “good idea”. Therefore, before you start building a pull server you need to make sure you have three things:
- You have a webserver certificate available and installed. Private key is obviously needed, but it doesn’t have to be a public cert, any private cert off a company PKI is fine, as long a the server nodes trust it.
- Windows Server 2012 R2 is installed with at least WMF4.0 and KB2883200. Much like when Hyper-V was first released, the KB is needed to make sure DSC works properly. We are at an “any day now” for WMF 5.0 which will make the KB irrelevant, but good to know for as of this moment WMF5 was pulled for a bug and can’t be downloaded.
- Optional: PowerShellGet. If you already have it installed, great. If not, download it and have it ready for the install script to use. You can grab it here: https://www.microsoft.com/en-us/download/details.aspx?id=49186. Note this is only for WMF version 3 or 4, If you have WMF5.0 it’s already included. Install scripts will try to grab missing modules with this, so the other option is to just grab the needed modules manually.
- Optional: xPSDesiredStateConfiguration module. Install scripts will attempt to download this if it can’ find it using PowerShellGet. You can always download it yourself, or use PoweShellGet and a simple install-module xPSDesiredStateConfiguration.
Assuming you have all this taken care of, we can get the install rolling:
1) Download https://github.com/Justin-DynamicD/DSC-Manager/releases and unzip the contents into the base C:\DSC-Manager directory.
2) Open up PowerShell as an Administrator, then navigate to C:\DSC-Manager\Initialize. Let’s run the installation using the thumbprint (required) and PowerShellGet path (if need).
.\Install-PullServer.ps1 –thumbprint <thumbprint> –powershellgetinstaller <msi path>
This will download and install modules then start the configuration. In theory … that’s it! Realistically you’ll be prompted a few times by the PowerShellGet installer for NuGet and to validate your install.
Note: if you install too much at once … you may need to restart your PowerShell Session. On my many test cases I’ve had “random” events where a newly downloaded resource isn’t detected by the start-dscconfiguration for reasons that don’t make the most sense. Joys of pre-release PowerShellGet perhaps? Anyway, a simple session restart then run the script again and it seems to solve the problem.
Installing a Node to check in with the Pull Server
Once the Pull server is up and running, you still need to register some nodes to use it. Again, an install-node.ps1 is provided. In this case, copy the singular node over to the agent you want to manage. Getting that node on the system has a few steps now, but mostly bcuase I tried ot merge some management into to the system:
1)Open up PowerShell as an Administrator, then navigate to your folder and run the following:
.\Install-Node.ps1 –pullserver <Pull server FQDN>
The FQDN will obviously be the Pull Server, and use a URL present on the certificate you used during that install.
Ill probably silent this output in a later release, but for now its good to see what it’s doing. the script will look if a certificate exists on the node and if it does … copies it to the cert store on the pull server. It also copies a simple text file, which is essentially the request.
2) On the DSC PullServer, use the cmdlet to approve the pending request:
Add-xDSCMAgent –NodeName <Server Name>
This simple function does a few things behind the scenes. It looks at the dscnodes.csv, and grabs a GUID if one has already been assigned to the node, and generates one one if not. It also checks for a certificate file with the same name, and if it exist it records the thumbprint to the same csv file. Because: management.
3) Return to the Node in question, and run the exact same command again. This time something different should happen:
The GUID will get pulled back from the request file, the configuration will occur, and then the request is deleted for security reasons. In the end, if you look into your C:\ProgramFiles\WindowsPowerShell\DSCService\Management\dscnodes.csv, you’ll see everything tracked:
Yeah, don’t reveal these numbers on your production system … but from my lab, why not. But anyway, you now have a system of of nodes checking into your Pull Server, and a file that keeps a record of node names and their associated GUID and Certificates. Which means we are now ready for our next next part: configuring some code to manage DSC. But that will be in Part-2.