diff --git a/CHANGELOG.md b/CHANGELOG.md index ce7e9958d2..358e97642a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,7 +97,7 @@ * Major changes to the export process where resource instances will now be assigned a meaningful nam that will follow the ResourceName-PrimaryKey convention. * Added a fix making sure that the progress bar "Scanning dependencies" is no longer displayed after the operation is completed. - * Changed configuration drift reporting to event log to include the instance name as the source. + * Added a new Set-M365DSCLoggingOption function to enable logging information about non-drifted resources in Event Viewer. FIXES [#2981](https://github.com/microsoft/Microsoft365DSC/issues/2981) # 1.23.322.1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdministrativeUnit/MSFT_AADAdministrativeUnit.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdministrativeUnit/MSFT_AADAdministrativeUnit.schema.mof index 039f2ae884..fbc5e20c82 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdministrativeUnit/MSFT_AADAdministrativeUnit.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdministrativeUnit/MSFT_AADAdministrativeUnit.schema.mof @@ -9,8 +9,6 @@ class MSFT_MicrosoftGraphScopedRoleMembership { [Write, Description("Name of the Azure AD Role that is assigned. See https://learn.microsoft.com/en-us/azure/active-directory/roles/admin-units-assign-roles#roles-that-can-be-assigned-with-administrative-unit-scope")] String RoleName; [Write, Description("Member that is assigned the scoped role"), EmbeddedInstance("MSFT_MicrosoftGraphMember")] String RoleMemberInfo; - // [Write, Description("Identity of member. For users, specify a UserPrincipalName. For groups and SPNs, specify the DisplayName")] String Identity; - // [Write, Description("Specify User, Group or ServicePrincipal to interpret the Identity")] String Type; }; [ClassVersion("1.0.0.0"), FriendlyName("AADAdministrativeUnit")] diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADAdministrativeUnit/2-CreateNewAdministrativeUnit.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADAdministrativeUnit/2-CreateNewAdministrativeUnit.ps1 index d09f4fdecc..add5f150fc 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/AADAdministrativeUnit/2-CreateNewAdministrativeUnit.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/AADAdministrativeUnit/2-CreateNewAdministrativeUnit.ps1 @@ -2,18 +2,6 @@ This example is used to test new resources and showcase the usage of new resources being worked on. It is not meant to use as a production baseline. #> - -Configuration Example -{ - param - ( - [Parameter(Mandatory = $true)] - [PSCredential] - $credsGlobalAdmin - ) - - Import-DscResource -ModuleName Microsoft365DSC - Configuration Example { param @@ -39,12 +27,13 @@ Configuration Example } AADAdministrativeUnit 'TestUnit' { + ID = 'Test-Unit' DisplayName = 'Test-Unit' ScopedRoleMembers = @( MSFT_MicrosoftGraphScopedRoleMembership { RoleName = "User Administrator" - RoleMemberInfo = MSFT_MicrosoftGraphIdentity + RoleMemberInfo = MSFT_MicrosoftGraphMember { Identity = "TestGroup" Type = "Group" diff --git a/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 index 8a26608e57..a675ab252a 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 @@ -180,7 +180,7 @@ function Add-M365DSCEvent [Parameter()] [System.String] - [ValidateSet('Drift', 'Error', 'Warning')] + [ValidateSet('Drift', 'Error', 'Warning', 'NonDrift')] $EventType, [Parameter()] @@ -448,7 +448,7 @@ function New-M365DSCNotificationEndPointRegistration [Parameter(Mandatory = $true)] [System.String] - [ValidateSet('Drift', 'Error', 'Warning')] + [ValidateSet('Drift', 'Error', 'Warning', 'NonDrift')] $EventType ) @@ -498,7 +498,7 @@ function Remove-M365DSCNotificationEndPointRegistration [Parameter(Mandatory = $true)] [System.String] - [ValidateSet('Drift', 'Error', 'Warning')] + [ValidateSet('Drift', 'Error', 'Warning', 'NonDrift')] $EventType ) @@ -550,7 +550,7 @@ function Get-M365DSCNotificationEndPointRegistration [Parameter()] [System.String] - [ValidateSet('Drift', 'Error', 'Warning')] + [ValidateSet('Drift', 'Error', 'Warning', 'NonDrift')] $EventType ) @@ -606,7 +606,7 @@ function Send-M365DSCNotificationEndPointMessage [Parameter()] [System.String] - [ValidateSet('Drift', 'Error', 'Warning')] + [ValidateSet('Drift', 'Error', 'Warning', 'NonDrift')] $EventType ) @@ -677,48 +677,63 @@ function Assert-M365DSCIsNonInteractiveShell <# .Description -This function retrieves the name of the last resource instance being processed in the log files. +This function configures the option for logging events into the Event Log. + +.Parameter IncludeNonDrifted +Determines whether or not we should log information about resource's instances that don't have drifts. .Functionality -Private +Public #> -function Get-M365DSCCurrentResourceInstanceNameFromLogs +function Set-M365DSCLoggingOption { [CmdletBinding()] - [OutputType([System.String])] param( [Parameter()] - [System.String] - $ResourceName + [System.Boolean] + $IncludeNonDrifted ) + + if ($null -ne $IncludeNonDrifted) + { + [System.Environment]::SetEnvironmentVariable('M365DSCEventLogIncludeNonDrifted', $IncludeNonDrifted, ` + [System.EnvironmentVariableTarget]::Machine) + } +} + +<# +.Description +This function returns information about the option for logging events into the Event Log. + +.Functionality +Public +#> +function Get-M365DSCLoggingOption +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param() + try { - $allEvents = Get-WinEvent -LogName "Microsoft-windows-dsc/operational" -MaxEvents 10 - foreach ($event in $allEvents) - { - $message = $event.Message - $stringToFind = "Resource execution sequence :: [$($ResourceName.Split('_')[1])]" - $start = $message.IndexOf($stringToFind) - if ($start -ge 0) - { - $end = $message.IndexOf(".", $start) - return $message.Substring($start + 31, $end-($start + 31)) - } + return @{ + IncludeNonDrifted = [Boolean]([System.Environment]::GetEnvironmentVariable('M365DSCEventLogIncludeNonDrifted', ` + [System.EnvironmentVariableTarget]::Machine)) } } catch { - Write-Verbose -Message $_ + throw $_ } - return $null } Export-ModuleMember -Function @( 'Add-M365DSCEvent', 'Export-M365DSCDiagnosticData', - 'Get-M365DSCCurrentResourceInstanceNameFromLogs', + 'Get-M365DSCLoggingOption', 'New-M365DSCLogEntry', 'Get-M365DSCNotificationEndPointRegistration', 'New-M365DSCNotificationEndPointRegistration', - 'Remove-M365DSCNotificationEndPointRegistration' + 'Remove-M365DSCNotificationEndPointRegistration', + 'Set-M365DSCLoggingOption' ) diff --git a/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 index 10d6f2767d..168b0fc893 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 @@ -286,6 +286,7 @@ Public function Get-M365DSCTelemetryOption { [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] param() try diff --git a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 index 525aa027d7..8ee63d8aef 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 @@ -853,17 +853,23 @@ function Test-M365DSCParameterState } } + $includeNonDriftsInformation = $false + try + { + $includeNonDriftsInformation = [System.Environment]::GetEnvironmentVariable('M365DSCEventLogIncludeNonDrifted', ` + [System.EnvironmentVariableTarget]::Machine) + } + catch + { + Write-Verbose -Message $_ + } if ($returnValue -eq $false) { - $currentInstanceName = Get-M365DSCCurrentResourceInstanceNameFromLogs -ResourceName $Source - if ([System.String]::IsNullOrEMpty($currentInstanceName)) - { - $currentInstanceName = $Source - } - $EventMessage = "`r`n" - $EventMessage += " `r`n" + $EventMessage = [System.Text.StringBuilder]::New() + $EventMessage.Append("`r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null - $EventMessage += " `r`n" + $EventMessage.Append(" `r`n") | Out-Null foreach ($key in $DriftedParameters.Keys) { Write-Verbose -Message "Detected Drifted Parameter [$Source]$key" @@ -885,7 +891,7 @@ function Test-M365DSCParameterState $driftedData.Add('Tenant', $TenantName) Add-M365DSCTelemetryEvent -Type 'DriftInfo' -Data $driftedData #endregion - $EventMessage += " " + $DriftedParameters.$key + "`r`n" + $EventMessage.Append(" " + $DriftedParameters.$key + "`r`n") | Out-Null } #region Telemetry @@ -894,9 +900,9 @@ function Test-M365DSCParameterState $data.Add('Tenant', $TenantName) #endregion - $EventMessage += " `r`n" - $EventMessage += " `r`n" - $EventMessage += " `r`n" + $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null foreach ($Key in $DesiredValues.Keys) { $Value = $DesiredValues.$Key @@ -904,13 +910,34 @@ function Test-M365DSCParameterState { $Value = "`$null" } - $EventMessage += " $Value`r`n" + $EventMessage.Append(" $Value`r`n") | Out-Null } - $EventMessage += " `r`n" - $EventMessage += '' + $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append('') | Out-Null - Add-M365DSCEvent -Message $EventMessage -EventType 'Drift' -EntryType 'Warning' ` - -EventID 1 -Source $currentInstanceName + Add-M365DSCEvent -Message $EventMessage.ToString() -EventType 'Drift' -EntryType 'Warning' ` + -EventID 1 -Source $Source + } + elseif ($includeNonDriftsInformation -eq $true) + { + # Include details about non-drifted resources. + $EventMessage = [System.Text.StringBuilder]::New() + $EventMessage.Append("`r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null + foreach ($Key in $DesiredValues.Keys) + { + $Value = $DesiredValues.$Key + if ([System.String]::IsNullOrEmpty($Value)) + { + $Value = "`$null" + } + $EventMessage.Append(" $Value`r`n") | Out-Null + } + $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append('') | Out-Null + Add-M365DSCEvent -Message $EventMessage.ToString() -EventType 'NonDrift' -EntryType 'Information' ` + -EventID 2 -Source $Source } #region Telemetry diff --git a/docs/docs/Images/April2023MR-EventViewer.png b/docs/docs/Images/April2023MR-EventViewer.png index ccd7e53868..5c37cf7907 100644 Binary files a/docs/docs/Images/April2023MR-EventViewer.png and b/docs/docs/Images/April2023MR-EventViewer.png differ diff --git a/docs/docs/blog/april-2023-major-release.md b/docs/docs/blog/april-2023-major-release.md index ab365677a5..614e140089 100644 --- a/docs/docs/blog/april-2023-major-release.md +++ b/docs/docs/blog/april-2023-major-release.md @@ -115,26 +115,11 @@ In order to make it easier for folks to follow the execution process of the Star * Name This means that if a resource instance defines both DisplayName and Id, that the DisplayName value will be used to name the instance. -## Logging Improvements to Include the Instance Name ([#3091](https://github.com/microsoft/Microsoft365DSC/pull/3091)) -Starting with this version of M365DSC, drift events logged in Event Viewer will include the Instance name as their source instead of just the full resource's name. -![image](https://raw.githubusercontent.com/microsoft/Microsoft365DSC/Dev/docs/docs/Images/April2023MR-EventViewer.png) -In addition to this, the M365DSCEvent XML content will now include an additional property for the ConfigurationDrift element that will be named **InstanceName** and will contain the resource's instance name. E.g., +## Logging Improvements to Include Non-Drifted Resource Instances ([#3091](https://github.com/microsoft/Microsoft365DSC/pull/3091)) +Starting with this version of M365DSC, users can decide to also include informaton about resources that don't have any detected drifts in them by setting the logging settings with the new Set-M365DSCLoggingOption. E.g., ``` - - - - 192.226.137.107/12192.226.137.106/12 - - - - #microsoft.graph.ipNamedLocation - Nik's Laptop - 192.226.137.106/12 - True - Present - System.Management.Automation.PSCredential - True - - +Set-M365DSCLoggingOption -IncludeNonDrifted $True ``` +These events will be reported as Information entries having an Event ID of 2. +![image](https://raw.githubusercontent.com/microsoft/Microsoft365DSC/Dev/docs/docs/Images/April2023MR-EventViewer.png)