powershellpowershell-v6.0

PowerShell, Cannot read data file


I have a PowerShell script that reads a register.psd1 file with contents as below.

@{
    # Building Zig compiler
    zig = @{
        name = "zig"
        path = ./python/buildzig.py
        language = "Python"
        os = "all" 
    }

    # Building Windows Terminal for Windows 10.
    windowsterminal = @{
        name = "WindowsTerminal"
        path = ./powershell/msterminal.ps1
        language = "Python"
        os = "windows"  
    }
}

I read the file using the following command.

Import-PowerShellDataFile -Path register.psd1

After running the script I get the following error message.

Import-PowerShellDataFile : Cannot generate a PowerShell object for a ScriptBlock evaluating dynamic expressions.

What am I doing wrong and what is the possible solution?


Solution

  • *.psd1 files contain PowerShell hashtable literals and therefore require the same syntax as when defining such literals in code:

    Therefore, if you want to create an entry with key path that contains the string literal ./python/buildzig.py (or ./powershell/msterminal.ps1), you must quote it - either form is OK here:

    However, given that in the context of a *.psd1 file you're virtually limited to literal values, use of '...' (single quotes) makes more sense (see about_Quoting_Rules).


    As for what you tried:

    A hashtable entry such as path = ./python/buildzig.py attempts to create an entry with key path and the value that is the result of executing file ./python/buildzig.py, because - in the absence of quoting - the token is interpreted as a command (see about_Parsing to learn about how PowerShell parses commands and expressions).

    The - unfortunately vague - error message you saw (Cannot generate a PowerShell object for a ScriptBlock evaluating dynamic expressions.), stems from the fact that for security reasons, executing commands isn't permitted in *.psd1 files, which are (mostly[1]) limited to defining literal values.


    [1] You can use the following "variables", which in effect are constants: $true, $false, $null. Additionally, depending on the purpose of the *.psd1 file, a select few additional automatic variables are permitted: $PSCulture and $PSUICulture, except in files to be read by Import-PowerShellDataFile, and, additionally, $PSScriptRoot, $PSEdition, and $EnabledExperimentalFeatures in module manifests - see about_Language_Modes.