How to create a log file with multiple sources?

Hi,

I have a requirement to build a custom event log file that has two sources.

In Powershell, I do this:

New-EventLog -LogName GFWM_LOG -Source DBLogger
Limit-EventLog -OverflowAction OverWriteAsNeeded -MaximumSize 20480KB -LogName GFWM_LOG

New-EventLog -LogName GFWM_LOG -Source LogginService

However, in DSC if I try to reference the same log file it complains about duplicates and errors.

I have looked at the examples and the help file, but they don’t address the issue of multiple sources.

As I look further into my project I see some log file with as many as five sources.

Here is how I build the log file in my DSC script:

cCreateLogFile GFWMF-DBLogger-EventLogs {
Name = ‘GFWM_LOG’
Source = ‘DBLogger’
Limit = 20480KB
Id = 411
Ensure = ‘Present’
}

And the module cCreateLogFile looks like this: (I have xx out the company name)
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name
)

$Configuration = @{
Name = $Name
Source = $Source
limit = $limit
Id = $Id
}

Try{
write-verbose “Get: Getting current Logfile $name status”
$Status = [System.Diagnostics.EventLog]::Exists($Name)

If ($Status -eq $true) {
  write-verbose "Test: Logfile $name Present"
  $Configuration.Add('Ensure','Present')
} else {
  write-verbose 'Test: Logfile $name Not present'
  $Configuration.Add('Ensure','Absent')
}  
return $Configuration

}
Catch{
$exception = $_
Write-Verbose (“An Error Occurred: $exception.message”)
}
}

function Set-TargetResource
{
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name,

[System.String]
$Source,

[System.UInt32]
$limit,

[System.UInt32]
$Id,

[ValidateSet('Present','Absent')]
[System.String]
$Ensure

)

try {
if ($Ensure -like ‘Present’)
{
write-verbose “Set: Creating Logfile $Name $Source”
new-eventlog -logname $Name -Source $Source
limit-eventLog -logname $Name -MaximumSize $limit -overflowaction OverwriteOlder
write-eventlog -logname $Name -Source $Source -Message ‘Eventlog created by DSC Configuration=EWM-WebRole,`
Module=xxxxxxxxxx -Resource=XX_CreateLogFile’ -id $Id
}
else
{
write-verbose “Set: Removing Logfile $Name”
Remove-EventLog -LogName $name
}
}
Catch{
$exception = $_
Write-Verbose (“An Error Occurred: $exception.message”)
}
}

function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name,

[System.String]
$Source,

[System.UInt32]
$limit,

[System.UInt32]
$Id,

[ValidateSet('Present','Absent')]
[System.String]
$Ensure

)

try {
write-verbose “Test: Getting current Logfile $name status”
$Status = [System.Diagnostics.EventLog]::Exists($Name)

if ($Ensure -like 'Present') 
{
  
  if (($Status -eq $true)) 
  {
    return $true
  } 
  else 
  {
    return $false
  }
  
} 
else 
{
  
  if ($Status -eq $true) 
  {
    return $false
  } 
  else 
  {
    return $true
  }
  
}

}
Catch {
$exception = $_
Write-Verbose (“An Error Occurred: $exception.message”)
}
}

Export-ModuleMember -Function *-TargetResource

New-EventLog’s -Source parameter accepts an array of strings. You could modify your DSC resource to accept the same thing, eliminating the need for multiple calls.

As you’ve discovered, you can’t have multiple DSC resources with the same key properties in the same configuration / MOF document. I suspect, in this case, your cCreateLogFile resource is using the Name property as its key value. If so, that means you need to be able to pass in all of the parameters necessary to construct that log (including multiple sources) in a single call for that log Name. Even if New-EventLog didn’t allow multiple Source values to be passed in a single call, your resource would still need to accept multiple Sources, and the Set-TargetResource method would be responsible for calling New-EventLog as many times as needed.

Alternatively, if it made sense to do so, you could make the Source property a Key property on the DSC resource. Then each unique Name + Source combination should be allowed in the DSC configuration.

Thanks for the quick answer. So editing the cCreateLogFile resource to accept an array of strings would be the solution I am looking for.
Would that be as simple as editing this section:

$Configuration = @{
Name = $Name
Source = $Source
limit = $limit
Id = $Id
}

to something like:

$Source = @()
$Configuration = @{
Name = $Name
Source = $Source
limit = $limit
Id = $Id
}

Or am I missing the point entirely?

You would need to update the parameter from a [String] to a [String] in both the Test-, Set- and Get-TargetResource functions of your PSM1 file, and you’d also need to update the Schema.mof file (changing “String Source;” to “String Source;”)

The current code in the Test-TargetResource and Get-TargetResource functions is pretty skimpy… it only really tests to see if the event log specified by $Name exists, and doesn’t bother to verify or retrieve settings for all of the other parameters. While that means you don’t need to change anything else in order to support changing Source to an array, it also means that the resource would not detect or correct certain types of configuration drift, such as if a source were deleted (but not the log itself), or someone changed the log file’s maximum size.