Script resource using xdscdiagnostics

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of Ryan Young Ryan Young 2 years ago.

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

    Hi folks, thanks to Dave Wyatt for getting me this far 🙂 I'm having a go at my first attempt to use the script resource. Below is what I have so far, and there are two problems. 1) The test script always returns false, even if things are good. and 2) powershell gives me an error about xdscdiagnostics not existing.

    Configuration DSCLogging
    {
    Import-dscresource -ModuleName xDscDiagnostics
    	node localhost
    	{
    		$logPreferences = @(
    		@{
    			LogName = 'Analytic'
    			Enabled = $true
    		}
    		
    		@{
    			LogName = 'Operational'
    			Enabled = $true
    		}
    		
    		@{
    			LogName = 'Debug'
    			Enabled = $false
    		}
    		)
    		$logName = $logPreference.LogName
    		$log = Get-WinEvent -ListLog Microsoft-Windows-DSC/$logName
    		
    		Script DSCLogs
    		{
            DependsOn = '[xdscdiagnostics]Update-xDscEventLogStatus'
    			GetScript = {
    				@{
    					Names = $LogPreferences.Logname
    					Statuses = $testscript
    				}
    			}
    			
    			Setscript = {
    				foreach ($logPreference in $logPreferences)
    				{
    					if ($log.IsEnabled -ne $logPreference.Enabled)
    					{
    						if ($logPreference.Enabled)
    						{
    							$status = 'Enabled'
    						}
    						else
    						{
    							$status = 'Disabled'
    						}
    						
    						Update-xDscEventLogStatus -Channel $logName -Status $status
    					}
    				}
    			}
    			TestScript = {
    				foreach ($logPreference in $logPreferences)
    				{
    					if ($log.IsEnabled -ne $logPreference.Enabled)
    					{
    						Return $false
    					}
    					else
    					{
    						return $true
    					}
    				}
    			}
    		}
    	}
    }

    And the error powershell throws me:

    PS C:\CieDSCCustom\Workdir> dsclogging
    Get-WinEvent : There is not an event log on the localhost computer that matches "Microsoft-Windows-DSC/".
    At line:23 char:10
    +         $log = Get-WinEvent -ListLog Microsoft-Windows-DSC/$logName
    +                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (:) [Get-WinEvent], Exception
        + FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
     
    ValidateNodeResources : Resource '[xdscdiagnostics]Update-xDscEventLogStatus' required by '[Script]DSCLogs' does not exist. Please ensure that the required resource exists and the 
    name is properly formed.
    At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:665 char:17
    +                 ValidateNodeResources
    +                 ~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [Write-Error], InvalidOperationException
        + FullyQualifiedErrorId : RequiredResourceNotFound,ValidateNodeResources
    Errors occurred while processing configuration 'DSCLogging'.
    At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:2088 char:5
    +     throw $errorRecord
    +     ~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (DSCLogging:String) [], InvalidOperationException
        + FullyQualifiedErrorId : FailToProcessConfiguration
     
      

    I looked further and indeed, the file/folder structure for the xdscdiagnostics resource is a bit different than the other resources. It contains no "DSCResources" folder, and no schema.mof or schema.psm1 file but instead contains a psd1 file, a psm1 file, and a .ps1xml file. I tried creating the DSC resources folder structure and copying the files as I saw fit, but running get-dscresources doesn't result in it showing up in the list. I can however still import the module and use the cmdlets from there.

    I know I could probably use wevutil rather than xdscdiagnostics to solve the problem, but then where would I learn from that haha? :). The scenario gives me a double whammy of having to deploy a module to a target system and make the script rely on said module.

    Help is highly appreciated!

  • #21011
    Profile photo of Don Jones
    Don Jones
    Keymaster

    So... maybe I'm the one who is confused 🙂 but xDscDiagnostics isn't a DSC Resource. It's a regular PowerShell module that enables certain DSC diagnostic logging operations. You're not meant to use it *within* a configuration.

  • #21012
    Profile photo of Ryan Young
    Ryan Young
    Participant

    I was starting to figure that was the scenario Don! 🙂 I was just about to turn this into a "but how do I make it a resource" question, and well stopped myself cause I'm guilty of not having completely read/grasped that bit from the books and powershell videos I've watched thus far, mostly cause of my headstrong focus on the goal in front of me. I need to do more reading! haha 🙂

    The only question I have left then is about the "testscript" in the above: why does it always return false?

    			Setscript = {
    				foreach ($logPreference in $logPreferences)
    				{
    					if ($log.IsEnabled -ne $logPreference.Enabled)
    					{
    						if ($logPreference.Enabled)
    						{
    							$status = 'Enabled'
    						}
    						else
    						{
    							$status = 'Disabled'
    						}
    						
    						Update-xDscEventLogStatus -Channel $logName -Status $status
    					}
    				}
    			}
    			TestScript = {
    				foreach ($logPreference in $logPreferences)
    				{
    					if ($log.IsEnabled -ne $logPreference.Enabled)
    					{
    						Return $false
    					}
    					else
    					{
    						return $true
    					}
    				}
    			}
    

    Once I have that bit answered, I can turn to use wevutil and come back to trying to 'convert' xdscdiagnostics to a resource later, after I've done some more reading hehe 🙂

  • #21013
    Profile photo of Don Jones
    Don Jones
    Keymaster

    So, couple of maybe-things. I'm not sure it's a great practice to assume $logPreferences is in-scope. Ditto $log. I'm not entirely sure that's the best way to structure all this, actually – I've not done it that way, at least. I mean, the Get/Set/Test scripts are meant to be standalone, but $log is being populated elsewhere entirely. Keep in mind that, when this produces a static MOF file, the line where you populate $log won't exist, and so $log won't mean anything.

    I think you need to refactor so that your Test script is accepting input. When this gets produces as a MOF file, there's no executable code per se. The Test script will get run in a more-or-less new instance of PowerShell, and I don't think those variables will exist.

  • #21015
    Profile photo of Ryan Young
    Ryan Young
    Participant

    Okay so just a recap, here's a modified (to use wevutil instead of update-xdsceventlogstatus) / working version of what Dave Wyatt helped me out with earlier today:

    $logPreferences = @(
    @{
    	LogName = 'Microsoft-Windows-DSC/Analytic'
    	Enabled = $true
    }
    
    @{
    	LogName = 'Microsoft-Windows-DSC/Operational'
    	Enabled = $true
    }
    
    @{
    	LogName = 'Microsoft-Windows-DSC/Debug'
    	Enabled = $false
    }
    )
    
    foreach ($logPreference in $logPreferences)
    {
    	$bash = 'Wevtutil.exe'
    	$args = @('sl')
    	$logName = $logPreference.LogName
    	$log = Get-WinEvent -ListLog $logName
    	
    	if ($log.IsEnabled -ne $logPreference.Enabled)
    	{
    		if ($logPreference.Enabled)
    		{
    			$status = '/e:true'
    		}
    		else
    		{
    			$status = '/e:false'
    		}
    		#Update-xDscEventLogStatus -Channel $logName -Status $status
    		echo y | & $bash $args $logname $status
    	}
    }

    I'm the one who took what he had given me and bastardized it to fit in a script resource haha. My endgame goal is to send this out as a composite resource, and have the target server configure itself for logging. (useful for me for dividing and conquering the various environments between dev to prod). I've also been using this as a "learn dsc and powershell the hard way" project.

    So if I understand you correctly, at least with how I had it put out there before, the LCM can't repopulate these variables when running locally? I would have thought that the LCM starts its own powershell session and can fill in its own variables to do the tasks? ——

    I just read what you said more carefully.. the Test Script in specific! Because TestScript itself becomes its own cmdlet perse? So that gets run on its own and the shell might not have the data populated from the other sections of the existing MOF/Script? I think I can get that.

  • #21021
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Generally speaking, you'd want to avoid the Script resource wherever possible. It's tricky to use properly, and isn't really much easier than writing a real DSC resource. It sounds like what you want is a resource named "cEventLog" (or something similar), which could be placed into a configuration like this:

    configuration someConfig
    {
        node localHost
        {
            cEventLog DSCOpLog
            {
                Name = 'Microsoft-Windows-DSC/Operational'
                Enabled = $true
    
                # Whatever other options might need to be configured for
                # an event log could also be available here
            }
    
            # Add other resource calls here for Analytic / Debug
        }
    }
    

    This is much nicer to read when you're managing the configuration script, as all the code necessary to "make it so" lives in the DSC resource and doesn't clutter things up here.

  • #21025
    Profile photo of Ryan Young
    Ryan Young
    Participant

    I just found out that I'm trying to re-invent the wheel. Found this article explaining how to do it with xWinEvent http://blogs.technet.com/b/heyscriptingguy/archive/2014/10/16/use-powershell-dsc-to-enable-logging.aspx

    Wish I'd of seen this sooner, I'll be back with results 🙂

You must be logged in to reply to this topic.