Powershell – Why can’t I use a DSC resource in push mode from a module that is installed in the user’s module path

dscpowershell

I have a Powershell DSC custom resource, embedded in a module. The full code is available here if you want to see it, but that may not be necessary; my problem isn't (I think) in the code I wrote, but in how to access it.

In my case, I'm using DSC Push Mode. There's a normal Powershell script I use to install required modules, compile the configuration, and start it. In that script, I add the location of my module to $env:PSModulePath. After doing that, I can then see the module and import it in my interactive shell like this:

PS> Get-Module -ListAvailable | Where-Object -Property Name -eq cWinTrialLab | Import-Module
PS> Get-DscResource -Module cWinTrialLab

ImplementedAs   Name                      ModuleName                     Version    Properties
-------------   ----                      ----------                     -------    ----------
PowerShell      cWtlShortcut              cWinTrialLab                   0.0.1      {Ensure, ShortcutPath, TargetPath, DependsOn...}

So I create a test configuration file:

Configuration TestConfig {

    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName cWinTrialLab

    Node localhost {

        cWtlShortcut "TestShortcut" {
            Ensure = "Present"
            ShortcutPath = "$env:USERPROFILE\Desktop\TestShortcut.lnk"
            TargetPath = "C:\Windows\system32\cmd.exe"
        }

    }
}

And I try to use it:

PS> . .\testDscConfig.ps1
PS> TestConfig
PS> Start-DscConfiguration -Wait -Force TestConfig

Compiling the MOF appears to work, but actually starting the configuration fails with:

The PowerShell DSC resource cWtlShortcut from module <cWinTrialLab,0.0.1> does not exist at the PowerShell module path nor is it registered as a WMI DSC resource.
At $Home\Documents\psyops\submod\wintriallab\azure\test.ps1:13 char:1
+ Start-DscConfiguration -Wait -Force TestConfig
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : DscResourceNotFound
    + PSComputerName        : localhost

What could cause this?

  1. I have made sure that there is only one copy of the module in all folders in my $env:PSModulePath.
  2. Something appears to be working; it can determine the correct version of my module in the error message (and when I change the version on my module's .psd1 file, the version reported in the error message changes as well)
  3. I don't believe it's related to Why can't DSC find a resource that's installed? because I'm using push mode, and there are no module versioning issues.
  4. Could it be related to a nonstandard entry in $env:PSModulePath? I've tried copying the module to $env:ProgramFiles\WindowsPowershell\Modules, but then I get an error I really don't understand:
    Importing module cWinTrialLab failed with error - File C:\Program Files\WindowsPowerShell\Modules\cWinTrialLab\cWtlShortcut\cWtlShortcut.psm1 cannot be loaded because
    running scripts is disabled on this system. For more information, see about_Execution_Policies
    . For the record:

    PS> Get-ExecutionPolicy -List
            Scope ExecutionPolicy
            ----- ---------------
    MachinePolicy       Undefined
       UserPolicy       Undefined
          Process       Undefined
      CurrentUser    Unrestricted
     LocalMachine    Unrestricted
    
  5. Maybe it's something wrong with my directory layout? I haven't actually seen an example of a module containing multiple class-based DSC resources in the wild, so I'm kind of guessing as to the layout.
  6. (If there is an example of this kind of module – a single module, containing multiple class-based DSC resources – a link to it would be really helpful.)

Finally, I'm using Powershell 5.1 on Windows 10 with all updates applied from Windows Update. (Ultimately, I'll be deploying my configuration on a Server 2016 machine.)

What else could I be missing?

Best Answer

Processing the DSC configuration runs under a system account, and therefore isn't searching a particular user's PSModulePath. Put the module in one of the standard locations, typically under $env:ProgramFiles\WindowsPowerShell\Modules.

When you say you modified your $env:PSModulePath, I assume you did that for your current user, rather than modifying a machine wide setting.

If you need the resource to have access to resources available to a particular user, some will allow passing credential objects as parameters to the resource.