diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec71f0b..d58f61d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +## 6.2.0.0 + +- WindowsEventLog: + - Migrated the xWinEventLog from [xWinEventLog](/~https://github.com/PowerShell/xWinEventLog) + and renamed to WindowsEventLog. + - Moved strings in localization file. + - LogMode is now set with Limit-EventLog, + - Fixes [Issue #18](/~https://github.com/PowerShell/ComputerManagementDsc/issues/18). + ## 6.1.0.0 - Updated LICENSE file to match the Microsoft Open Source Team standard. diff --git a/Modules/ComputerManagementDsc/ComputerManagementDsc.psd1 b/Modules/ComputerManagementDsc/ComputerManagementDsc.psd1 index 74c2da66..d54fb06d 100644 --- a/Modules/ComputerManagementDsc/ComputerManagementDsc.psd1 +++ b/Modules/ComputerManagementDsc/ComputerManagementDsc.psd1 @@ -1,6 +1,6 @@ @{ # Version number of this module. -moduleVersion = '6.1.0.0' +moduleVersion = '6.2.0.0' # ID used to uniquely identify this module GUID = 'B5004952-489E-43EA-999C-F16A25355B89' @@ -49,9 +49,12 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = '- Updated LICENSE file to match the Microsoft Open Source Team standard. - Fixes [Issue 197](/~https://github.com/PowerShell/ComputerManagementDsc/issues/197). -- Explicitly removed extra hidden files from release package + ReleaseNotes = '- WindowsEventLog: + - Migrated the xWinEventLog from [xWinEventLog](/~https://github.com/PowerShell/xWinEventLog) + and renamed to WindowsEventLog. + - Moved strings in localization file. + - LogMode is now set with Limit-EventLog, + - Fixes [Issue 18](/~https://github.com/PowerShell/ComputerManagementDsc/issues/18). ' @@ -64,3 +67,4 @@ PrivateData = @{ + diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.psm1 b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.psm1 new file mode 100644 index 00000000..831075be --- /dev/null +++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.psm1 @@ -0,0 +1,461 @@ +$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' + +# Import the ComputerManagementDsc Common Modules +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` + -ChildPath 'ComputerManagementDsc.Common.psm1')) + +# Import the ComputerManagementDsc Resource Helper Module +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'ComputerManagementDsc.ResourceHelper' ` + -ChildPath 'ComputerManagementDsc.ResourceHelper.psm1')) + +# Import Localization Strings +$script:localizedData = Get-LocalizedData ` + -ResourceName 'MSFT_WindowsEventLog' ` + -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) + +<# + .SYNOPSIS + Gets the current state of the Windows Event Log. + + .PARAMETER LogName + Specifies the given name of a Windows Event Log. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $LogName, + + [Parameter()] + [System.Boolean] + $IsEnabled + ) + + $log = Get-WindowsEventLog -LogName $LogName + + $LogRetentionDays = (Get-EventLog -List | Where-Object -Property Log -eq $LogName).minimumRetentionDays + + $returnValue = @{ + LogName = [System.String] $LogName + LogFilePath = [system.String] $log.LogFilePath + MaximumSizeInBytes = [System.Int64] $log.MaximumSizeInBytes + IsEnabled = [System.Boolean] $log.IsEnabled + LogMode = [System.String] $log.LogMode + SecurityDescriptor = [System.String] $log.SecurityDescriptor + LogRetentionDays = [System.Int32] $logRetentionDays + } + + Write-Verbose -Message ($localizedData.GettingEventlogName -f $LogName) + return $returnValue +} + +<# + .SYNOPSIS + Sets the current state of the Windows Event Log. + + .PARAMETER LogName + Specifies the given name of a Windows Event Log. + + .PARAMETER MaximumSizeInBytes + Specifies the given maximum size in bytes for a specified Windows Event Log. + + .PARAMETER LogMode + Specifies the given LogMode for a specified Windows Event Log. + + .PARAMETER LogRetentionDays + Specifies the given LogRetentionDays for the Logmode 'AutoBackup'. + + .PARAMETER SecurityDescriptor + Specifies the given SecurityDescriptor for a specified Windows Event Log. + + .PARAMETER IsEnabled + Specifies the given state of a Windows Event Log. + + .PARAMETER LogFilePath + Specifies the given LogFile path of a Windows Event Log. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $LogName, + + [Parameter()] + [System.Boolean] + $IsEnabled, + + [Parameter()] + [System.Int64] + $MaximumSizeInBytes, + + [Parameter()] + [ValidateSet('AutoBackup', 'Circular', 'Retain')] + [System.String] + $LogMode, + + [Parameter()] + [System.Int32] + $LogRetentionDays, + + [Parameter()] + [System.String] + $SecurityDescriptor, + + [Parameter()] + [System.String] + $LogFilePath + ) + + $log = Get-WindowsEventLog -LogName $LogName + + if ($null -eq $log) + { + return + } + + $shouldSaveLogFile = $false + + Write-Verbose -Message ($localizedData.GettingEventlogName -f $LogName) + + if ($IsEnabled -eq $true) + { + if ($PSBoundParameters.ContainsKey('IsEnabled') -and $IsEnabled -ne $log.IsEnabled) + { + Write-Verbose -Message ($localizedData.SettingEventlogIsEnabled -f $LogName, $IsEnabled) + $log.IsEnabled = $IsEnabled + $shouldSaveLogFile = $true + } + + if ($PSBoundParameters.ContainsKey('MaximumSizeInBytes') -and $MaximumSizeInBytes -ne $log.MaximumSizeInBytes) + { + Write-Verbose -Message ($localizedData.SettingEventlogLogSize -f $LogName, $MaximumSizeInBytes) + $log.MaximumSizeInBytes = $MaximumSizeInBytes + $shouldSaveLogFile = $true + } + + if ($PSBoundParameters.ContainsKey('LogMode') -and $LogMode -ne $log.LogMode) + { + Write-Verbose -Message ($localizedData.SettingEventlogLogMode -f $LogName, $LogMode) + $log.LogMode = $LogMode + $shouldSaveLogFile = $true + } + + if ($PSBoundParameters.ContainsKey('SecurityDescriptor') -and $SecurityDescriptor -ne $log.SecurityDescriptor) + { + Write-Verbose -Message ($localizedData.SettingEventlogSecurityDescriptor -f $LogName, $SecurityDescriptor) + $log.SecurityDescriptor = $SecurityDescriptor + $shouldSaveLogFile = $true + } + + if ($PSBoundParameters.ContainsKey('LogFilePath') -and $LogFilePath -ne $log.LogFilePath) + { + Write-Verbose -Message ($localizedData.SettingEventlogLogFilePath -f $LogName, $LogFilePath) + $log.LogFilePath = $LogFilePath + $shouldSaveLogFile = $true + } + } + else + { + Write-Verbose -Message ($localizedData.SettingEventlogIsEnabled -f $LogName, $IsEnabled) + $log.IsEnabled = $IsEnabled + $shouldSaveLogFile = $true + } + + if ($shouldSaveLogFile -eq $true) + { + Save-LogFile -Log $log + } + + if ($PSBoundParameters.ContainsKey('LogRetentionDays')) + { + + if ($LogMode -eq 'AutoBackup' -and (Get-EventLog -List | Where-Object {$_.Log -like $LogName})) + { + $matchingEventLog = Get-EventLog -List | Where-Object -FilterScript { + $_.Log -eq $LogName + } + + $minimumRetentionDaysForLog = $matchingEventLog.minimumRetentionDays + + if ($LogRetentionDays -ne $minimumRetentionDaysForLog) + { + Set-LogRetentionDays -LogName $LogName -LogRetentionDays $LogRetentionDays + } + } + else + { + Write-Verbose -Message ($localizedData.EventlogLogRetentionDaysWrongMode -f $LogName) + } + } +} + +<# + .SYNOPSIS + Tests if the the current state of the Windows Event Log is in the desired state. + + .PARAMETER LogName + Specifies the given name of a Windows Event Log. + + .PARAMETER MaximumSizeInBytes + Specifies the given maximum size in bytes for a specified Windows Event Log. + + .PARAMETER LogMode + Specifies the given LogMode for a specified evWindows Event Logentlog. + + .PARAMETER LogRetentionDays + Specifies the given LogRetentionDays for the Logmode 'AutoBackup'. + + .PARAMETER SecurityDescriptor + Specifies the given SecurityDescriptor for a specified Windows Event Log. + + .PARAMETER IsEnabled + Specifies the given state of a Windows Event Log. + + .PARAMETER LogFilePath + Specifies the given LogFile path of a Windows Event Log. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $LogName, + + [Parameter()] + [System.Boolean] + $IsEnabled, + + [Parameter()] + [ValidateRange(1028kb, 18014398509481983kb)] + [System.Int64] + $MaximumSizeInBytes, + + [Parameter()] + [ValidateSet('AutoBackup', 'Circular', 'Retain')] + [System.String] + $LogMode, + + [Parameter()] + [ValidateRange(1, 365)] + [System.Int32] + $LogRetentionDays, + + [Parameter()] + [System.String] + $SecurityDescriptor, + + [Parameter()] + [System.String] + $LogFilePath + ) + + $log = Get-WindowsEventLog -LogName $LogName + + if ($null -eq $log) + { + return + } + + $desiredState = $true + + if ($IsEnabled -eq $true) + { + + if ($PSBoundParameters.ContainsKey('IsEnabled') -and $log.IsEnabled -ne $IsEnabled) + { + Write-Verbose -Message ($localizedData.TestingEventlogIsEnabled -f $LogName, $IsEnabled) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'IsEnabled') + } + + if ($PSBoundParameters.ContainsKey('MaximumSizeInBytes') -and $log.MaximumSizeInBytes -ne $MaximumSizeInBytes) + { + Write-Verbose -Message ($localizedData.TestingEventlogMaximumSizeInBytes -f $LogName, $MaximumSizeInBytes) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'MaximumSizeInBytes') + } + + if ($PSBoundParameters.ContainsKey('LogMode') -and $log.LogMode -ne $LogMode) + { + Write-Verbose -Message ($localizedData.TestingEventlogLogMode -f $LogName, $LogMode) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'LogMode') + } + + if ($PSBoundParameters.ContainsKey('LogRetentionDays')) + { + + if ($LogMode -eq 'AutoBackup') + { + $minimumRetentionDays = Get-EventLog -List | Where-Object -FilterScript { $_.Log -eq $LogName } + + if ($LogRetentionDays -ne $minimumRetentionDays.minimumRetentionDays) + { + Write-Verbose -Message ($localizedData.TestingEventlogLogRetentionDays -f $LogName, $LogRetentionDays) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'LogRetentionDays') + } + } + else + { + Write-Verbose -Message ($localizedData.EventlogLogRetentionDaysWrongMode -f $LogName) + $desiredState = $false + } + } + + if ($PSBoundParameters.ContainsKey('LogFilePath') -and $log.LogFilePath -ne $LogFilePath) + { + Write-Verbose -Message ($localizedData.TestingWindowsEventlogLogFilePath -f $LogName, $LogFilePath) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'LogFilePath') + } + + if ($PSBoundParameters.ContainsKey('SecurityDescriptor') -and $log.SecurityDescriptor -ne $SecurityDescriptor) + { + Write-Verbose -Message ($localizedData.TestingWindowsEventlogSecurityDescriptor -f $LogName, $SecurityDescriptor) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'SecurityDescriptor') + } + } + else + { + if ($PSBoundParameters.ContainsKey('IsEnabled') -and $log.IsEnabled -ne $IsEnabled) + { + Write-Verbose -Message ($localizedData.TestingEventlogIsEnabled -f $LogName, $IsEnabled) + $desiredState = $false + } + else + { + Write-Verbose -Message ($localizedData.SetResourceIsInDesiredState -f $LogName, 'IsEnabled') + } + } + return $desiredState +} + +<# + .SYNOPSIS + Helper function for the Windows Event Log. + + .PARAMETER Log + Gets the specified Windows Event Log properties. +#> +Function Get-WindowsEventLog +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $LogName + ) + + $log = Get-WinEvent -ListLog $LogName + + if (!$log) + { + Write-Warning ` + -Message ($script:localizedData.WindowsEventLogNotFound -f $LogName) + } + else + { + Write-Verbose -Message ($localizedData.WindowsEventLogFound -f $LogName) + return $log + } +} + +<# + .SYNOPSIS + Save the Windows Event Log properties. + + .PARAMETER Log + Specifies the given object of a Windows Event Log. +#> +Function Save-LogFile +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.Object] + $Log + ) + + try + { + $Log.SaveChanges() + Write-Verbose -Message ($localizedData.SaveWindowsEventlogSuccess) + } + catch + { + Write-Verbose -Message ($localizedData.SaveWindowsEventlogFailure) + } +} + +<# + .SYNOPSIS + Set the Log Retention for a Windows Event Log. + + .PARAMETER LogName + Specifies the given name of a Windows Event Log. + + .PARAMETER Retention + Specifies the given RetentionDays for LogMode Autobackup. +#> +Function Set-LogRetentionDays +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $LogName, + + [Parameter(Mandatory = $true)] + [System.Int32] + $LogRetentionDays + ) + + Write-Verbose -Message ($localizedData.SettingEventlogLogRetentionDays -f $LogName, $LogRetentionDays) + + try + { + Limit-Eventlog -LogName $LogName -OverflowAction 'OverwriteOlder' -RetentionDays $LogRetentionDays + Write-Verbose -Message ($localizedData.SettingWindowsEventlogRetentionDaysSuccess -f $LogName, $LogRetentionDays) + } + catch + { + Write-Verbose -Message ($localizedData.SettingWindowsEventlogRetentionDaysFailed -f $LogName, $LogRetentionDays) + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.schema.mof b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.schema.mof new file mode 100644 index 00000000..60cfc45d --- /dev/null +++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/MSFT_WindowsEventLog.schema.mof @@ -0,0 +1,12 @@ + +[ClassVersion("1.0.0.1"), FriendlyName("WindowsEventLog")] +class MSFT_WindowsEventLog : OMI_BaseResource +{ + [Key, Description("Specifies the given name of a Windows Event Log")] String LogName; + [Write, Description("Specifies the given state of a Windows Event Log")] Boolean IsEnabled; + [Write, Description("Specifies the given maximum size in bytes for a specified Windows Event Log")] Sint64 MaximumSizeInBytes; + [Write, Description("Specifies the given LogMode for a specified Windows Event Log"), ValueMap{"AutoBackup","Circular","Retain"}, Values{"AutoBackup","Circular","Retain"}] String LogMode; + [Write, Description("Specifies the given SecurityDescriptor for a specified Windows Event Log")] String SecurityDescriptor; + [Write, Description("Specifies the given LogFile path of a Windows Event Log")] String LogFilePath; + [Write, Description("Specifies the given LogRetentionDays for the Logmode 'AutoBackup'")] Sint32 LogRetentionDays; +}; diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/README.md b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/README.md new file mode 100644 index 00000000..3960eec5 --- /dev/null +++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/README.md @@ -0,0 +1,5 @@ +# Description + +This resource allows the configuration of the Logsize, Logmode, SecurityDescriptor, +RetentionDays and enabled/disabled the state of a specified Windows Event Log. +It is also possible to set the maximum size of the Windows Event Log. diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/en-US/MSFT_WindowsEventLog.strings.psd1 b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/en-US/MSFT_WindowsEventLog.strings.psd1 new file mode 100644 index 00000000..ef6fc6fb --- /dev/null +++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_WindowsEventLog/en-US/MSFT_WindowsEventLog.strings.psd1 @@ -0,0 +1,24 @@ +# culture ="en-US" +ConvertFrom-StringData -StringData @' + GettingEventlogName = Getting the Windows Event Log '{0}'. + TestingWindowsEventlogSecurityDescriptor = Setting the SecurityDescriptor for Windows Event Log '{0}' to '{1}'. + TestingWindowsEventlogLogFilePath = Setting the LogFilePath for Windows Event Log '{0}' to '{1}'. + TestingEventlogMaximumSizeInBytes = Testing the given LogSize '{1}' for Windows Event Log '{0}'. + TestingEventlogLogMode = Testing the given LogMode '{1}' for Windows Event Log '{0}'. + TestingEventlogLogRetentionDays = Testing the given Retention '{1}' days for Windows Event Log '{0}'. + TestingEventlogIsEnabled = Testing the given State '{1}' for Windows Event Log '{0}'. + SettingEventlogLogMode = Setting the LogMode for Windows Event Log '{0}' to '{1}'. + SettingEventlogLogRetentionDays = Setting the Log Retention for Windows Event Log '{0}' to '{1}' days. + SettingEventlogLogSize = Setting the LogSize for Windows Event Log '{0}' to '{1}'. + SettingEventlogLogFilePath = Setting the LogFilePath for Windows Event Log '{0}' to '{1}'. + SettingEventlogIsEnabled = Setting the IsEnabled configuration for Windows Event Log '{0}' to '{1}'. + SettingEventlogSecurityDescriptor = Setting the SecurityDescriptor configuration for Windows Event Log '{0}' to '{1}'. + SettingWindowsEventlogRetentionDaysSuccess = Updating Logfile Retention for Windows Event Log '{0}' successfully to '{1}' days. + SettingWindowsEventlogRetentionDaysFailed = Updating Logfile Retention for Windows Event Log '{0}' to '{1}' failed. + SetResourceIsInDesiredState = Windows Event Log '{0}' is in desired state for configuration '{1}'. + EventlogLogRetentionDaysWrongMode = Setting the Log Retention for Windows Event Log '{0}' failed. LogMode must be AutoBackup. + SaveWindowsEventlogSuccess = Saving Windows Event Log settings successful. + SaveWindowsEventlogFailure = Saving Windows Event Log settings failed. + WindowsEventLogNotFound = Windows Event Log '{0}' is not found. + WindowsEventLogFound = Windows Event Log '{0}' was found. +'@ diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/1-SetWindowsEventlogSize.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/1-SetWindowsEventlogSize.ps1 new file mode 100644 index 00000000..f3b98959 --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/1-SetWindowsEventlogSize.ps1 @@ -0,0 +1,27 @@ +<# + .EXAMPLE + Example script that sets the application Windows Event Log + to a maximum size 4096MB, the logmode to 'Circular' and ensure that it is enabled. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog ApplicationEventlogSize + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 4096KB + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/2-SetWindowsEventlogLogMode.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/2-SetWindowsEventlogLogMode.ps1 new file mode 100644 index 00000000..807a50cc --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/2-SetWindowsEventlogLogMode.ps1 @@ -0,0 +1,29 @@ +<# + .EXAMPLE + Example script that sets the application Windows Event Log + to mode AutoBackup and logsize to a maximum size of 2048MB + with a logfile retention for 10 days and ensure it is enabled. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog ApplicationEventlogMode + { + LogName = 'Microsoft-Windows-MSPaint/Admin' + IsEnabled = $true + LogMode = 'AutoBackup' + LogRetentionDays = '10' + MaximumSizeInBytes = 2048kb + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/3-EnableWindowsEventLog.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/3-EnableWindowsEventLog.ps1 new file mode 100644 index 00000000..57e5843a --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/3-EnableWindowsEventLog.ps1 @@ -0,0 +1,28 @@ +<# + .EXAMPLE + Example script that sets the Dsc Analytic Windows Event Log + to size maximum size 4096MB, with logmode 'Retain' and ensure it is enabled. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog Enable-DscAnalytic + { + LogName = 'Microsoft-Windows-Dsc/Analytic' + IsEnabled = $True + LogMode = 'Retain' + MaximumSizeInBytes = 4096kb + LogFilePath = "%SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-DSC%4Analytic.evtx" + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/4-SetWindowsEventlogLogMode.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/4-SetWindowsEventlogLogMode.ps1 new file mode 100644 index 00000000..a218b89a --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/4-SetWindowsEventlogLogMode.ps1 @@ -0,0 +1,27 @@ +<# + .EXAMPLE + Example script that sets the application Windows Event Log + logmode to 'Autobackup' with 30 days retention and ensure it is enabled. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog ApplicationEventlogSize + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'AutoBackup' + LogRetentionDays = 30 + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/5-SetWindowsEventlogSecurityDescriptor.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/5-SetWindowsEventlogSecurityDescriptor.ps1 new file mode 100644 index 00000000..a7a95e6a --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/5-SetWindowsEventlogSecurityDescriptor.ps1 @@ -0,0 +1,29 @@ +<# + .EXAMPLE + Example script that sets the application Windows Event Log + logmode to 'Circular' with 30 days retention, + with a Security Desriptor and ensure it is enabled. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog ApplicationEventlogSize + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 2048kb + SecurityDescriptor = 'O:BAG:SYD:(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)' + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/6-DisableWindowsEventlog.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/6-DisableWindowsEventlog.ps1 new file mode 100644 index 00000000..3c91c682 --- /dev/null +++ b/Modules/ComputerManagementDsc/Examples/Resources/WindowsEventlog/6-DisableWindowsEventlog.ps1 @@ -0,0 +1,24 @@ +<# + .EXAMPLE + Example script that disables the given Windows Event Log. +#> +Configuration Example +{ + param + ( + [Parameter()] + [System.String[]] + $NodeName = 'localhost' + ) + + Import-DSCResource -ModuleName ComputerManagementDsc + + Node $NodeName + { + WindowsEventLog Enable-DscAnalytic + { + LogName = 'Microsoft-Windows-Dsc/Analytic' + IsEnabled = $false + } # End of Windows Event Log Resource + } # End of Node +} # End of Configuration diff --git a/README.md b/README.md index d6ac1223..054d8bec 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ The **ComputerManagementDsc** module contains the following resources: - **VirtualMemory**: allows configuration of properties of the paging file on the local computer. - **PowerShellExecutionPolicy**: Specifies the desired PowerShell execution policy. +- **WindowsEventLog**: This resource allows configuration of a specified + Windows Event Log. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) diff --git a/Tests/Integration/MSFT_WindowsEventLog.Integration.Tests.ps1 b/Tests/Integration/MSFT_WindowsEventLog.Integration.Tests.ps1 new file mode 100644 index 00000000..996408e0 --- /dev/null +++ b/Tests/Integration/MSFT_WindowsEventLog.Integration.Tests.ps1 @@ -0,0 +1,293 @@ +$script:DSCModuleName = 'ComputerManagementDsc' +$script:DSCResourceName = 'MSFT_WindowsEventLog' + +#region HEADER +# Integration Test Template Version: 1.1.1 +$script:moduleRoot = Join-Path -Path $(Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path))) -ChildPath 'Modules\ComputerManagementDsc' +if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','/~https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $script:moduleRoot -ChildPath '\DSCResource.Tests\')) +} + +Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceName ` + -TestType Integration + +#endregion + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1" + . $configFile + Describe "$($script:DSCResourceName)_Integration" { + + Context 'Set Windows Event Log to Logmode Retain' { + $CurrentConfig = 'MSFT_WindowsEventLog_RetainSize' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Set Windows Event Log to Logmode AutoBackup with LogRetentionDays of 30 days' { + $CurrentConfig = 'MSFT_WindowsEventLog_AutobackupLogRetention' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Set Windows Event Log to Logmode Circular, MaximumSizeInBytes 20971520, LogFilePath C:\temp\Application.evtx' { + $CurrentConfig = 'MSFT_WindowsEventLog_CircularLogPath' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Set Windows Event Log to Default' { + $CurrentConfig = 'MSFT_WindowsEventLog_Default' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Enable a Logfile other than Application Eventlog' { + $CurrentConfig = 'MSFT_WindowsEventLog_EnableLog' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Disable a Logfile other than Application Windows Event Log' { + $CurrentConfig = 'MSFT_WindowsEventLog_DisableLog' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Set Eventlog to Logmode Circular with a SecurityDescriptor' { + $CurrentConfig = 'MSFT_WindowsEventLog_CircularSecurityDescriptor' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Enable a Logfile other than Application Windows Event Log with Retention' { + $CurrentConfig = 'MSFT_WindowsEventLog_EnableBackupLog' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should not apply the MOF' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a incompliant state' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $false + } + } + + Context 'Disable a Logfile other than Application Eventlog with retention' { + $CurrentConfig = 'MSFT_WindowsEventLog_DisableBackupLog' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + + Context 'Set Windows Event Log back to the default configuration' { + $CurrentConfig = 'MSFT_WindowsEventLog_Default' + $ConfigDir = (Join-Path -Path $TestDrive -ChildPath $CurrentConfig) + $ConfigMof = (Join-Path -Path $ConfigDir -ChildPath 'localhost.mof') + + It 'Should compile a MOF file without error' { + { + . $CurrentConfig -OutputPath $ConfigDir + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should apply the MOF correctly' { + { + Start-DscConfiguration -Path $ConfigDir -Wait -Verbose -Force + } | Should -Not -Throw + } + + It 'Should return a compliant state after being applied' { + (Test-DscConfiguration -ReferenceConfiguration $ConfigMof -Verbose).InDesiredState | Should -Be $true + } + } + } +} +finally +{ + Restore-TestEnvironment -TestEnvironment $TestEnvironment +} diff --git a/Tests/Integration/MSFT_WindowsEventLog.config.ps1 b/Tests/Integration/MSFT_WindowsEventLog.config.ps1 new file mode 100644 index 00000000..82c19df0 --- /dev/null +++ b/Tests/Integration/MSFT_WindowsEventLog.config.ps1 @@ -0,0 +1,135 @@ +# Integration Test Config Template Version: 1.0.0 +configuration MSFT_WindowsEventLog_Default +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 2048kb + LogFilePath = '%SystemRoot%\System32\Winevt\Logs\Application.evtx' + SecurityDescriptor = 'O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)' + } + } +} + +configuration MSFT_WindowsEventLog_RetainSize +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Retain' + MaximumSizeInBytes = 4096kb + } + } +} + +configuration MSFT_WindowsEventLog_AutobackupLogRetention +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'AutoBackup' + LogRetentionDays = '30' + } + } +} + +configuration MSFT_WindowsEventLog_CircularLogPath +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 4096kb + LogFilePath = 'C:\temp\Application.evtx' + } + } +} + +configuration MSFT_WindowsEventLog_EnableLog +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Microsoft-Windows-CAPI2/Operational' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 1028kb + } + } +} + +configuration MSFT_WindowsEventLog_DisableLog +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Microsoft-Windows-CAPI2/Operational' + IsEnabled = $false + } + } +} + +configuration MSFT_WindowsEventLog_CircularSecurityDescriptor +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Application' + IsEnabled = $true + LogMode = 'Circular' + MaximumSizeInBytes = 2048kb + SecurityDescriptor = 'O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x3;;;BO)(A;;0x5;;;SO)(A;;0x1;;;IU)(A;;0x3;;;SU)(A;;0x1;;;S-1-5-3)(A;;0x2;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)' + } + } +} + +configuration MSFT_WindowsEventLog_EnableBackupLog +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Microsoft-Windows-Backup' + IsEnabled = $true + LogMode = 'AutoBackup' + LogRetentionDays = '30' + } + } +} + +configuration MSFT_WindowsEventLog_DisableBackupLog +{ + Import-DscResource -ModuleName ComputerManagementDsc + node 'localhost' + { + WindowsEventLog Integration_Test + { + LogName = 'Microsoft-Windows-Backup' + IsEnabled = $false + } + } +} diff --git a/Tests/Unit/MSFT_WindowsEventLog.Tests.ps1 b/Tests/Unit/MSFT_WindowsEventLog.Tests.ps1 new file mode 100644 index 00000000..0a682847 --- /dev/null +++ b/Tests/Unit/MSFT_WindowsEventLog.Tests.ps1 @@ -0,0 +1,390 @@ +#region HEADER +$script:DSCModuleName = 'ComputerManagementDsc' +$script:DSCResourceName = 'MSFT_WindowsEventLog' + +Import-Module -Name (Join-Path -Path (Join-Path -Path (Split-Path $PSScriptRoot -Parent) -ChildPath 'TestHelpers') -ChildPath 'CommonTestHelper.psm1') -Global + +# Unit Test Template Version: 1.2.0 +$script:moduleRoot = Join-Path -Path $(Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path))) -ChildPath 'Modules\ComputerManagementDsc' +if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone', '/~https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $script:moduleRoot -ChildPath '\DSCResource.Tests\')) +} + +Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force + +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceName ` + -TestType Unit +#endregion HEADER + +# Begin Testing +try +{ + InModuleScope $script:DSCResourceName { + $script:DSCResourceName = 'MSFT_WindowsEventLog' + + Describe "$($script:DSCResourceName)\Get-TargetResource" -Tag 'Get' { + + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 4096kb + IsEnabled = $true + LogMode = 'Circular' + LogFilePath = '%SystemRoot%\System32\Winevt\Logs\Application.evtx' + SecurityDescriptor = 'TestDescriptor' + LogRetentionDays = '0' + LogName = 'Application' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + $results = Get-TargetResource -LogName 'Application' -IsEnabled $true + + It 'Should return an hashtable' { + $results.GetType().Name | Should -Be 'Hashtable' + } + + It 'Should return a Logname Application' { + $results.LogName = 'Application' + } + + It 'Should return a MaximumSizeInBytes of 4096kb' { + $results.MaximumSizeInBytes | Should -Be 4096kb + } + + It 'Should return IsEnabled is true' { + $results.IsEnabled | should -Be $true + } + + It 'Should return a LogMode is Circular' { + $results.LogMode | Should -Be 'Circular' + } + + It 'Should return a LogRetentionDays of 0' { + $results.LogRetentionDays | Should -Be 0 + } + + It 'Should return a LogFilePath of %SystemRoot%\System32\Winevt\Logs\Application.evtx' { + $results.LogFilePath | Should -Be "%SystemRoot%\System32\Winevt\Logs\Application.evtx" + } + + It 'Should return SecurityDescriptor with a value TestDescriptor' { + $results.SecurityDescriptor | Should -Be 'TestDescriptor' + } + } + + Describe "$($script:DSCResourceName)\Test-TargetResource" -Tag 'Test' { + + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 1028kb + IsEnabled = $true + LogMode = 'Circular' + LogFilePath = '%SystemRoot%\System32\Winevt\Logs\Application.evtx' + SecurityDescriptor = 'TestDescriptor' + LogRetentionDays = '7' + LogName = 'Application' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Mock -CommandName Get-EventLog -MockWith { + $params = @{ + MinimumRetentionDays = '7' + Log = 'Application' + } + + return (New-Object -TypeName PSObject -Property $params) + } + + It 'Should not throw when passed an valid Logname' { + { Test-TargetResource -LogName 'Application' -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should throw when passed an invalid LogMode' { + { Test-TargetResource -LogName 'Application' -LogMode 'BadLogmode' -IsEnabled $true -ErrorAction Stop } | Should -Throw + } + + It 'Should not throw when passed an valid LogMode' { + { Test-TargetResource -LogName 'Application' -LogMode 'Circular' -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should return $true if Logmode is in desired state' { + Test-TargetResource -LogName 'Application' -LogMode 'Circular' -IsEnabled $true | Should -Be $true + } + + It 'Should return $false if Logmode is not in desired state' { + Test-TargetResource -LogName 'Application' -LogMode 'AutoBackup' -IsEnabled $false | Should -Be $false + } + + It 'Should throw when passed an invalid MaximumSizeInBytes below 1028kb' { + { Test-TargetResource -LogName 'Application' -LogMode 'Circular' -IsEnabled $true -MaximumSizeInBytes 1027kb -ErrorAction Stop } | Should -Throw + } + + It 'Shoudl throw when passed an invalid MaximumSizeInBytes above 18014398509481983kb' { + { Test-TargetResource -LogName 'Application' -LogMode 'Circular' -IsEnabled $true -MaximumSizeInBytes 18014398509481983kb -ErrorAction Stop } | Should -Throw + } + + It 'Should return $true if MaximumSizeInBytes is in desired state' { + Test-TargetResource -MaximumSizeInBytes 1028kb -LogName 'Application' -IsEnabled $true | Should -Be $true + } + + It 'Should return $false if MaximumSizeInBytes is not in desired state' { + Test-TargetResource -MaximumSizeInBytes 2048kb -LogName 'Application' -IsEnabled $true | Should -Be $false + } + + It 'Should not throw when passed an valid MaximumSizeInBytes' { + { Test-TargetResource -LogName 'Application' -MaximumSizeInBytes 1028kb -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should throw when passed an invalid LogRetentionDays below 1 day' { + { Test-TargetResource -LogName 'Application' -LogMode 'AutoBackup' -IsEnabled $true -LogRetentionDays 0 -ErrorAction Stop } | Should -Throw + } + + It 'Should throw when passed an invalid LogRetentionDays above 365 days' { + { Test-TargetResource -LogName 'Application' -LogMode 'AutoBackup' -IsEnabled $true -LogRetentionDays 366 -ErrorAction Stop } | Should -Throw + } + + It 'Should not throw when passed an valid LogRetentionDays' { + { Test-TargetResource -LogName 'Application' -LogMode 'AutoBackup' -LogRetentionDays 30 -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should return $false if LogRetentionDays is not in desired state' { + Test-TargetResource -LogName 'Application' -IsEnabled $true -LogRetentionDays 13 -LogMode 'AutoBackup' | Should -Be $false + } + + It 'Should return $true if LogRetentionDays is in desired state' { + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 1028kb + IsEnabled = $true + LogMode = 'AutoBackup' + LogFilePath = '%SystemRoot%\System32\Winevt\Logs\Application.evtx' + SecurityDescriptor = 'TestDescriptor' + LogRetentionDays = '7' + LogName = 'Application' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Test-TargetResource -LogName 'Application' -IsEnabled $true -LogRetentionDays 7 -LogMode 'AutoBackup' | Should -Be $true + } + + It 'Should not throw when passed an invalid LogRetentionDays' { + { Test-TargetResource -LogName 'WrongLog' -LogMode 'AutoBackup' -LogRetentionDays 30 -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should not throw when passed an invalid LogMode with LogRetention' { + { Test-TargetResource -LogName 'Application' -LogMode 'Circular' -LogRetentionDays 30 -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should not throw when passed an valid LogFilePath' { + { Test-TargetResource -LogName 'Application' -IsEnabled $true -LogFilePath '%SystemRoot%\System32\Winevt\Logs\Application.evtx' -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should return $true if LogFilePath is in desired state' { + Test-TargetResource -LogName 'Application' -LogFilePath '%SystemRoot%\System32\Winevt\Logs\Application.evtx' -IsEnabled $true | Should -Be $true + } + + It 'Should return $false if LogFilePath is not in desired state' { + Test-TargetResource -LogName 'Application' -LogFilePath '%SystemRoot%\System32\Winevt\OtherLogs\Application.evtx' -IsEnabled $true | Should -Be $false + } + + It 'Should not throw when passed an valid SecurityDescriptor' { + { Test-TargetResource -LogName 'Application' -SecurityDescriptor 'TestDescriptor' -IsEnabled $true -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should return $true if SecurityDescriptor is in desired state' { + Test-TargetResource -LogName 'Application' -SecurityDescriptor 'TestDescriptor' -IsEnabled $true | Should -Be $true + } + + It 'Should return $false if SecurityDescriptor is not in desired state' { + Test-TargetResource -LogName 'Application' -SecurityDescriptor 'TestTestDescriptor' -IsEnabled $true | Should -Be $false + } + + It 'Should return $true if IsEnabled is in desired state' { + Test-TargetResource -LogName 'Application' -IsEnabled $true | Should -Be $true + } + + It 'Should return $false if IsEnabled is not in desired state' { + Test-TargetResource -LogName 'Application' -IsEnabled $false | Should -Be $false + } + + It 'Should return $false if IsEnabled is not in desired state' { + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 1028kb + IsEnabled = $false + LogName = 'Application' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Test-TargetResource -LogName 'Application' -IsEnabled $true | Should -Be $false + } + + It 'Should return $true if IsEnabled is not in desired state' { + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 1028kb + IsEnabled = $true + LogName = 'Application' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Test-TargetResource -LogName 'Application' -IsEnabled $true | Should -Be $true + } + } + + Describe "$($script:DSCResourceName)\Set-TargetResource" -Tag 'Set' { + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 5000kb + IsEnabled = $true + LogMode = 'AutoBackup' + LogFilePath = 'c:\logs\test.evtx' + SecurityDescriptor = 'TestDescriptor' + LogRetentionDays = '7' + LogName = 'TestLog' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Mock -CommandName Get-EventLog -MockWith { + $params = @{ + MinimumRetentionDays = '7' + Log = 'TestLog' + } + + return (New-Object -TypeName PSObject -Property $params) + } + + It 'Should set MaximumSizeInBytes to 1028kb' { + Mock -CommandName Save-LogFile + Set-TargetResource -MaximumSizeInBytes 1028kb -IsEnabled $true -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + It 'MaximumSizeInBytes is in desired state' { + Mock -CommandName Save-LogFile + Set-TargetResource -MaximumSizeInBytes 5000kb -IsEnabled $true -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 0 -Scope It + } + + It 'Should set SecurityDescriptor to OtherTestDescriptor' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $true -LogName 'TestLog' -SecurityDescriptor 'OtherTestDescriptor' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + It 'SecurityDescriptor is in desired state' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $true -LogName 'TestLog' -SecurityDescriptor 'TestDescriptor' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 0 -Scope It + } + + It 'Should set LogFilePath to default path' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $true -LogName 'TestLog' -LogFilePath '%SystemRoot%\System32\Winevt\Logs\Application.evtx' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + It 'LogFilePath is in desired state' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $true -LogName 'TestLog' -LogFilePath 'c:\logs\test.evtx' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 0 -Scope It + } + + It 'Should set LogRetentionDays to 14 days' { + Mock -CommandName Set-LogRetentionDays + Set-TargetResource -LogRetentionDays '14' -IsEnabled $true -LogName 'TestLog' -LogMode 'Autobackup' + Assert-MockCalled -CommandName Set-LogRetentionDays -Exactly -Times 1 -Scope It + } + + It 'Should set LogRetentionDays to 32 days, wrong Logmode' { + Mock -CommandName Set-LogRetentionDays + Set-TargetResource -LogRetentionDays '32' -IsEnabled $true -LogName 'TestLog' -LogMode 'Circular' + Assert-MockCalled -CommandName Set-LogRetentionDays -Exactly -Times 0 -Scope It + } + + It 'Should set LogRetentionDays is in desired state' { + Mock -CommandName Set-LogRetentionDays + Set-TargetResource -LogRetentionDays '7' -IsEnabled $true -LogName 'TestLog' -LogMode 'Autobackup' + Assert-MockCalled -CommandName Set-LogRetentionDays -Exactly -Times 0 -Scope It + } + + It 'Should set IsEnabled to false' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $false -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + It 'IsEnabled is in desired state' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $true -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 0 -Scope It + } + + It 'IsEnabled is not in desired state' { + Mock -CommandName Save-LogFile + Set-TargetResource -IsEnabled $false -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + It 'Should throw if IsEnabled is not in desired state' { + Mock -CommandName Save-LogFile + Mock -CommandName Get-WindowsEventLog -MockWith { throw } + { Set-TargetResource -LogName 'SomeLog' -IsEnabled $false } | Should -Throw + } + + It 'IsEnabled is not in desired state' { + Mock -CommandName Get-WindowsEventLog -MockWith { + $properties = @{ + MaximumSizeInBytes = 5000kb + IsEnabled = $false + LogMode = 'AutoBackup' + LogFilePath = 'c:\logs\test.evtx' + SecurityDescriptor = 'TestDescriptor' + LogRetentionDays = '7' + LogName = 'TestLog' + } + + return (New-Object -TypeName PSObject -Property $properties) + } + + Set-TargetResource -IsEnabled $true -LogName 'TestLog' + Assert-MockCalled -CommandName Save-LogFile -Exactly -Times 1 -Scope It + } + + Describe "$($script:DSCResourceName)\Save-LogFile" -Tag 'Helper' { + Mock -CommandName Limit-Eventlog -MockWith { throw } + + It 'Should throw if we are unable to get a log' { + { Limit-Eventlog -LogName 'Application' -OverflowAction 'OverwriteOlder' -RetentionDays 30 } | Should -Throw + } + } + + Describe "$($script:DSCResourceName)\Set-LogRetentionDays" -Tag 'Helper' { + Mock -CommandName Limit-Eventlog -MockWith { throw } + + It 'Should throw if we are unable to get a log' { + { Limit-Eventlog -LogName 'Application' -OverflowAction 'OverwriteOlder' -RetentionDays 30 } | Should -Throw + } + } + } + } +} +finally +{ + Restore-TestEnvironment -TestEnvironment $TestEnvironment +}