Monday, 23 October 2017

Learn PowerShell DSC - Part 5

Introduction

Welcome to part 5! Hopefully you’re getting the hang of pushing out DSC configurations and are wondering if there are other ways to deploy DSC configurations and in fact, you’re in luck! Today’s we’ll go through how you can get the target machine to automatically pull the DSC configuration rather than you having to push it out.

There are two methods you can use to pull DSC configurations - SMB and HTTP/HTTPS. We’ll go through the simplest one first - SMB pull.

What is DSC SMB Pull?

SMB Pull allows you to store your DSC configurations (.MOF) in an SMB share which the target machines then connect to, download and apply their configurations. There are three steps we will go through:

  • Set up a DSC SMB Pull Server
  • Configure target machine for DSC SMB Pull
  • Create DSC configuration for SMB pull target machine

Once done, we basically create a DSC configuration, target it at the target machine and also create a checksum file. We’ll go through this in more detail later on.

Set up a DSC SMB Pull Server

Now, this is easy. Just create a share and provide read access to the computer account of the target machine. This is because DSC runs as the Local System account by default.

1. Create a folder e.g. C:\DSCSMB

2. Share the folder as DSCSMB and grant full control to Everyone:

image

3. Configure the NTFS permissions by disabling inheritance, removing permissions for Users and granting read only permissions for the target machine computer account or an AD group which contains the computer accounts.As I’m just doing a demo, I’ll assign permissions to “Contoso\Domain Computers”.

image

Configure target machine for DSC SMB Pull

By default, DSC is configured for push configurations only and obviously it has no idea that we have an SMB Pull server or what its UNC path is so we’ll need to configure this. The DSC local configuration is configured using the the DSC Local Configuration Manager or LCM for short. The LCM is a WMI provider built into PowerShell v4 and later.

To configure DSC using the LCM, you basically create a configuration specifying [DSCLocalconfigurationManager()] and then you can create a MOF file, and then push this out to your target server using Set-DscLocalConfigurationManager.

1. Create the LCM configuration as below. Note that we’re specifying the parameters:

    • ConfigurationID: This is the ID of the LCM on the target machine and is used to find the correct configuration to apply as there may be many configurations for other machines in the same share
    • RefreshMode: This sets out LCM to pull instead of push which is the default
    • SourcePath: This is the UNC path of our DSC SMB Pull server

[DSCLocalconfigurationManager()]
Configuration Configure_LCM_SMBPULL 
{
    param
        (
            [Parameter(Mandatory=$true)] 
            [string[]]$ComputerName,

            [Parameter(Mandatory=$true)]
            [string]$guid 
        )
        
Node $ComputerName
{
Settings {
            RefreshMode = 'Pull' 
            ConfigurationID = $guid
        }
          
ConfigurationRepositoryShare DSCSMB {
            Sourcepath = "\\contchidsc01\DSCSMB" 
        }  
}
}

2. Specify the computer name and the GUID. Here we’re creating a new GUID.

$ComputerName='contchisql01'
$guid=[guid]::NewGuid()

3. Create the MOF file however it’s a .meta.mof file for the LCM

Configure_LCM_SMBPULL -ComputerName $ComputerName -Guid $guid -OutputPath C:\Scripts\DSC

image

4. We now configure the LCM on the target machine using Set-DscLocalConfigurationManager

Set-DscLocalConfigurationManager -ComputerName $ComputerName   -Path C:\Scripts\DSC -Verbose

image

5. Our LCM should now be configured and we can use Get-DscLocalConfigurationManager to confirm our settings:

$a = Get-DscLocalConfigurationManager -CimSession $ComputerName 
$a | ft PSComputerName,RefreshMode,ConfigurationID,`
@{Name='ConfigurationRepositoryShare';Expression=`
{[string]$_.ConfigurationDownloadManagers.SourcePath}}

image

We can see that RefreshMode is set to Pull, a ConfigurationID is assigned and the ConfigurationRepositoryShare to our DSC SMB Pull server UNC path. Great! Our next task is to create a configuration for the target server and store it in the SMB share.

Create DSC configuration for SMB pull target machine

This is basically the same as creating a normal DSC configuration but instead of naming the mof file contchisql01.mof, we need to name it using the ConfigurationID of the target machine LCM i.e. c46a4a4b-8b5f-49e5-90f4-faaf80e2ec9f.mof. We also need to create a checksum file called c46a4a4b-8b5f-49e5-90f4-faaf80e2ec9f.mof.checksum.

1. Create your configuration as normal. See my example one below which basically just creates a text file C:\testfile1.txt and sets the contents to My test file

Configuration CreateTestFile {
   
    Param (
    [Parameter(Mandatory=$true)]
    [string]$ComputerName
    )
   
    Import-DscResource -ModuleName PSDesiredStateConfiguration

   
    Node $ComputerName {
   
        File CreateTestFile {
            Type = 'File'
            DestinationPath = 'C:\testfile1.txt'
            Contents = 'My test file'
            }
        }

}

2. Specify the computer name and create your MOF file

$ComputerName = "contchisql01"
CreateTestFile -ComputerName $ComputerName -OutputPath C:\Scripts\DSC

image

3. Get the LCM ConfigurationID and copy the mof file to the SMB share with a name <ConfigurationID>.mof

$guid=(Get-DscLocalConfigurationManager -CimSession $ComputerName).ConfigurationID
$DestinationFile = 'C:\DSCSMB\' + $guid + '.mof'
Copy-Item C:\Scripts\DSC\$ComputerName.mof $DestinationFile -Force

image

4. Create a checksum file in the SMB share: <ConfigurationID>.mof.checksum

New-DscChecksum $DestinationFile -Force

image

5. Now you can either wait 30mins for the target machine to apply the configuration or you can force it using Update-DscConfiguration

Update-DscConfiguration -ComputerName $ComputerName -Wait -Verbose

image

6. That looks successful so let’s confirm our file is there and the contents are set:

Get-Content '\\contchisql01\c$\testfile1.txt'

image

There you have it - our test file is created!

Conclusion

In this post, we configured an SMB pull server then configured the LCM on a target machine to use the pull server. We then created a configuration for the target machine and put this in the SMB share and confirmed the target machine can pull it and apply it.

In the next post, we’ll look at HTTP pull servers.

Wednesday, 4 October 2017

VSCode - Keep focus on editor

In VSCode, you’ll find that when you run your script using F8 or F5, your focus will shift to the terminal which may not be what you want especially as ISE doesn’t change the focus.

To change this behaviour, just click on the settings icon and go to settings:

image

Then add the below line into the user settings window on the right:

"powershell.integratedConsole.focusConsoleOnExecute": false

It should now look like this:

image

Close User Settings and save your changes and there you go.

Monday, 18 September 2017

Create a PowerShell Module

Introduction

When you build up your own library of functions, it’s really useful to have them always available on your machine without you having to load script files etc. This is where creating your own PowerShell module comes in handy. You can have all your functions available in this module and just take it around wherever you go.

Today, I’m going to write a simple function and then create my own module which includes this function.

How to build a PowerShell module

So, this is really not as hard as it seems. The basic steps are below:

  1. Create your functions in a single .psm1 file
  2. Copy your .psm1 file into one of the PowerShell module folders
  3. Create a module manifest

1 - Create your functions and save the file as .psm1

I’ve created three simple functions below:

function Get-LoggedOnUser
    {
        ($env:USERDOMAIN).ToLower() + "\" + $env:USERNAME
    }

function List-Process 
    {
        Get-Process -IncludeUserName
    }

function List-MyProcesses
    {
        List-Process | ? {$_.UserName -eq (Get-LoggedOnUser)}
    }

List-MyProcesses

Get-LoggedOnUser just gets the user name. List-Process gets a list of all processes and List-MyProcesses filters the processes using the logged on user details.

We only want to have the function List-MyProcesses available to users who use the module and we’ll configure this when we create our module manifest in step 3.

2 - Copy your .psm1 file

You can store your psm1 file in one of three locations by default in Server 2016:

  • C:\Users\Administrator.contoso\Documents\WindowsPowerShell\Modules
  • C:\Program Files\WindowsPowerShell\Modules
  • C:\Windows\system32\WindowsPowerShell\v1.0\Modules

…..and you can confirm these are the locations by running the command below:

$env:PSModulePath -split ";"

image

We now need to make a folder for our module and give it a name. In this case, we will call our module ProcessTroubleshooting and we’ll save it in a module folder.

Make a new folder: C:\Program Files\WindowsPowerShell\Modules\ProcessTroubleshooting

Save your PowerShell file as C:\Program Files\WindowsPowerShell\Modules\ProcessTroubleshooting\ProcessTroubleshooting.psm1

Note the psm1 extension. This is the convention for creating modules.

3 - Create a module manifest

We now need a module manifest so that our module can be loaded automatically and so that PowerShell knows which functions to provide to the user. To create a module manifest, you need to use the New-ModuleManifest cmdlet. The module manifest file is a .psd1 file.

New-ModuleManifest -Path 'C:\Program Files\WindowsPowerShell\Modules\ProcessTroubleshooting\ProcessTroubleshooting.psd1' `
-RootModule 'C:\Program Files\WindowsPowerShell\Modules\ProcessTroubleshooting\ProcessTroubleshooting.psm1' `
-Author "Mark Gossa" `
-FunctionsToExport List-MyProcesses

We now have a module manifest which includes information about our module and very importantly which functions to export and allow the user to access. The FunctionsToExport parameter lists which functions we want to provide to users, i.e. which functions we want to export. It’s all nice and simple really.

You should now be able to import your module and use all the functions you’ve exported. In Server 2012 and later, you don’t need to even import it - Windows Server just imports it as you call one of the functions. See below for our function in action:

image

So, there we have it - that's how you create PowerShell modules but manual steps I hear you say? Well, you can just write your own function that will package up your module for you and create the manifest and you can even save that function in another module.

Happy scripting!

Monday, 4 September 2017

Learn PowerShell DSC - Part 4

Introduction

Sometimes you can’t find the DSC resource you need built into Windows. For example, let’s say you want to deploy a certificate from your CA - the DSC resource just doesn’t exist but then there’s GitHub. I’ll demo how you can search for and install the xCertificate DSC resource then how to use it in your configuration.

Other parts in this series:

Find DSC Resources

GitHub is a great repository for DSC resources which are not yet included in Windows. You can go to GitHub and download the additional DSC resources you need or you can just search for them using PowerShell:

Find-Module -Tag dsc

image

You can also filter by name e.g.

Find-Module -Tag dsc -Name *cert*

image

Our module is called xCertificate. Now, that was quite easy. Let’s move on.

Install DSC Resource

The DSC resource is actually part of a module which we need to install. To do this, we simply run the command below. It will prompt you to install a NuGet module if you don’t already have it - this is used to get modules from GitHub:

Install-Module xCertificate -Force

image

We can check our module is installed too:

Get-Module xCertificate -ListAvailable

image

You need to install the module on the server you’re writing your configuration on and also on the target server (the one that will receive the configuration). In upcoming articles, I’ll explain how to pull configurations using SMB or HTTPS. Using a pull server, you not only have a central repository for configurations but also have a central repository for the modules which are pulled as well. How good is that!?

To save time and install the module on a remote computer (contchidsc01), we can use remote PowerShell to install the NuGet Package Provider and xCertificate module:

icm contchidsc01 {Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
     Install-Module xCertificate -Force
     }

image

Deploy a certificate with DSC

Okay, so we now have all the pre-requisites we need. We have the DSC resource on our development machine and our target server. Let’s go ahead and write a DSC configuration. If you’re not familiar with this then go back and review part 1. You’ll see I’m using parameters in my configuration - if you’re not familiar with this, go and review part 3.

The plan is to deploy a new certificate to our target server, contchidsc01. The details are below:

  • Subject: contchidsc01.contoso.com
  • Subject alternative names: contchidsc01.contoso.com, contshidsc01
  • Exportable: true
  • Certificate Template: Server

configuration HTTPSPullServerCertificate
     {
         Param (
             [Parameter(Mandatory = $true)]
             [string] $ComputerName
         )

        # Modules must exist on target pull server
         Import-DSCResource -ModuleName PSDesiredStateConfiguration
         Import-DscResource -ModuleName xCertificate

        Node $ComputerName
             {
                 $ComputerFqdn = $ComputerName + ".contoso.com"

                xCertReq Certificate
                     {
                         Subject = $ComputerFqdn
                         SubjectAltName = "dns=$ComputerFqdn&dns=$ComputerName"
                         Exportable = $true
                         CertificateTemplate = "Server"
                     }
             }
     }

image

You’ll see we’re using our new xCertificate module and calling a new resource called xCertReq. The xCertReq DSC resource is what we need to request a certificate from the CA. There are other DSC resources available in the module and you can find all the documentation on GitHub here.

This line below simply gets the FQDN of the computer and saves it as $ComputerFqdn. We use it to add it to the certificate names:

$ComputerFqdn = $ComputerName + ".contoso.com”

Now, let’s create our MOF files:

HTTPSPullServerCertificate -ComputerName contchidsc01 -OutputPath C:\DSC\Certificate

…..and push our configuration:

Start-DscConfiguration -Path C:\DSC\Certificate -Verbose -Wait -Force

then test our configuration was deployed successfully:

Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Certificate

The entire script is below:

configuration HTTPSPullServerCertificate
     {
         Param (
             [Parameter(Mandatory = $true)]
             [string] $ComputerName
         )

        # Modules must exist on target pull server
         Import-DSCResource -ModuleName PSDesiredStateConfiguration
         Import-DscResource -ModuleName xCertificate

        Node $ComputerName
             {
                 $ComputerFqdn = $ComputerName + ".contoso.com"

                xCertReq Certificate
                     {
                         Subject = $ComputerFqdn
                         SubjectAltName = "dns=$ComputerFqdn&dns=$ComputerName"
                         Exportable = $true
                         CertificateTemplate = "Server"
                     }
             }
     }

#Create MOF file
HTTPSPullServerCertificate -ComputerName contchidsc01 -OutputPath C:\DSC\Certificate
#Push the configuration
Start-DscConfiguration -Path C:\DSC\Certificate -Verbose -Wait -Force
#Test the configuration
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Certificate

image

Let’s go ahead and run it:

image

Now, that’s a lot of info because we’re using the -Verbose switch on the Start-DscConfiguration cmdlet. If you look closely at the blue section, you’ll see DSC doing this:

  • Locate the CA
  • Call certutil to ping the CA to check it’s online
  • Check for a certificate which matches the names we’ve requested
  • Create a certificate request
  • Install the certificate

At the end, in white, Test-DscConfiguration runs and states that our target machine is in the desired state so let’s check we have the correct certificate installed on our target machine:

Connect to remote PowerShell on the target computer:

Enter-PSSession contchidsc01

Open up the local computer certificate store:

cd Cert:\LocalMachine\My\

List the certificates:

dir

image

Now we have our certificate installed!

Conclusion

We’re learning quite a lot about DSC. We’re now able to find the DSC resources we need to do almost anything we need to do and we know how to find the documentation, download the modules and use the included DSC resources. So far, we’ve been pushing configurations using Start-DscConfiguration but in the upcoming posts, we’ll look at configuring SMB or HTTPS pull servers.

Sunday, 3 September 2017

Learn PowerShell DSC - Part 3

Introduction

So, we’ve learnt a bit about the basics of DSC with a simple configuration using the File DSC resource in part 1 and then moved on to discuss other DSC resources you can find built into Windows in part 2.

In this post, I’ll show you how you can integrate parameters when creating DSC configurations and also how you can set up dependencies between different DSC resources in your configuration.

Other parts in the series can be found below:

PowerShell DSC parameters

Why are we doing this? Well, it allows you to specify variables which are used to generate the configuration which is then pushed out to the target machines.

In this example which uses the Registry DSC resource to create registry values, I have four parameters that I want to pass to the configuration:

  • ComputerName - this determines which target machines the configuration will be pushed out to
  • Key - this is the registry key
  • ValueName - this is the name of the value
  • ValueData - this is the data that goes in the registry value
  • ValueType - this is the type of value, e.g. string, binary, dword

You specify the parameters as you would normally when writing a script or a function so this section looks like this:

param
     (
         [Parameter(Mandatory=$true)]
         [string]$ComputerName,
         [Parameter(Mandatory=$true)]
         [string]$Key,
         [Parameter(Mandatory=$true)]
         [string]$ValueName,
         [Parameter(Mandatory=$false)]
         [string]$ValueData,
         [Parameter(Mandatory=$false)]
         [string]$ValueType
     )
    

Nothing earth shattering here so stay with me. Let’s now make a configuration using the Registry DSC resource but instead of specifying the key, value and other parameters, we’ll use variables:

configuration RegistryConfig
{
     param
     (
         [Parameter(Mandatory=$true)]
         [string]$ComputerName,
         [Parameter(Mandatory=$true)]
         [string]$Key,
         [Parameter(Mandatory=$true)]
         [string]$ValueName,
         [Parameter(Mandatory=$false)]
         [string]$ValueData,
         [Parameter(Mandatory=$false)]
         [string]$ValueType
     )         

    Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node $ComputerName
     {       
         Registry CreateReg
         {
             Key = $Key
             ValueName = $ValueName
             ValueType = $ValueType
             ValueData = $ValueData
             Ensure = 'Present'
         }
     }
}

We can then generate the MOF file and specify what we need the key, value, value data and type to be and also which target machine to create the configuration for:

RegistryConfig -OutputPath C:\DSC\Registry -ComputerName contchidsc01 `
-Key HKEY_Local_Machine\Software\DSCTest -ValueName DSCTestGood -ValueData True -ValueType string

Now we have our MOF file, we can push it to our target machine contchidsc01:

Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Registry -Wait -Verbose -Force

The full script is below:

configuration RegistryConfig
{
     param
     (
         [Parameter(Mandatory=$true)]
         [string]$ComputerName,
         [Parameter(Mandatory=$true)]
         [string]$Key,
         [Parameter(Mandatory=$true)]
         [string]$ValueName,
         [Parameter(Mandatory=$false)]
         [string]$ValueData,
         [Parameter(Mandatory=$false)]
         [string]$ValueType
     )         

    Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node $ComputerName
     {       
         Registry CreateReg
         {
             Key = $Key
             ValueName = $ValueName
             ValueType = $ValueType
             ValueData = $ValueData
             Ensure = 'Present'
         }
     }
}

RegistryConfig -OutputPath C:\DSC\Registry -ComputerName contchidsc01 `
-Key HKEY_Local_Machine\Software\DSCTest -ValueName DSCTestGood -ValueData True -ValueType string
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Registry -Wait -Verbose -Force

image

When we run this, we can see that the HKEY_Local_Machine\Software\DSCTest key is created then the DSCTestGood value is created and set to True and the type is set to REG_SZ, (string).

image

So, there we have it. PowerShell parameters. Now, let’s say you need to deploy a number of different registry keys and values to a number of machines and you have it all in a CSV. Well, now you can do that quite easily - all using the same configuration.

PowerShell DSC DependsOn

Let’s say we need to copy a zip file to a target machine and then extract that zip file to a folder. Now, clearly we don’t want DSC to try extract a zip file before it’s been copied over because that would be rather dumb. Here’s where we can specify the order that DSC Resources are processed in a configuration - by using the DependsOn parameter which is built into DSC resources.

We’ll use the File DSC resource to copy the zip file over then we’ll use the Archive DSC resource to extract it but we’ll specify that the Archive DSC resource depends on the File DSC resource:

configuration Archive
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         File CopyArchive
         {
             SourcePath = '\\contchisql01\Software\Docker.zip'
             DestinationPath = 'C:\Software\Docker.zip'
             Type = 'File'
             Ensure = 'Present'
         }

        Archive ExtractArchive
         {
             Path = 'C:\Software\Docker.zip'
             Destination = 'C:\Software\Docker'
             DependsOn = "[File]CopyArchive"
         }
     }
}

Archive -OutputPath C:\DSC\Archive
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Archive -Wait -Verbose -Force

image

When we run this configuration and push it out, we see that our zip file is copied then extracted:

image

We can also look at the output from Start-DscConfiguration and we’ll see that the File DSC resource is run before the Archive DSC resource:

image

So, now you can get your configuration to apply DSC resources in order and ensure dependencies are met.

Conclusion

That’s DSC working with parameters and dependencies. I hope you’re starting to get into PowerShell DSC as much as I am! Next up, we’ll look at how to find, install and use DSC modules that are not build into Windows.

Saturday, 2 September 2017

Learn PowerShell DSC - Part 2

Introduction

In part 1, we went through how to make a simple configuration using the File DSC resource and then how to push it out to a single computer. In this part, we’ll go through how to learn about the available DSC resources and demo a few of them.

To go to other parts of this series, see below:

List DSC Resources

Windows has a number of DSC resources built in and you can view the list by using Get-DscResource:

Get-DscResource -Module PSDesiredStateConfiguration

image

Get help for a DSC Resource

Now, let’s say you think you need to use the Service DSC resource but you don’t know the syntax, you can use Get-DscResource:

Get-DscResource Service -Syntax

image

You can also use Get-DscResource to get information about what properties you can set:

Get-DscResource Service | % Properties

image

Service DSC Resource Example

As we’ve just seen the syntax of how to use this DSC resource, let’s start with this.

My target machine has the Windows Audio service stopped and the service is set to manual start:

Get-Service Audiosrv | fl *

image

I want to set this to start automatically and to also start the service so the configuration I’d use is below. (Remember to import the correct module that has your DSC resource - in our case it’s the PSDesiredStateConfiguration module):

configuration Service
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {
         Service WindowsAudio
         {
             Name = "audiosrv"
             StartupType = "Automatic"
             State = "Running"
         }
     }
}

image

Run your configuration - you should see no output from this.

As in part 1, we create a MOF file:

Service -OutputPath C:\DSC\Service

image

…….then push the configuration to our target machine contchidsc01:

Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Service -Wait -Verbose -Force

image

……and then we confirm that our target machine matches the configuration:

Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Service

image

We can also check the service to make sure it’s started and start up is automatic:

Get-Service Audiosrv | fl *

image

Archive DSC Resource Example

This allows you to extract a zip file from a location into a location on the target machine. See the example below:

configuration Archive
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         Archive Unzip
         {
             Destination = 'C:\Software\Docker'
             Path = '\\contchisql01\Software\Docker.zip'
             Checksum = 'SHA-256'
             Validate = $true
             Force = $true
             Ensure = 'Present'
         }
     }
}

Archive -OutputPath C:\DSC\Archive
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Archive -Wait -Verbose -Force
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Archive

image

Environment DSC Resource Example

This DSC resource adds environment variables. In this case, it creates a new variable called NewVar and gives it a value of ‘Value to store’.

configuration Environment
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         Environment NewVar
         {
             Name = 'MYNEWVAR'
             Value = 'Value to store'
             Ensure = 'Present'
         }
     }
}

Environment -OutputPath C:\DSC\Environment
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Environment -Wait -Verbose -Force
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Environment

image

Group DSC Resource Example

This DSC resource creates a local group and can set the members for it too. This example creates a group called TestGroup and makes Administrator a member of it.

configuration GroupConfig
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         Group TestGroup
         {
             Ensure = 'Present'
             GroupName = 'TestGroup'
             Description = 'This is a DSC test group'
             Members = 'administrator'
         }
     }
}

GroupConfig -OutputPath C:\DSC\Group
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Group -Wait -Verbose -Force
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Group

image

Process DSC Resource Example

This DSC resource starts or stops a particular process. You can also specify the arguments for the process too. This example ensures that notepad.exe is running.

configuration ProcessConfig
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         WindowsProcess MSPaint
         {
             Path = 'notepad.exe'
             Arguments = ''
         }
     }
}

ProcessConfig -OutputPath C:\DSC\Process
Start-DscConfiguration -Computername contchidsc01 -Path C:\DSC\Process -Wait -Verbose -Force
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Process

image

Registry DSC Resource Example

You can use this DSC resource to create, delete or set registry keys and values. This example creates a registry key 'HKEY_Local_Machine\Software\DSCTest' with the below value:

  • Name: DSCTestGood
  • Value: True
  • Type: REG_SZ (string)

configuration RegistryConfig
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Node contchidsc01
     {       
         Registry CreateReg
         {
             Key = 'HKEY_Local_Machine\Software\DSCTest'
             ValueName = 'DSCTestGood'
             ValueType = 'string'
             ValueData = 'True'
         }
     }
}

RegistryConfig -OutputPath C:\DSC\Registry
Start-DscConfiguration -Computername contchidsc01
-Path C:\DSC\Registry -Wait -Verbose -Force
Test-DscConfiguration -ComputerName contchidsc01 -Path C:\DSC\Registry

image

Conclusion

As you can see, you can do a lot with PowerShell DSC and these are just a few of the built in DSC resources you can use. There’s a lot more on GitHub and we’ll come to this in part 4. Stay tuned for part 3 where we’ll start using parameters and a setting called DependsOn.

Monday, 28 August 2017

Learn PowerShell DSC - Part 1

Introduction

PowerShell DSC. What’s that? DSC stands for Dynamic State Configuration. It sounds like it could get a little complicated but if you’re just starting out using PowerShell to deploy configurations to machines then you’ll probably be lost in long scripts which check whether your configuration is correct then takes the steps to correct it.

To go to other parts of this series, see below:

You would have to write out the check statements and then write out all the logic to install the feature or copy the file etc.

With PowerShell DSC, you just state what you want your configuration to look like and DSC just “makes it so” and that’s the beauty of DSC.

image

Advantages of PowerShell DSC

As explained above, you need to write less code. That’s great but there’s more.

1) You can read through your code easier

This is called a configuration document. Rather than having a long script with if statements and lots of logic, you now just have a simpler script which states what you want the configuration to look like.

2) Look for configuration drift

DSC allows you to check a server against a configuration document to make sure there hasn’t been any changes.

3) Auto-remediation

DSC periodically checks a server’s configuration against the configuration document and then can be set to automatically restore the configuration to what it should be

4) Remote execution

You can deploy a configuration to remote machines and you can apply the same configuration to many machines

5) Centralised repository

You can configure your servers to pull their configuration from a central repository. This saves you having to copy scripts around and helps you manage versioning.

6) Works with workgroup servers

You’re not tied down to Kerberos authentication! You can deploy configurations to remote machines which are not on the domain.

7) Different teams can manage different configurations

This is called partial configurations. For example it allows your DBAs to manage the SQL related configuration while your systems team can manage the networking and your developers manage IIS.

8) One to many deployment

You can deploy the same configuration to more than one server at a time.

As you can see, DSC is really the best thing since sliced bread! It saves so much time and is a very elegant and efficient way to deploy configurations.

PowerShell DSC Example

Let’s take a look at a quick example. Let’s say we just want to make sure that an install file is copied to C:\Software on our server.

  • Server to configure: contlonsql01
  • Source file: \\contchisql01\Software\Installer.msi
  • Destination file: C:\Software\Installer.msi

Here’s what we’d write out to make this happen. Things to note:

  • configuration. This specifies that this is a PowerShell DSC configuration and the name is Configuration1.
  • Import-DscResource -ModuleName PSDesiredStateConfiguration. Perhaps you guessed it already but this imports the DSC resources from the DSC module. We’ll go into resources and modules another time so don’t worry about this line for now.
  • node is an array of servers we want to configure.
  • File. This specifies that we will be asking DSC to do a file or folder operation and we tell it what we want - i.e. we want to ensure that installer.msi is present which means it needs to be copied from the source location to the destination location.


image

configuration Configuration1 #Configuration1 is the name of the configuration
{
     Import-DscResource -ModuleName PSDesiredStateConfiguration #Imports the DSC module

    node ("contlonsql01") #List the servers you'll be targeting. It'll deploy the settings within node {}
     {
         File InstallerFile #File is a DSC Resource
         {
            Ensure = "Present"
            SourcePath = "\\contchisql01\Software\Installer.msi"
            DestinationPath = "C:\Software\Installer.msi"          
         }
     }
}

There is no output from this. It’s like when you define a function:


image

Push a DSC configuration

Now we need to push the configuration to the machine. To do this we need to create a Management Object File or MOF file and we simply run the configuration and specify an output path for the MOF file:

Configuration1 -OutputPath C:\DS

image

Let’s take a look at the contents of C:\DSC

image

Note that the MOF file is named after the node specified in the configuration. If you have specified more than one node then you’ll get one MOF file per node.
We then deploy the configuration by using Start-DscConfiguration

Start-DscConfiguration -Path C:\DSC

image

Note that you don’t really get much output here. You just see that a job’s been started. if you want to get the output of the job, you can run use Get-Job:

Get-Job 11

image

So, it’s completed and we can confirm our install.msi file has been copied over:

image

We can also use Test-DscConfiguration to check our target machine configuration against the configuration we deployed to it:

Test-DscConfiguration -Path C:\DSC

image

Conclusion

So, that’s just a quick intro into PowerShell DSC. It’s such a great way to configure your servers and definitely the way of the future. In the next post, I’ll talk through DSC resources - these define what types of configuration settings you can make e.g. file, windows features, registry changes etc. Click here for part 2 to continue the DSC journey.