4

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?

2

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.

  • Passing credentials to a resource has some other challenges, particularly with Partial Configurations where some configurations take credentials and some do not. If you need to go there, drop a comment here and we can start another Question. – Matthew Wetmore Sep 13 '17 at 8:14
  • 1
    I don't need to pass credentials for my current use case, but thanks for the offer. I will say that I had to change my module from the version that is still linked in the question - rather than a parent cWinTrialLab module that contains a cWtlShortcut child module that exports an eponymous DSC resource, I had to add the cWtlShortcut module itself to a directory in $env:PSModulePath. Once I followed your advice to use the standard location, and ditched the parent module, everything worked as expected. Thanks for your help! – Micah R Ledbetter Sep 13 '17 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.