Create DSC Configuration dynamically Create DSC Configuration dynamically powershell powershell

Create DSC Configuration dynamically


When you write your DSC configuration, it's a script that gets executed at design time to ultimately generate the MOF file. So you can do something like this:

Configuration Folders {    Get-Content 'myfolderlist.txt' | ForEach-Object {        File $($_ -replace '\\','_')        {            DestinationPath = $_            Ensure = "Present"        }    }}

This doesn't address permissions, but it shows how a loop can be used in a DSC configuration. The important thing to remember here is that what this will do, is generate a static configuration (MOF) file with 20k File resources at design time. The loop doesn't get run (nor is it at all present) when DSC is running.

DSC is not the fastest thing.. doing a test/set on 20,000 resources is likely to be really slow and somewhat resource intensive. I kind of feel like this might not be the tool for the job.

Or, you could create a custom DSC resource that does all the logic of testing and setting the folder structure and permissions, so it happens all in one resource.

Essentially then this is a glorified scheduled task, but that might be ok, especially if you want to use DSC in a wider sense. There are lots of articles (and books) out there about how to create a custom resource if you want to take a look at those.


It's not pretty, but I do stuff like below for NTFS permissions, where you may need to expand if you set no subfolder access, etc. I didn't see of an easy way to create the configuration dynamically so I repurpose with different params set. Obviously this is 5 years later so you've probably come up with something. The switches up top are basically to replace variables from your node definition file.

        Function NtfsPermissions        {            Param (                [Parameter(Mandatory=$true)]                [ValidateSet("Present","Absent")]                [string]$Ensure,                [Parameter(Mandatory=$true)]                [string]$Account,                [Parameter(Mandatory=$true)]                [string]$Path,                [string[]]$FileSystemRights,                [string]$Inheritance,                [string]$Depends            )        #Switches are used to dynamically replace accounts and paths that can't be set in nodedefinition file            switch ($Account)            {                "SQLAGENT"                {                    $Account = $Node.gSqlAgt                    break                }                "SQLSVC"                {                    $Account = $Node.gSqlSvc                    break                }                "SQLIS"                {                    $Account = $Node.gSqlIs                    break                }            }            switch ($Path)            {                "AuditPath"                {                    $Path = $Node.AuditPath                    break                }                "LogDir"                {                    $Path = $Node.LogDir                    break                }                "DataDir"                {                    $Path = $Node.DataDir                    break                }                "TempdbDir"                {                    $Path = $Node.TempdbDir                    break                }            }            if ($Ensure -ne "Absent")            {                cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))                {                    Ensure = $Ensure                    Path = $Path                    Principal = $Account                    AccessControlInformation = @(                        cNtfsAccessControlInformation                        {                            AccessControlType = 'Allow'                            FileSystemRights = $FileSystemRights                            Inheritance = $Inheritance                            NoPropagateInherit = $false                        }                        )                    DependsOn = $("[File]$Depends")                    }                                }            else            {                cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))                    {                        Ensure = $Ensure                        Path = $Path                        Principal = $Account                        #Need depends on, just not sure how to structure yet                        DependsOn = "[File]" + $Depends                }                        }    }    $NtfsEntries = $ConfigurationData.NonNodeData.Roles.($Node.Role[0]).NtfsPerms #Need to find a better approach to reference Role        foreach ($ntfs in $NtfsEntries) {            NtfsPermissions -Ensure $ntfs[0] -Account $ntfs[1] -Path $ntfs[2] -FileSystemRights $ntfs[3] -Inheritance $ntfs[4] -Depends $ntfs[5]        }