PowerShell DSC is a perfect option to define the state of a machine in a declarative way. Therefore PowerShell comes with a small set of resources that could be used in the definition. For special cases (create web sites, create or configure file shares, etc.) some additional resources a provided in the PowerShell DSC Resource Kit (https://gallery.technet.microsoft.com/scriptcenter/DSC-Resource-Kit-All-c449312d). When you want to use a resource from the resource kit, this resource must be made available on the target node. The next steps will show how to distribute the modules from the resource kit using PowerShell DSC, when using the push mode. The setup in this example is very simple. There is one server acting as a DSC controller and two nodes. From the DSC controller we will push the configuration to the nodes.

First of all we need to download the PowerShell DSC Resource Kit from the Technet Gallery. The downloaded zip-file will be extracted to a folder on the DSC controller.


In our case the files are extracted to the folder “C:\DSC Resources”. The modules we need to distribute will be available in “C:\DSC Resources\All Resources”. All these folders contain the module definitions that need to be copied to the Modules folder in “C:\Program Files\WindowsPowerShell\Modules”, so they could be imported and used.

For this step we use the following script that is saved as “PrepareDSCResourceKitFolder.ps1”:

# prepare DSCResourceKit folder

$sourceDir = 'C:\DSC Resources\All Resources'
$targetDir = 'C:\DSCResourceKit'

$folders = Get-ChildItem -Path $sourceDir | Where-Object {$_.PSIsContainer}

foreach ($folder in $folders)
{
	$f = Get-Item $folder.FullName
    
    Copy-Item $f $targetDir -Recurse
}

Get-ChildItem -Recurse -Path $targetDir | Unblock-File

Important is the last line in the script, because the psm1-files are blocked, when we extract the zip-file with the resource kit.

At this point we have the resource kit files in a structure that could be copied to our nodes. So the final step is simple, because we just need to create a configuration in PowerShell DSC that will copy these files and folders to our nodes.

$DscResourceKit = "\\Dsc-Controller\DscResourceKit"

$configData = 
@{
    AllNodes = 
    @(
        @{
            NodeName = "DSC-Controller"
            Role = "Controller"
        }
        @{
            NodeName = "Node1"
            Role = "WebServer"
        }
        @{
            NodeName = "Node2"
            Role = "WebServer"
        }
    );

    NonNodeData = ""   
}



Configuration EnsureDscResources
{
	Node $AllNodes.Where{$_.Role -ne ""}.NodeName
	{
		File DscResourceKit
		{
			Ensure = 'Present'
            SourcePath = $DscResourceKit
            DestinationPath = "$env:ProgramFiles\WindowsPowerShell\Modules"
            Type = "Directory"
            Recurse = $true
            Force = $true
		}

        Log DscResourceKitFinished
        {
			Message = 'CopyFilesTester finished.'
            DependsOn = '[File]DscResourceKit'
        }
	}
}

EnsureDscResources -ConfigurationData $configData

Start-DscConfiguration -Path .\EnsureDscResources -Wait

That’s it. Just to test, whether we can use the modules or not, we just make a simple configuration that will create a folder on our nodes an share this folder. In this sample the configuration (list of nodes and roles) is separated from the desired state definition.

@{
    AllNodes = 
    @(
        @{
            NodeName = "Node1"
            Role = "WebServer"
        }
        @{
            NodeName = "Node2"
            Role = "WebServer"
        }
    );

    NonNodeData = ""   
}

 


Configuration CreateSampleShare
{
    Import-DscResource -ModuleName cFileShare

    node $AllNodes.Where{$_.Role -ne ""}.NodeName
    {
        File DropFolder
        {
            Ensure = 'Present'
            Type = 'Directory'
            DestinationPath = 'C:\DropFolder'
        }

        cCreateFileShare CreateShare
        {
            ShareName = 'DropFolder'
            Path      = 'C:\DropFolder'
            Ensure    = 'Present'
            DependsOn = '[File]DropFolder'
        }

        cSetSharePermissions SetPermissions
        {
            ShareName         = 'DropFolder'
            DependsOn         = '[cCreateFileShare]CreateShare'
            Ensure	          = 'Present'
            #FullAccessUsers   = @('[user1]')
            #ChangeAccessUsers = @('[user2]')
            ReadAccessUsers   = @('Everyone')
        }
    }
}

CreateSampleShare -ConfigurationData "C:\Scripts\ConfigData.psd1"

Start-DscConfiguration -Path .\CreateSampleShare -Wait

From now on we can use the modules from the PowerShell DSC Resource Kit in all our configuration definitions. When we create new (own) resources, we can distribute them with the same technique to the nodes in our environment.

Advertisements