Custom Service Resource

This topic contains 1 reply, has 2 voices, and was last updated by Profile photo of Don Jones Don Jones 4 months ago.

  • Author
    Posts
  • #62023
    Profile photo of Paul Frankovich
    Paul Frankovich
    Participant

    My environment has a security requirement that requires we configure particular services as Disabled or Automatic. Using a database of this information we are testing configuring these with DSC. In order to automate this we have a DSC Resource class for services that will be used to ignore services that are not installed on a particular node. What we have written works just fine with configuring the services but doesn't always succeed when using Test-DSCConfiguration or Get-DSCConfiguration. From one check to the next it will work okay, or fail with the error:

    Get-DscConfiguration : The PowerShell DSC resource '[customService]AppMgmt' with SourceInfo 'C:\DSC\config.ps1::141::13::customService' threw one or more non-terminating errors while running the Get functionality. 
    These errors are logged to the ETW channel called Microsoft-Windows-DSC/Operational. Refer to this channel for more details.
    At line:1 char:1
    + Get-DscConfiguration
    + ~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (MSFT_DSCLocalConfigurationManager:root/Microsoft/...gurationManager) [Get-DscConfiguration], CimException
        + FullyQualifiedErrorId : NonTerminatingErrorFromProvider,Get-DscConfiguration

    Here is the resource code. Please let me know if any additional information will help as the event logs mentioned just repeat the error given above. Also, any assistance on how better to approach this would be welcome.

    Enum StartupType
    {
        Automatic
        Disabled
        Manual
    }
    
    Enum Status
    {
        Running
        Stopped
        Ignore
    }
    
    
    [DscResource()]
    Class customService
    {
        
        [DscProperty(Key)]
        [String]$Service
    
        
        [DscProperty(Mandatory)]
        [StartupType]$StartupType
    
        
        [DscProperty(Mandatory)]
        [Status]$Status
    
        
        [void] Set()
        {
            $ServiceExist = $this.ServiceExist($this.Service)
    
            If ($ServiceExist)
            {
                $this.SetService()
            }
            Else
            {
                Write-Verbose "$($this.Service) not available. Set skipped."
            }
        }
    
        
        [bool] Test()
        {
            $ServiceExist = $this.ServiceExist($this.Service)
    
            If ($ServiceExist)
            {
                Write-Verbose "Found $($this.Service)."
                $Configured = $this.TestService($this.Service,$this.StartupType.ToString(),$this.Status)
                If ($Configured)
                {
                    Return $true
                }
                Else
                {
                    Return $False
                }
            }
            Else
            {
                Write-Verbose "Did not find $($this.Service). Skipped"
                Return $true
            }
             
        }
    
        
        [customService] Get()
        {
            Return $this
        }
    
        
        [bool] ServiceExist([string]$Service)
        {
            $Present = Get-Service -Name $Service -ErrorAction SilentlyContinue
            
            If ($Present)
            {
                Return $true
            }
            Else
            {
                Return $false
            }
        }
    
        
        [bool] TestService([string]$Service,[string]$StartType,[string]$State)
        {
            $ServiceInfo = Get-WmiObject -Class Win32_Service -Filter "Name='$Service'" -ErrorAction SilentlyContinue
    
            If ($State -eq 'Ignore')
            {
                $State = $ServiceInfo.State
                Write-Verbose "Service is listed as Ignore - Testing for $($ServiceInfo.State)"
            }
    
            If ($ServiceInfo.StartMode -eq $StartType -and $ServiceInfo.State -eq $State)
            {
                Return $true
            }
            Else
            {
                Return $false
            }
        }
    
        
        [void] SetService()
        {
            If (-not $this.ServiceExist($this.Service))
            {
                Write-Verbosek "$($this.Service) is not found. Set skipped"
            }
            Else
            {
                Write-Verbose "Setting $($this.Service) to $($this.StartupType) - $($this.Status)"
    
                If ($this.StartupType -eq [StartupType]::Disabled)
                {
                    Write-Verbose "Stopping $($this.Service)."
                    Stop-Service -Name $this.Service -WarningAction SilentlyContinue
                }
    
                If ($this.Status -eq 'Ignore')
                {
                    Set-Service -Name $this.Service -StartupType $this.StartupType.ToString()
                }
                Else
                {
                    Set-Service -Name $this.Service -StartupType $this.StartupType.ToString() -Status $this.Status
                }
            }
        }
    
    }
  • #62724
    Profile photo of Don Jones
    Don Jones
    Keymaster

    You're going to have to add some logging and debug code to your class, so you can log what it's about to try and then catch and log any errors. Just staring at the code, I can't really point to a definite problem.

You must be logged in to reply to this topic.