DSC
DSC came out in PowerShell version 4 and it will work with Windows 7 and 2008R2 providing they have WMF4 or 5 installed.
DSC can be used in both pull and push modes. So far I have only used push mode outside of the lab. I kind of prefer to be in control.
Configurations are declarations of what you want the machine to look like. The make it so document.
It is the local configuration manager that actually does the work needed to make it so. This is in push mode by default but needs to be configured if you want to use a pull server.
Also by default it is set to apply and monitor. If you are using a pull server it will need to be set to autoconfig.
Setting The LCM PowerShell v4
Configuration LCMPUSH {
Node $ComputerName {
LocalConfigurationManager{
AllowModuleOverwrite = $true
ConfigurationMode = 'ApplyAndAutoCorrect'
RefreshMode = 'Push'
}
}
}
$ComputerName = "svr1","svr2"
Setting The LCM in PowerShell v5
[DscLocalConfigurationManager()]
Configuration LCMPUSH{
Node $ComputerName{
Settings{
AllowModuleOverwrite = $true
ConfigurationMode = 'ApplyAndAutoCorrect'
RefreshMode = 'Push'
}
}
}
$ComputerName = "svr1","svr2"
LCMPUSH -outputpath c:\DSC\LCM
break; #This will create svr1.meta.mof and svr2.meta.mof
#finally run
Set-DscLocalConfigurationManager -ComputerName $computername -Path c:\dsc\lcm -Verbose
A list of DSC commands
PS C:\> Get-Command -Module PSDesiredStateConfiguration | ft commandtype,name -AutoSize
CommandType Name
----------- ----
Function Configuration
Function Disable-DscDebug
Function Enable-DscDebug
Function Get-DscConfiguration
Function Get-DscConfigurationStatus
Function Get-DscLocalConfigurationManager
Function Get-DscResource
Function New-DscChecksum
Function Remove-DscConfigurationDocument
Function Restore-DscConfiguration
Function Stop-DscConfiguration
Cmdlet Invoke-DscResource
Cmdlet Publish-DscConfiguration
Cmdlet Set-DscLocalConfigurationManager
Cmdlet Start-DscConfiguration
Cmdlet Test-DscConfiguration
Cmdlet Update-DscConfiguration
Function Find-DscResource PowerShellGet
When DSC first came out it had 12 built in resources it now has 25 as of June 2020
PS C:\> (Get-DscResource).name
File
SignatureValidation
PackageManagement
PackageManagementSource
Archive
Environment
Group
GroupSet
Log
Package
ProcessSet
Registry
Script
Service
ServiceSet
User
WaitForAll
WaitForAny
WaitForSome
WindowsFeature
WindowsFeatureSet
WindowsOptionalFeature
WindowsOptionalFeatureSet
WindowsPackageCab
WindowsProcess
PS C:\> (Get-DscResource).count
25
The Basic structure of a DSC configuration is:
configuration Testconfig {
node s1 {
windowsfeature webserver {
}
}
}
Find-DscResource can be used to search all of the resourses in the PSGallery
You can find the syntax for DSC resources by using Get-DscResource [name] -Syntax
PS C:\> Get-DscResource file -Syntax
File [String] #ResourceName
{
DestinationPath = [string]
[Attributes = [string[]]{ Archive | Hidden | ReadOnly | System }]
[Checksum = [string]{ CreatedDate | ModifiedDate | SHA-1 | SHA-256 | SHA-512 }]
[Contents = [string]]
[Credential = [PSCredential]]
[DependsOn = [string[]]]
[Ensure = [string]{ Absent | Present }]
[Force = [bool]]
[MatchSource = [bool]]
[PsDscRunAsCredential = [PSCredential]]
[Recurse = [bool]]
[SourcePath = [string]]
[Type = [string]{ Directory | File }]
}
addSecGroups
This script is designed to create two security groups for the nominated machine SEC_machineName_Admin and SEC_machineName_RDP it then uses DSC to place these security groups into the administrators group and the Remote Desktop Users group as appropriate.
This script is meant to be run from the ISE with Domain Admin priveleges. The variable $node needs to be changed to the name of the server you want
to do this to and when the script has been executed and the mof file has been created, hightlight the line after the break statement and press f8
Start-DscConfiguration -Path C:\dsc\config -ComputerName $node -Verbose -wait -force
configuration addSecGroups{
Import-DscResource -ModuleName PSDesiredStateConfiguration
node $node{
Group RemoteDesktopUsers {
GroupName = "Remote Desktop Users"
Members = $rdp
}
Group Administrators {
GroupName = "Administrators"
MembersToInclude = $admins
}
}
}
function new-PF_SecGroup{
[cmdletbinding()]
param(
[Parameter(Mandatory=$true)]
$name,
[Parameter(Mandatory=$true)]
[ValidateSet("Admin", "RDP")]
$type
)
if($type -eq "Admin"){
$ending = "_Admin"
$path = "OU=Server-Admin,OU=Security,DC=company,DC=pri"
}else{
$ending="_RDP"
$path = "OU=Server-RDP,OU=Security,DC=company,DC=pri"
}
$gname = "SEC_" + $name + "$ending"
new-adgroup -Name $gname -Path $path -GroupScope Global -GroupCategory Security
}
$node = "Server01"
$rdp = "company\SEC_" + $node + "_RDP"
$admins = "company\SEC_" + $node + "_Admin"
$rdpt = "SEC_" + $node + "_RDP"
$admint = "SEC_" + $node + "_Admin"
#region test for security groups and make them if necessary
try{
Get-ADGroup $rdpt -ErrorAction Stop | Out-Null
}
catch{
new-PF_SecGroup -name $node -type rdp
}
try{
Get-ADGroup $admint -ErrorAction Stop | Out-Null
}
catch{
new-PF_SecGroup -name $node -type Admin
}
#endregion
addSecGroups -outputpath c:\dsc\config
break;
Start-DscConfiguration -Path C:\dsc\config -ComputerName $node -Verbose -wait -force
Installing chrome
Install-module xchrome -force
configuration InstallChrome {
Import-DSCResource -Module xchrome -Name msft_xchrome
node $computername {
msft_xchrome installme
{
language = 'en'
}
}
}
$computername = hostname
InstallChrome -outputpath c:\dsc\config
break
Start-DscConfiguration -Path C:\dsc\config -ComputerName $computername -Verbose -wait -force
Test-DscConfiguration -ComputerName $computername
IE Enhanced Security
The following configuration can be used to turn off the annoying enhansed security settings for Internet Explorer
configuration IES {
Import-DSCResource -Module xSystemSecurity -Name xIEEsc
node $computername {
xIEEsc EnableIEEscAdmin
{
IsEnabled = $False
UserRole = "Administrators"
}
xIEEsc EnableIEEscUser
{
IsEnabled = $True
UserRole = "Users"
}
}
}
$computername = hostname
IES -outputpath c:\dsc\config
Start-DscConfiguration -Path C:\dsc\config -ComputerName $computername -Verbose -wait -force
Test-DscConfiguration -ComputerName $computername
This can also be done by using the registry resource (I havn't tested this one lately it may needs some tweeks to work but the structure is sound.)
configuration enhanced
{
# One can evaluate expressions to get the node list
# E.g: $AllNodes.Where("Role -eq Web").NodeName
node $computername
{
registry ESC {
key = 'HKEY_local_machine\software\microsoft\active setup\installed components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}\'
valuename = "isinstalled"
valuedata = 0
valuetype = "dword"
}
registry ESC1 {
key = 'HKEY_local_machine\software\microsoft\active setup\installed components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}\'
valuename = "isinstalled"
valuedata = 0
valuetype = "dword"
}
}
}
$computername = hostname
enhanced -outputpath c:\dsc\config
Start-DscConfiguration -Path C:\dsc\config -ComputerName $computername -Verbose -wait -force
Test-DscConfiguration -ComputerName $computername
Finding product number for package resource
In order to install programs with the DSC package resource you need the product number.
You can do that by going to a machine that already has the package installed and running the following command:
gwmi win32_product |select name,identifyingnumber
name identifyingnumber
---- -----------------
Google Chrome {25D02A91-99C1-38B7-8A36-2C5B1836C4CB}
Google Update Helper {60EC980A-BDA2-4CB6-A427-B07A5498B4CA}
In order to package you need:
package productName {
Name = [string]
Path = [string]
ProductId = [string]
}
The full syntax is as follows:
PS C:\WINDOWS\system32> Get-DscResource package -Syntax
Package [String] #ResourceName
{
Name = [string]
Path = [string]
ProductId = [string]
[Arguments = [string]]
[Credential = [PSCredential]]
[DependsOn = [string[]]]
[Ensure = [string]{ Absent | Present }]
[LogPath = [string]]
[PsDscRunAsCredential = [PSCredential]]
[ReturnCode = [UInt32[]]]
}
