Enabling / Disabling logging for DSC

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Ryan Young Ryan Young 1 year, 12 months ago.

  • Author
    Posts
  • #20999
    Profile photo of Ryan Young
    Ryan Young
    Participant

    Hello folks, I'm still a bit of a powershell newbie and hoping I can get your help in figuring out where I'm going wrong. Here's my script so far:

    Import-Module xDscDiagnostics
    function Get-DSCLogStatus
    {
    	[OutputType([string])]
    	param (
    		[Parameter(Mandatory)]
    		[string] $IsEnabled
    	)
    	
    	switch -Wildcard ($IsEnabled)
    	{
    		'*True*' { return 'True' }
    		default { return 'False' }
    	}
    }
    function get-dsclogname
    {
    	[OutputType([string])]
    	param (
    		[Parameter(Mandatory)]
    		[string] $log
    	)
    	
    	switch -wildcard ($log)
    	{
    		'*Analytic' { return 'Analytic' }
    		'*Debug' { return 'Debug' }
    		Default { return 'Operational' }
    	}
    }
    
    
    $DSCLog =  Get-WinEvent -Force -ListLog * | Where LogName -Match "Microsoft-Windows-DSC" | Select-Object LogName, isEnabled
    
    $DSCLogStatus = @{
    	AllLogs = @(
    	foreach ($Log in $DSCLog)
    	{
    		@{
    			LogNames = Get-DSCLogname -Log $Log.logname | Out-String
    			LogStatus = Get-DSCLogStatus -isenabled $Log.isEnabled
    		}
    	}
    	)
    }
    
    function EnableDscLogging
    {
    	foreach ($Logs in $dsclogstatus.alllogs)
    	{
    		If ($logs.logstatus -eq $false)
    		{
    			#Update-xDscEventLogStatus -Channel $logs.lognames -status Enabled
    			Invoke-expression "Update-xDscEventLogStatus -Channel Debug -status Enabled"
    		}
    		ElseIf ($logs.logstatus -eq $true)
    		{
    			(Write-Warning -Message "Eventlog already enabled")
    		}
    	}
    }

    Objective: Run a 'foreach disabled log' and fill in the "channel" property with the value containing the truncated name (Analytic, Debug, or Operational) of said log, allowing me to use the update-xdsceventlogstatus command to activate the logs. I will later convert this into a composite resource that I can use in DSC to pick/choose which types of targets should have analytic/debug logs enabled.

    Problem: see here:

    		If ($logs.logstatus -eq $false)
    		{
    			#Update-xDscEventLogStatus -Channel $logs.lognames -status Enabled
    			Invoke-expression "Update-xDscEventLogStatus -Channel Debug -status Enabled"
    		} 

    The code I need to fill in the channel (that I have commented) doesn't work, but I tried using the 2nd line as a 'test' to ensure the other sections of my code are okay and it does indeed activate the debug channel, which I'm interpreting as it coming back and acknowledging that the status of at least one of the logs is "disabled".

    I'm kinda scratching my head at this point. I still learning how to fully utilize hash tables to their fullest. Help is much appreciated!

  • #21005
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You seem to be doing something similar to setting up a ConfigurationData hashtable here, but that's a really convoluted way of doing things for anything that's not DSC. You already know that the three logs you need to fetch are 'Microsoft-Windows-DSC/Analytic', '/Debug', and '/Operational'. There's no problem with hard-coding those three values; the code right now is a bit hard to follow, with no real benefit. It looks like all you're really doing here could be simplified down to this:

    $logNames = 'Analytic', 'Operational', 'Debug'
    
    foreach ($logName in $logNames)
    {
        $log = Get-WinEvent -ListLog Microsoft-Windows-DSC/$logName
    
        if (-not $log.IsEnabled)
        {
            Update-xDscEventLogStatus -Channel $logName -Status Enabled
        }
    }
    

    If you wanted to further parameterize this and be able to enable some logs and disable others, it might look something like this:

    $logPreferences = @(
        @{
            LogName = 'Analytic'
            Enabled = $true
        }
    
        @{
            LogName = 'Operational'
            Enabled = $true
        }
    
        @{
            LogName = 'Debug'
            Enabled = $false
        }
    )
    
    foreach ($logPreference in $logPreferences)
    {
        $logName = $logPreference.LogName
        $log = Get-WinEvent -ListLog Microsoft-Windows-DSC/$logName
    
        if ($log.IsEnabled -ne $logPreference.Enabled)
        {
            if ($logPreference.Enabled)
            {
                $status = 'Enabled'
            }
            else
            {
                $status = 'Disabled'
            }
    
            Update-xDscEventLogStatus -Channel $logName -Status $status
        }
    }
    

    With an array of hashtables here, we're starting to look like something closer to a DSC configuration data structure, but there's no need to nest that array into an outer hashtable with an AllLogs key. DSC's structure with the AllNodes key serves a specific purpose. Here, it's not needed.

  • #21006
    Profile photo of Ryan Young
    Ryan Young
    Participant

    Aye, I'm kind of doing the reverse order here... Using what I've seen in DSC to learn powershell haha! I've seen a lot of use of ConfigurationData and my script kiddie background has me reusing what I have seen previously. My imagination hasn't yet stretched out this far as to "how to do things efficiently". Gonna move forward with what you've put here for sure, and try my hand at making it work within a composite resource "script" block. I'll report back soon on it 🙂

  • #21007
    Profile photo of Ryan Young
    Ryan Young
    Participant

    Your script, as written works wonderfully. I'm going to open a new thread in the dsc forum because this is moving away from basic powershell now.

You must be logged in to reply to this topic.