Author Posts

May 11, 2015 at 11:30 am

Does anyone else experience this with class-based resources? They seem to not want to import.

Could not import the PowerShell DSC resource: C:\Program Files\WindowsPowerShell\Modules\cNetConnection
+ CategoryInfo : InvalidArgument: (:) [], CimException
+ FullyQualifiedErrorId : ProviderImportFailure
+ PSComputerName : DESMOND

Here is the Class code in cNetConnection.psm1:

enum Ensure
{
    Absent
    Present
}

[DscResource()]
class cNetConnectionProfile
{    
    [DscProperty(Key)]
    [string]$InterfaceAlias

    [DscProperty(Mandatory)]
    [ValidateSet("Public","Private")]
    [string]$NetworkCategory

    [DscProperty(Mandatory)]
    [Ensure]$Ensure
       
    [cNetConnectionProfile] Get()
    {
        $Configuration = [hashtable]::new()
        $Configuration.Add('InterfaceAlias',$this.InterfaceAlias)

        $netConnectionProfile = Get-NetConnectionProfile -InterfaceAlias $this.InterfaceAlias -ErrorAction Ignore
        
        if ($netConnectionProfile)
        {
            Write-Verbose -Message "The net connection with interface alias $($this.InterfaceAlias) exists."
            $Configuration.Add("NetworkCategory",$netConnectionProfile.NetworkCategory)

            if ($netConnectionProfile.NetworkCategory -eq $this.NetworkCategory)
            {
                Write-Verbose -Message "The net connection with interface alias $($this.InterfaceAlias) is correct."
                $Configuration.Add("Ensure","Present")
            }
            else
            {
                Write-Verbose -Message "The net connection with interface alias $($this.InterfaceAlias) is not correct."
                $Configuration.Add("Ensure","Absent")
            }
        }
        else
        {
            Write-Verbose -Message "The net connection with interface alias $($this.InterfaceAlias) does not exist."
            $Configuration.Add("NetworkCategory",$null)
            $Configuration.Add("Ensure","Absent")
        }
        
        return $Configuration
    }

    [void] Set()
    {
        if ($this.Ensure -eq "Present")
        {
            Write-Verbose "Setting network category on net connection with interface alias $($this.InterfaceAlias) to $($this.NetworkCategory)."

            $netConnectionProfile = Get-NetConnectionProfile -InterfaceAlias $this.InterfaceAlias
            $netConnectionProfile.NetworkCategory = $this.NetworkCategory
            Set-NetConnectionProfile -InputObject $netConnectionProfile
        }
        else
        {
            Write-Verbose "Nothing to set, as we are indifferent to the existence or state of net connection with interface alias $($this.InterfaceAlias)."
        }
    }

    [bool] Test()
    {
        $result = $true
        
        if ($this.Ensure -eq 'Present')
        {
            $netConnectionProfile = Get-NetConnectionProfile -InterfaceAlias $this.InterfaceAlias
            if ($netConnectionProfile -eq $null)
            {
                Write-Verbose -Message "Need to check parameters - the net connection with interface alias $($this.InterfaceAlias) does not exist."
                $result = $false
            }
            elseif ($netConnectionProfile.NetworkCategory -eq $this.NetworkCategory)
            {
                Write-Verbose -Message "Nothing to configure - the net connection with interface alias $($this.InterfaceAlias) exists and is correct."
            }
            else
            {
                Write-Verbose -Message "Need to configure - the net connection with interface alias $($this.InterfaceAlias) is not correct."
                $result = $false
            }
        }
        else
        {
            Write-Verbose -Message "Nothing to configure - the net connection with interface alias $($this.InterfaceAlias) does not exist or its network category doesn't matter."
        }

        return $result
    }
}

And here is the manifest code in cNetConnection.psd1:

@{

# Script module or binary module file associated with this manifest.
RootModule = 'cNetConnection.psm1'

# Version number of this module.
ModuleVersion = '1.0.1'

# ID used to uniquely identify this module
GUID = 'fd3197bb-c534-4c1d-bf66-b1147a66abea'

# Author of this module
Author = 'Ryan Spletzer'

# Company or vendor of this module
CompanyName = 'Ryan Spletzer'

# Copyright statement for this module
Copyright = '(c) 2015 Ryan Spletzer. All rights reserved.'

# Description of the functionality provided by this module
Description = 'NetConnection resource module that allows for configuring network categories of net connection profiles. (See Get-NetConnectionProfile and Set-NetConnectionProfile.)'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'

# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''

# Minimum version of Microsoft .NET Framework required by this module
# DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''

# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = '*'

# DSC resources to export from this module
DscResourcesToExport = 'cNetConnectionProfile'

# List of all modules packaged with this module
# ModuleList = @()

# List of all files packaged with this module
# FileList = @()

# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{

    PSData = @{

        # Tags applied to this module. These help with module discovery in online galleries.
        Tags = @("NetConnectionProfile","DSC","DSC Resource")

        # A URL to the license for this module.
        # LicenseUri = ''

        # A URL to the main website for this project.
        # ProjectUri = ''

        # A URL to an icon representing this module.
        # IconUri = ''

        # ReleaseNotes of this module
        ReleaseNotes = 'Initial Release'

    } # End of PSData hashtable

} # End of PrivateData hashtable

# HelpInfo URI of this module
# HelpInfoURI = ''

# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''

}

They are both nested as follows:

C:\Program Files\WindowsPowerShell\Modules\cNetConnection
– cNetConnection.psd1
– cNetConnection.psm1

Here is the sample configuration I'm using, the CommonComputerSettings and HyperVHostVirtualSwitches are composite resources deployed through modules that work just fine — it's just the cNetConnectionProfile class-based resource that won't import:

Configuration DevMachineHyperVLabConfiguration
{
    [CmdletBinding()]
    param (
        [Parameter()]
        [PSCredential]$DomainCredential
    )
    
    Import-DscResource -ModuleName PSDesiredStateConfiguration,SpletzerDscCompositeResources,cNetConnection
    Node $AllNodes.NodeName
    {
        CommonComputerSettings CommonComputerSettings
        {
        }
    }

    Node $AllNodes.Where{ $_.Role -eq "DevMachineHyperVLabHost" }.NodeName
    {
        HyperVHostVirtualSwitches HyperVHostVirtualSwitches
        {
            ExternalNetAdapterName = $Node.ExternalNetAdapterName
            ExternalVirtualSwitchName = $Node.ExternalVirtualSwitchName
        }

        cNetConnectionProfile InternalVirtualSwitchNetConnectionProfile
        {
            InterfaceAlias = "vEthernet (Internal Virtual Switch)"
            NetworkCategory = "Private"
            Ensure = "Present"
            DependsOn = "[HyperVHostVirtualSwitches]HyperVHostVirtualSwitches"
        }
    }
}

Just to make sure it wasn't something with my code, I took the example class-based resource that they had in Day 2 Module 4 of the MVA class with Jeffrey Snover and Jason Helmick, which was working with the February preview, but when I use that in place of my cNetConnectionProfile resource as a test, I get the same issue.

Has anyone else out there gotten class-defined DSC Resources to work in with the WMF 5 April 2015 Preview? I really want class-based to work because they're a lot simpler and easier to work with, but at this point am tempted to revert back to the traditional Get-/Set-/Test-TargetResource approach for the time being...

May 13, 2015 at 11:54 am

I know a great many people have gotten class-based resources working. Let me ping a couple of folks to see if they have time to take a look.

However, keep in mind that v5 **is** definitely very much in preview still, and not 100% working. If your goal is to get something working outside of a let's-play-with-this lab, you should indeed switch back to the function-style resources and use them in v4. WMF5 definitely has some bugs and quirks in the current public preview.

May 13, 2015 at 11:58 am

What do you get when you call Get-DscResource, to enumerate the "installed" resources on your local system? Do you see it in the results?

Cheers,
Trevor Sullivan
Microsoft MVP: PowerShell
http://trevorsullivan.net

May 14, 2015 at 9:12 am

Don — yep, definitely just a "play-with-this" scenario in a local Hyper-V lab.

Trevor — does come up in a Get-DscResource call. And I can even generate a mof with it; should have been clearer above: I only get that exception when I do the Start-DscConfiguration call.

[img]https://lh4.googleusercontent.com/-FnPTVIGtVF4/VVTWgkjvzXI/AAAAAAAAJes/SGF1VKMK9f0/w728-h535-no/cNetConnectionGetDscResource.PNG[/img]

May 21, 2015 at 1:03 pm

I'm running into this as well with a class based resource I'm trying to write. I will note that I also receive the error going a Get-DscConfiguration on the target machine, for what that's worth.

PS C:\> Get-DscConfiguration
WARNING: [TSBLDINF03CORP]: [] The GET operation will be carried against a pending
configuration since the latest configuration has not converged yet.
Get-DscConfiguration : Could not import the PowerShell DSC resource: C:\Program
Files\WindowsPowerShell\Modules\xDFSReplication
At line:1 char:1
+ Get-DscConfiguration
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_DSCLocalConfigurationManager:root/Microsoft/...gurationManager) [
Get-DscConfiguration], CimException
+ FullyQualifiedErrorId : ProviderImportFailure,Get-DscConfiguration

May 21, 2015 at 4:10 pm

Alright, if Jeremy's getting it, too, I suppose I'll report it as a bug to the PowerShell team on the Connect site. Thanks!

May 26, 2015 at 10:59 pm

Good morning,

had the same issue but was just able to solve it by Setting the DebugMode of LCM back from 'All' to 'None'
Resolved the issue at least for me.

Cheers

November 6, 2015 at 9:28 am

As far as I know that 'ValidateSet' didn't work with DSC Class based resources. Remove 'ValidateSet' (change it by using enum) and give another try.

Side note: Enum didn't work with 'DscProperty(key)'