Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a PowerShell DSC foreach loop around File resource for copying multiple files defined in the config?

Tags:

powershell

dsc

I'm trying to use PowerShell DSC to do multiple file copies. My configuration has a list of source/target files that need to be copied. However, the File resource needs to have a unique name with it so that you can do dependencies on the resource.

I'm new to PowerShell and I'm trying to figure out the right format for the DSC script (.ps1) to allow a foreach around the File resource. Currently, my code gives me a "Duplicate Resource Identifier" error since it looks like the File resource isn't getting a unique name.

Configuration (psd1 file):

{
AllNodes = @(
@{
  NodeName = '*'
  BuildOutputRoot = 'C:\_BuildDrop\'
  FilesToCopy = @(
    @{
      SourcePath = 'C:\_BuildDrop\SampleConfig.xml'
      TargetPath = 'C:\SampleCode\SampleConfig.xml'
    },
    @{
      SourcePath = 'C:\_BuildDrop\SampleConfig2.xml'
      TargetPath = 'C:\SampleCode\SampleConfig2.xml'
    },

Powershell ps1 file for DSC (snippet):

Configuration MachineToolsFilesAndDirectories
{
# Copy files on all machines
Node $AllNodes.NodeName
{
    foreach ($FileToCopy in $Node.FilesToCopy)
    {
        File $FileToCopy$Number
        {
            Ensure = "Present"
            Type = "File"
            Recurse = $false
            SourcePath = $FileToCopy.SourcePath
            DestinationPath = $FileToCopy.TargetPath
        }
    }
like image 291
Mark Zuber Avatar asked Nov 14 '14 21:11

Mark Zuber


People also ask

How does foreach work in PowerShell?

One of the most common types of loops you'll use in PowerShell is the foreach type of loop. A foreach loop reads a set of objects (iterates) and completes when it's finished with the last one. The collection of objects that are read is typically represented by an array or a hashtable.

What PowerShell command is used to enact as a desired state configuration or DSC?

To easily configure your environment correctly, just run Set-WsManQuickConfig -Force in an elevated PowerShell Terminal. You can apply Configuration documents (MOF files) to a machine with the Start-DscConfiguration cmdlet.


2 Answers

It looks like you never define or change the value of $Number so each File resource ends up with the same name. Try something like this.

Configuration MachineToolsFilesAndDirectories
{
# Copy files on all machines
Node $AllNodes.NodeName
{
    $Number = 0
    foreach ($FileToCopy in $Node.FilesToCopy)
    {
        $Number += 1
        $thisFile = "$FileToCopy$Number"

        File $thisFile
        {
            Ensure = "Present"
            Type = "File"
            Recurse = $false
            SourcePath = $FileToCopy.SourcePath
            DestinationPath = $FileToCopy.TargetPath
        }
    }
}
like image 55
briantist Avatar answered Sep 28 '22 20:09

briantist


I'm not sure if it's what everyone does, but I alway name my resources after the key value in the resource so in the MOF each resource is obviously named after what it does. The only thing to remember is that you have to sanitise the resource name as only alphanumeric and a few other characters are allowed (Specifically not colons in the case for file paths).

For example:

File $FileToCopy.TargetPath.Replace(':','\')
{
    Ensure = "Present"
    Type = "File"
    Recurse = $false
    SourcePath = $FileToCopy.SourcePath
    DestinationPath = $FileToCopy.TargetPath
}

Which would equate to:

File 'C\\SampleCode\SampleConfig.xml'
{
    Ensure = "Present"
    Type = "File"
    Recurse = $false
    SourcePath = 'C:\_BuildDrop\SampleConfig.xml'
    DestinationPath = 'C:\SampleCode\SampleConfig.xml'
}

If it was populated from the following:

@{
  SourcePath = 'C:\_BuildDrop\SampleConfig.xml'
  TargetPath = 'C:\SampleCode\SampleConfig.xml'
}

I realise using the .Replace method is a bit of a sucky way to do it - I should probably build a regex to catch all of the possibilities I occur (Which has been $ for shares and colons in file paths so far).

like image 29
absolutejam Avatar answered Sep 28 '22 20:09

absolutejam