Search code examples
powershelldsc

How should custom DSC resources behave when the resource object cannot be created or removed?


How should custom DSC resources behave when the actual resource object cannot be created or removed by DSC?

In my specific example, I'm writing a resource for managing COM+ Applications, Components and Interfaces. Creating resources for Applications and Components is fine; they can be created and removed from the Catalog programmatically. However Interfaces are created automatically when a Component is created from a DLL.

I need to be able to update the Interface properties (namely the QueuingEnabled property). I therefore intended to describe the configuration of a COM+ Interface as below:

COMplusInterface MyInterface
{
    Ensure = 'Present'
    ApplicationID = 'BB5B8A1F-D70C-44BD-8ADD-E548DF39AACF'
    ComponentDLLPath = 'C:\Program Files\MyApplication\bin\MyComponent.dll'
    InterfaceName = 'MyInterface'
    Description = 'This is my interface'
    QueuingEnabled = $true
}

But if the Application or Component doesn't yet exist, should this resource throw an error? Similarly if the DLL just doesn't have that interface. There's no point in Test-TargetResource returning $false because that will initiate Set-TargetResource that then won't be able to create the Interface.

Following on from that, what should the DSC resource do if Ensure is set to Absent? The Interface can't be removed if it does exist, only by removing the Component can I do that. Should I just return all Interface properties to their default values?


Solution

  • Starting with your question about Ensure, I'll just say that there is no requirement whatsoever to have an Ensure property. Although most resources do, you'll find ones (even from Microsoft) where it doesn't quite make sense. If it doesn't make sense for your resource, don't include it.

    As for what to do if the component doesn't exist, yes, you should throw an error. Use DependsOn in your COMplusInterface resource to ensure it's applied after your COMplusComponent resource.

    Test-TargetResource should return $false whenever the state doesn't match, whether the reason is that the component doesn't exist, or the properties don't match. If the component doesn't exist then Set-TargetResource will run, and it will fail, as it should. You're trying to describe state with your Configuration so you should have set pre-requisite states in the configuration before this part runs (that's where DependsOn comes in).

    I would say that ApplicationID should be your Key property, and the others should be optional; you would only want to specify them if you are forcing their state, so I think you should be able to specify your configuration this way:

    COMplusComponent MyComponent
    {
        <# your component resource #>
    }
    
    COMplusInterface MyInterface
    {
        ApplicationID = 'BB5B8A1F-D70C-44BD-8ADD-E548DF39AACF'
        QueuingEnabled = $true
        DependsOn = '[COMplusComponent]MyComponent'
    }