Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using variables inside a DSC composite resource

I am fairly new to PowerShell DSC to the answer to this may be blindingly obvious but I cannot find a similar problem described anywhere.

I have a PowerShell DSC composite resource which downloads some MSIs and runs them. The directory that the file is downloaded to is referenced in several places so I am trying to store it in a variable. However, when I come to apply the configuration which uses this resource using Start-DscConfiguration the values always appear to be null.

Here is an example of the resource:

Configuration xExample {

  Import-Module -ModuleName 'PSDesiredStateConfiguration'

  $path = 'C:\Temp\Installer.msi'

  Script Download {
    SetScript = { 
      Invoke-WebRequest -Uri "..." -OutFile $path 
    }
    GetScript = {
      @{ 
        Result = $(Test-Path $path)
      }
    }
    TestScript = {
      Write-Verbose "Testing $($path)"
      Test-Path $path
    }
  }
}

When this resource is being executed the the verbose output shows "Testing " and the call to Test-Path fails due to the Path parameter being null.

I have tried declaring the $path variable outside of the configuration and using $global to no avail.

What am I missing?

like image 238
Mark Watts Avatar asked Apr 03 '17 08:04

Mark Watts


1 Answers

DSC stores scripts as strings in the compiled mof-files. Standard variables are not expanded as it wouldn't know which to expand and which to keep as part of the script.

However, you can use the using-scope to access variables outside the script. During mof-compilation, the code that defines the variable is added to the beginning of each scriptblock for Test-/Set-/GetScript.

If you need to use variables from your configuration script in the GetScript, TestScript, or SetScript script blocks, use the $using: Scope

Source: DSC Script Resources @ MSDN

Example:

Configuration xExample {

  Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

  #Can also be set outside of Configuration-scriptblock
  $path = 'C:\Temp\Installer2.msi'

  Script Download {
    SetScript = { 
      Invoke-WebRequest -Uri "..." -OutFile $using:path
    }

    GetScript = {
      @{ 
        Result = $(Test-Path "$using:path")
      }
    }

    TestScript = {
      Write-Verbose "Testing $using:path"
      Test-Path "$using:path"
    }
  }
}

localhost.mof (scriptresource-part):

instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
{
ResourceID = "[Script]Download";
 GetScript = "$path ='C:\\Temp\\Installer2.msi'\n\n      @{ \n        Result = $(Test-Path \"$path\")\n      }\n    ";
 TestScript = "$path ='C:\\Temp\\Installer2.msi'\n\n      Write-Verbose \"Testing $path\"\n      Test-Path \"$path\"\n    ";
 SourceInfo = "::7::3::Script";
 SetScript = "$path ='C:\\Temp\\Installer2.msi'\n \n      Invoke-WebRequest -Uri \"...\" -OutFile $path\n    ";
 ModuleName = "PSDesiredStateConfiguration";

ModuleVersion = "1.0";

 ConfigurationName = "xExample";

};

Source: MSDN

like image 194
Frode F. Avatar answered Sep 18 '22 23:09

Frode F.