There are several DSC Resources that come-the-box with a PowerShell install. These DSC Resources are enough to get you started and cover most basic system and software configuration tasks; however, you are not expected to survive on these alone. Remember, we want to be as specific and custom as possible with a DSC Resource, or it is of little use for us. At some point, you will want to find more DSC Resources than those that come installed by default, but where do you go to get them?
Ruby has rubygems.org, Perl has CPAN, Node has npm, but what does DSC have? Since DSC is still "new," there are many places to find official and community provided DSC Resources, but there isn't one place that everyone has agreed on to use. This is to be expected with a new software product; things are new and in flux and both the community and Microsoft haven't sorted out the best approaches for distribution yet. Things like this happen over time as various approaches are tried out and run through the gauntlet of production systems.
It took a long time for systems such as CPAN and npm to work out the kinks and be accepted as the default resources for both the companies that made them as well as the community that uses them. With this in mind, it's no surprise that Microsoft started out with one approach and is now moving toward a different approach. But we are getting ahead of ourselves; let's cover each available option one by one.
Microsoft's first approach is the DSC Resource Kit. These harken back to the Windows Resource Kits of old that first started coming out in the Windows NT days. The Windows Resource Kit was a bundle of several utilities that may not have had the same support guarantees as the built-in tools of Windows, but nonetheless provided needed functionality that system administrators came to rely on.
The DSC Resource Kit is similar in approach, in that it contains several DSC Resources bundled together into one ZIP file that you download from the Microsoft Script Center. However, they do not come with any support guarantees and are very much a "use at your own risk" type of option. This sounds like a dangerous idea and not something you would expect from Microsoft. You're used to getting production quality tools ready to use in your environment from Microsoft at day 1 of their release. This was a good approach for Microsoft in the past, but in today's world delivering that kind of quality means months to even years of development and testing. Instead, Microsoft is following an agile cadence in releasing these DSC Resources and producing a new release every month or so. By releasing these DSC Resource Kits earlier in the development cycle, Microsoft delivers the tools faster to end users and also gets feedback earlier (when it can actually be acted upon and not months down the line when decisions are immutable). Users get the DSC Resources they need sooner, but have to balance that with testing these DSC Resources themselves.
However convenient they are these, Resource Kits are hard to deploy in your environments. They were released in "waves" over the course of a year, each release happening every month or so. Users received a human-typed list of changes and features added, but no real way to see the differences between releases. Extensive testing had to be employed to ensure the new DSC Resource at least behaved as well or better than the last release. These "waves" frequently had missing DSC Resources that were present in the last release or they deprecated a DSC Resource without telling the end user in the release notes, causing a surprise when it came time to use it. This made it quite evident that the process of releasing a Resource Kit wave was a human zipping a folder by hand and writing up release notes after the fact, not an automated process executed in tandem with development.
The largest negative for this approach (as if the previous observations weren't enough), and most likely the reason Microsoft has deemphasized this approach, is that it still took a long time for these Resource Kits to get to end users. It was a month or more between "waves," and then the only way an end user knew there was a new release was to see it on the Windows PowerShell Blog or through social media. While the PowerShell community is great at disseminating information quickly, this informal approach is not something to rely on as an update notification measure, and not one Microsoft really expected to stay as is.
Installing DSC Resource Kits is a simple, if very manual, process:
$env:ProgramFilesWindowsPowerShellModules
folder on all target nodes.These steps are repeated for every new release and every new target machine.
The DSC Resources provided in the Resource Kits were developed at an agile cadence, which meant that the community received the DSC Resources faster than the traditional development schedules could handle. This speed also meant that bugs were being caught by the community instead of through internal testing. The PowerShell community is a powerful force full of some very smart people; when they are presented with a problem, they find a solution. Ultimately, they found solutions to these bugs but had nowhere to submit them.
Seeing the need to have the official DSC Resources developed in the open and in a manner that could accept contributions from the community, the Microsoft PowerShell team open-sourced all the existing DSC Resources that were previously only available inside the Resource Kits and put them up on GitHub at https://github.com/powershell/DscResources or as we will refer to it from now on: PowerShell/DscResources
.
Gone are the days of finding a solution to a problem in an existing DSC Resource and not being able to share your solution with the community. With a little bit of Git knowledge, you can commit your fix to the PowerShell/DscResource
repositories and see your fix directly used by anyone using that module.
If at this point you're seeing Git and GitHub and wondering what the author is going on about, you shouldn't worry, as you are not alone. Git is a version control system for software code and is currently the cream of the crop of VCS software. If Git is new to you, you should take some time to learn about it before you try to commit your fixes or features to the community. There are many books and resources online to help you learn Git, and going to https://git-scm.com/ will get you on your way.
If you do not feel like learning Git at this point, do not worry; this book will assume some basic Git knowledge only for this section and it will not be needed for the rest of the chapter.
When we refer to the PowerShell/DscResources
GitHub repository, we actually mean repositories. The PowerShell team created a GitHub organization and created a repository per DSC Resource module. While this resulted in many repositories (currently 52 and counting) and sounds like a hard-to-manage solution, this approach makes sense. You want to have each DSC Resource module be a unique unit where bug reports and feature requests can be made without confusing things for other DSC Resources. A repository per DSC Resource module also allows separate versioning per DSC Resource, which is a must when dealing with so many different moving parts. You want to be able to say that an increment to the version of the xTimeZone
DSC Resource does not mean the user has to update the xWinEventLog
DSC Resource, as well.
This does make consuming these DSC Resources slightly cumbersome. You could maintain a separate clone locally of each DSC Resource repository, and keep them up-to-date yourself. Doing this, however, puts you in charge of tracking versioning and tags and determining when a given DSC Resource is "stable."
Another approach is to use the PowerShell/DscResources
repository. This repository is a mostly empty repository that contains Git submodules, or links, to all the individual DSC Resource repositories. When cloning https://github.com/PowerShell/DscResources.git, you tell Git to recursively check out all the Git submodules as well as the main repository:
git clone https://github.com/PowerShell/DscResources.git --recurse -submodules
Git submodules and their use are a hot topic in developer circles. There is a lot of opinion and disagreement out there on how to use them or whether to use them at all, which is mostly beyond the scope of this book. What is germane to our use case is that Git submodules are point-in-time links to a certain Git commit. This means that, when checking out the PowerShell/DscResources
repository, we do get all DSC Resources but at the latest Git commit they have been pinned at. If active development is going on in a given DSC Resource repository, it won't be reflected in the PowerShell/DscResources
repository because it has not been updated to point at the newer commit. This is not a bad thing, just something to keep in mind if you are exclusively using the PowerShell/DscResources
repository. This is something that Microsoft is working to address, as documented in their issue tracker (https://github.com/PowerShell/DscResources/issues/31).
While GitHub is a great development experience and a great way to see how the DSC Resources you are using are being worked on, this does not lend itself well to some operational deployment models. You will have to either clone the main PowerShell/DscResources
repository or keep up with all the available DSC Resource repositories on GitHub. Then, once those are all cloned, you'll have to take the local copy and distribute it out to your target nodes or to your DSC Pull Servers yourself. Sure, you can automate some of this and get a pretty good script going, but if this all feels like a "solved problem" that you shouldn't be worrying about, you are not alone. The Microsoft PowerShell Gallery addresses this issue.
The Microsoft PowerShell Gallery (or PSGallery) is a central repository for PowerShell modules and DSC Resources and is the premier choice for consuming and deploying DSC Resources. The PowerShell Gallery contains useful PowerShell modules and DSC Resources that you can use on all your target servers. Not all of the content in the gallery will be from Microsoft; some of it will be community contributed content. It is recommended that you test and inspect all content downloaded from the gallery.
To use the PowerShell Gallery, you must use a new feature of PowerShell v5 called PackageManagement
. Although work is being done to support PowerShell v4, it is not completed yet. PackageManagement
is a software package manager that manages packages. All joking aside, PackageManagement
is a powerful solution to the problem of finding, downloading, and installing software onto Windows target nodes.
At its core, PackageManagement
handles the searching for and resolving of software packages and installing those packages on target nodes. The beauty of PackageManagement
is that it delegates the details of package resolution and installation to submodules that handle the specifics of each software package and platform. This enables PackageManagement
to leave the implementation details to the "last mile" and worry about the larger issues at stake, resulting in faster, more nimble releases and allowing a large plugin community to grow to address any need.
PackageManagement
is currently targeted for release with PowerShell v5, but it supports down-level versions of Windows and PowerShell. The following has been tested as working on PowerShell v4, but as it is still in development, there may be steps changed or parts of this list that will be out-of-date at print time. In that case, please see the PackageManagement
documentation or the PowerShell Gallery for more information.
PackageManagement
comes preinstalled in any PowerShell v5 installation, but there are down-level packages available for the other PowerShell versions. PackageManagement
is in the last stages of very active development, so unfortunately, at the time of this publishing the distribution method of PackageManagement
for down-level versions is not set in stone.
Each PowerShell v5 installation package is a Windows Update Standalone Installer package or MSU. MSU responds to standardized command-line automation or through a user interface, so deploying PowerShell v5 manually or through software deployment systems such as Windows Update or SCOM should be relatively straightforward.
Once installed, you have to initialize PackageManagement
by running a command to the "bootstrap" NuGet on the target node. This can either be done on demand when a call to PackageManagement
is performed, such as Find-Module
or Install-Module
, or can be done interactively on the command line like so:
[PS]> Get-PackageProvider -Name NuGet –ForceBootstrap NuGet-anycpu.exe is required to continue. PowerShellGet requires NuGet-anycpu.exe to interact with NuGet based galleries. NuGet-anycpu.exe must be available in 'C:Program FilesPackageManagementProviderAssemblies' or 'C:UsersJamesAppDataLocalPackageManagementProviderAssemblies'. For more information about NuGet provider, see http://OneGet.org/NuGet.html. Do you want PowerShellGet to download NuGet-anycpu.exe now? [Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
Once bootstrapped, PackageManagement
will have all it needs to resolve and install packages.
Discovering DSC Resources in the PowerShell Gallery is a primary use case for the PSGallery and for PackageManagement
, so it is no surprise that it is an easy and smooth task.
You can find all the available DSC Resources in the PSGallery. While you can use the website to search for and find DSC Resources, most searching and discovery you perform will be done using the Find-Module
Cmdlet. Find-Module
will work on any PackageManagement
provider, but here we will focus just on the PSGallery:
[PS]> Find-Module -Includes DscResource Version Name Repository Description ------- ---- ---------- ----------- 0.2.16.6 xJea PSGallery Module with DSC Resources for Just Enough Admin ... 1.6.0.0 xWebAdministration PSGallery Module with DSC Resources for Web Administration 3.3.0.0 xPSDesiredStateConfiguration PSGallery The xPSDesiredStateConfiguration module is a par... 1.2.0 xDatabase PSGallery This module contains 2 resources. xDatabase allo... 1.3.0 xComputerManagement PSGallery The xComputerManagement module is originally par... 2.0.0 xWindowsUpdate PSGallery Module with DSC Resources for Windows Update 2.4.0.0 xActiveDirectory PSGallery Module with DSC Resources for Active Directory
You can search for a specific DSC Resource using its name or wildcards:
[PS]> Find-Module -Name xWinEventLog Version Name Repository Description ------- ---- ---------- ----------- 1.0.0.0 xWinEventLog PSGallery Configure Windows Event Logs [PS]> Find-Module -Name xWin* Version Name Repository Description ------- ---- ---------- ----------- 1.0.0.0 xWindowsEventForwarding PSGallery This module can be used to manage configuration ... 1.0.0 xWindowsRestore PSGallery This DSC Module includes 2 DSC resources, xSyste... 2.0.0 xWindowsUpdate PSGallery Module with DSC Resources for Windows Update 1.0.0.0 xWinEventLog PSGallery Configure Windows Event Logs
You can also search with a new cmdlet they have recently added called Find-DscResource
:
[PS]> Find-DscResource -moduleName xWebAdministration Name Version ModuleName Repository ---- ------- ---------- ---------- xIisFeatureDelegation 1.7.0.0 xWebAdministration PSGallery xIisHandler 1.7.0.0 xWebAdministration PSGallery xIisMimeTypeMapping 1.7.0.0 xWebAdministration PSGallery xIisModule 1.7.0.0 xWebAdministration PSGallery xWebApplication 1.7.0.0 xWebAdministration PSGallery xWebAppPool 1.7.0.0 xWebAdministration PSGallery xWebAppPoolDefaults 1.7.0.0 xWebAdministration PSGallery xWebConfigKeyValue 1.7.0.0 xWebAdministration PSGallery xWebsite 1.7.0.0 xWebAdministration PSGallery xWebSiteDefaults 1.7.0.0 xWebAdministration PSGallery xWebVirtualDirectory 1.7.0.0 xWebAdministration PSGallery
The Cmdlet Install-Module
is used to install DSC Resources from the PSGallery. It installs DSC Resources to the $env:ProgramFilesWindowsPowerShellModules
directory by default, which requires administrator privileges:
[PS}]> Install-Module -Name xWinEventLog -Verbose VERBOSE: The -Repository parameter was not specified. PowerShellGet will use all of the registered repositories. VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'. VERBOSE: The specified Location is 'https://www.powershellgallery.com/api/v2/' and PackageManagementProvider is 'NuGet'. VERBOSE: The specified module will be installed in 'C:Program FilesWindowsPowerShellModules'. VERBOSE: The specified Location is 'NuGet' and PackageManagementProvider is 'NuGet'. VERBOSE: Downloading module 'xWinEventLog' with version '1.0.0.0' from the repository 'https://www.powershellgallery.com/api/v2/'. VERBOSE: NuGet: GET https://www.powershellgallery.com/api/v2/Packages(Id='xWinEventLog',Version='1.0.0.0') VERBOSE: NuGet: GET https://www.powershellgallery.com/api/v2/package/xWinEventLog/1.0.0 VERBOSE: NuGet: Installing 'xWinEventLog 1.0.0.0'. VERBOSE: NuGet: Successfully installed 'xWinEventLog 1.0.0.0'. VERBOSE: Module 'xWinEventLog' was installed successfully.
You can also pipe Find-Module
to Install-Module
:
[PS]> Find-Module –Name xWinEventLog | Install-Module
By default, Install-Module
installs the latest version of a DSC Resource, so if you are looking for a specific version, you can specify the RequiredVersion
parameter:
[PS]> Install-Module –Name xWinEventLog –RequiredVersion 1.1.0.0
You can list the installed DSC Resources two ways:
[PS]> Get-DscResource ImplementedAs Name Module Properties ------------- ---- ------ ---------- Binary File {DestinationPath, Attributes, Checksum, Con... PowerShell Archive PSDesiredStateConfiguration {Destination, Path, Checksum, Credential...} PowerShell Environment PSDesiredStateConfiguration {Name, DependsOn, Ensure, Path...} PowerShell Group PSDesiredStateConfiguration {GroupName, Credential, DependsOn, Descript... Binary Log PSDesiredStateConfiguration {Message, DependsOn} PowerShell Package PSDesiredStateConfiguration {Name, Path, ProductId, Arguments...}
You can also specify the exact name to check if a DSC Resource is present:
[PS]> Get-DscResource -Name xWinEventLog ImplementedAs Name Module Properties ------------- ---- ------ ---------- PowerShell xWinEventLog xWinEventLog {LogName, DependsOn, IsEnabled, LogMode...}
At some point, you might want to create your own host for DSC Resources. Maybe you'll want to host your own DSC Resources for your company or you might want to maintain a local copy of DSC Resources so you don't have to go to the Internet every time you provision a machine. Whatever the reason, hosting your own DSC Resource repository is a reasonable desire. Unfortunately, there are not many readymade solutions out there that work without significant effort. Microsoft has said it is working on a solution, but has not produced one yet.
If you have a file share ready to hold all your DSC Resources, you can create a repository that PackageManagement
will use to resolve and install your DSC Resources.
In order to avoid any issues with DSC Resources you may have created during the course of the book, we will use the xWebAdministration
module. You can download it from the Microsoft GitHub repo at https://github.com/PowerShell/xWebAdministration. If you already have it present on the test system, remove it. If you are using a copy of xWebAdministration
that you installed from the PSGallery, you may have a second subfolder with the module version as its name. Be sure to point the following commands to that folder name instead of the root xWebAdministration
one so that the Publish-Module
Cmdlet can properly find the .psd1
files.
The first step is to register the network share as a repository:
[PS]> Register-PSRepository -Name folder -SourceLocation D:packages -PublishLocation D:packages -Verbose VERBOSE: Repository details, Name = 'PSGallery', Location = 'https://www.powershellgallery.com/api/v2/'; IsTrusted = 'False'; IsRegistered = 'True'. VERBOSE: Performing the operation "Register Module Repository" on target "Module Repository 'folder' (D:packages) in provider 'PSModule'". VERBOSE: The specified PackageManagement provider name 'NuGet'. VERBOSE: Successfully registered the repository 'folder' with source location 'D:packages'. VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False'; IsRegistered = 'True'.
The next step is to publish your DSC Resource package to the folder using the Publish-Module
Cmdlet. One thing to note is that we pass a value to the NugetApiKey
parameter that doesn't mean anything. This is because we are pushing to a local folder and not a NuGet server like the PSGallery. Publish-Module
expects you to be pushing to a PSGallery-based repository, but will function just the same with a folder:
[PS]> Publish-Module -Path 'C:examplexWebAdministration' -NugetApiKey 'j' -Repository folder -Verbose VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False';IsRegistered = 'True'. VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False';IsRegistered = 'True'. VERBOSE: Module'xWebAdministration' was found in 'C:Program FilesWindowsPowerShellMOdulesxWebAdministration'. VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False';IsRegistered = 'True'. VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False';IsRegistered = 'True'. VERBOSE: Using the specified source names : 'folder'. VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'. VERBOSE: The specified Location is 'D:packages' and PackageManagementProvider is 'NuGet'. VERBOSE: Performing the operation "Publish-Module" on target "Version '1.7.0.0' of module 'xWebAdministration'". VERBOSE: Successfully published module 'xWebAdministration' to the module publish location 'D:packages'. Please allow few minutes for 'xWebAdministration' to show up in the search results.
Installing the module works just as if you were installing from the PSGallery, except you specify which repository you want to install it from:
[PS]> Install-module -Name xWebAdministration -Repository folder -Verbose -Force -RequiredVersion 1.7.0.0 VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False'; IsRegistered = 'True'. VERBOSE: Repository details, Name = 'folder', Location = 'D:packages'; IsTrusted = 'False'; IsRegistered = 'True'. VERBOSE: Using the specified source names : 'folder'. VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'. VERBOSE: The specified Location is 'D:packages' and PackageManagementProvider is 'NuGet'. VERBOSE: The specified module will be installed in 'C:Program FilesWindowsPowerShellModules'. VERBOSE: The specified Location is 'NuGet' and PackageManagementProvider is 'NuGet'. VERBOSE: Downloading module xWebAdministration with version '1.7.0.0' from the repository 'D:packages'. VERBOSE: NuGet: Installing 'xWebAdministration 1.7.0.0'. VERBOSE: NuGet: Successfully installed 'xExampleResource 1.7.0.0'. VERBOSE: Module 'xWebAdministration' was installed successfully.
Another solution builds off of the work the NuGet team did for hosting their own packages. Instructions for setting this up are at http://blogs.msdn.com/b/powershell/archive/2014/05/20/setting-up-an-internal-powershellget-repository.aspx. This is honestly the hardest to set up as it requires you to compile ASP.NET projects and deploy websites yourself. This may be too much work for you to do, or it may be a piece of cake depending on your experience level.
There are several NuGet server options that are from the community and also run on non-Windows systems. An open source project called Chocolatey has a good guide on how to use these at https://github.com/chocolatey/choco/wiki/How-To-Host-Feed#non-windows-hosting.