Search code examples
powershelldsc

Is there a way to reference a parameter value within the same PSD1 file?


Let's say that I have a PSD1 file, with the following code:

@{
    AllNodes = @(
    @{
        NodeName = $env:COMPUTERNAME
        Tags = @{
            Environment = "dev"
            Datacenter = "east 1"
        }
        Data = @{
            ConfigName = [Tags.Environment]-[Tags.Datacenter.replace(" ","-")]
        }
    })
}

See how I am trying to reference the "Tags" section later on in the same file? Is there some way to do that, or do I simply need to do so within a separate PS1 file?


Solution

  • As iRon points out, what you're trying to do is not supported (and, if it were, would pose implementation challenges - see bottom section).

    In the interest of security (preventing injection of unwanted code and data), PowerShell strictly limits what is permitted inside a *.psd1 file:

    • In a nutshell, a *.psd1 file contains a hashtable literal (@{ .. }) whose values must be literal values - the sole exception being the following automatic variables (which, conceptually, are constants): $true, $false, and $null and, depending on context, $PSCulture and $PSUICulture (with Import-LocalizedData and in module manifests) and, in module manifests only, $PSScriptRoot and $PSEdition and $EnabledExperimentalFeatures (the latter two only in PowerShell (Core) 7+). [DSC]

    • Notably, this prevents use of:

      • Custom and environment variables.

        • Exception: In the context of DSC (your example) environment variables (e.g. $env:COMPUTERNAME) are allowed.
      • Commands and method calls, including via $(...) inside an expandable string ("...")

    Note: *.psd1 files are used in the following contexts:


    As for your idea:

    Hypothetically allowing intra-hashtable cross-references:

    • is certainly desirable in order to avoid repetition and reduce the maintenance burden.

    • is unproblematic from a security standpoint, given that no outside values would be referenced.

    • is challenging from an implementation perspective, however:

      • A contextual automatic variable such as $this (which already exists in classes, for instance) would have to be defined in order to be able to refer to other entries in the same hashtable.

        • In order to reference a specific key, e.g. $this.AllNodes.Tags.Environment, inside an expandable string ("..."), you would then need to use $(...) , which is currently not permitted.
      • Cyclical dependencies between entries would have to be checked for and prevented.

    If you feel strongly enough about having such a feature, I encourage you to submit a feature request on GitHub.