From 12ce7ec04286befb5de574d4b7e960480909a763 Mon Sep 17 00:00:00 2001 From: nikcharlebois Date: Fri, 14 Jan 2022 07:32:13 -0500 Subject: [PATCH 1/3] Fixes #1538 --- CHANGELOG.md | 6 ++++++ .../MSFT_EXORoleAssignmentPolicy.psm1 | 17 ++++++++++++++--- .../Modules/M365DSCPermissions.psm1 | 2 +- .../Microsoft365DSC/Modules/M365DSCReverse.psm1 | 10 +++++----- .../Microsoft365DSC/Modules/M365DSCUtil.psm1 | 12 +++++++++++- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78c286b2a4..625babe659 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change log for Microsoft365DSC +# 1.22.119.1 + +* EXORoleAssignmentPolicy + * Fixed logic to update roles assigned to an existing policy; + FIXES #1538 + # 1.22.112.1 * TeamsMeetingPolicy diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 index 49a80dce20..dd94fb3e8c 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 @@ -251,9 +251,20 @@ function Set-TargetResource elseif ($Ensure -eq "Present" -and $currentRoleAssignmentPolicyConfig.Ensure -eq "Present" -and $null -ne (Compare-Object -ReferenceObject $($currentRoleAssignmentPolicyConfig.Roles) -DifferenceObject $Roles)) { Write-Verbose -Message "Role Assignment Policy '$($Name)' already exists, but roles attribute needs updating." - Write-Verbose -Message "Remove Role AssignmentPolicy before recreating because Roles attribute cannot be change with Set cmdlet" - Remove-RoleAssignmentPolicy -Identity $Name -Confirm:$false - New-RoleAssignmentPolicy @NewRoleAssignmentPolicyParams + $differences = Compare-Object -ReferenceObject $($currentRoleAssignmentPolicyConfig.Roles) -DifferenceObject $Roles + foreach ($difference in $differences) + { + if ($difference.SideIndicator -eq '=>') + { + Write-Verbose -Message "Adding Role {$($difference.InputObject)} to Role Assignment Policy {$Name}" + New-ManagementRoleAssignment -Role $($difference.InputObject) -Policy $Name + } + elseif ($difference.SideIndicator -eq '<=') + { + Write-Verbose -Message "Removing Role {$($difference.InputObject)} to Role Assignment Policy {$Name}" + Remove-ManagementRoleAssignment -Identity "$($difference.InputObject)-$Name" + } + } } } diff --git a/Modules/Microsoft365DSC/Modules/M365DSCPermissions.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCPermissions.psm1 index 3c86a48316..34c476980b 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCPermissions.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCPermissions.psm1 @@ -110,7 +110,7 @@ function Update-M365DSCAllowedGraphScopes [System.String] $Type, - [Parameter(Mandatory = $true)] + [Parameter()] [ValidateSet('Global', 'China', 'USGov', 'USGovDoD', 'Germany')] [System.String] $Environment = 'Global' diff --git a/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 index c7598ea7f9..9b0a6fc6ce 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 @@ -334,7 +334,7 @@ function Start-M365DSCConfigurationExtract } [array]$ModuleVersion = Get-Module Microsoft365DSC $ModuleVersion = $ModuleVersion[0] - $DSCContent += " Import-DscResource -ModuleName 'Microsoft365DSC' -ModuleVersion '$version'`r`n`r`n" + $DSCContent += " Import-DscResource -ModuleName 'Microsoft365DSC'`r`n`r`n" $DSCContent += " Node localhost`r`n" $DSCContent += " {`r`n" @@ -636,10 +636,6 @@ function Start-M365DSCConfigurationExtract -Cert "cert:\LocalMachine\my\$($LCMConfig.CertificateID)" ` -Type CERT ` -NoClobber | Out-Null - Add-ConfigurationDataEntry -Node "localhost" ` - -Key "CertificateFile" ` - -Value "M365DSC.cer" ` - -Description "Path of the certificate used to encrypt credentials in the file." } catch { @@ -648,6 +644,10 @@ function Start-M365DSCConfigurationExtract -EventID 1 -Source $($MyInvocation.MyCommand.Source) } } + Add-ConfigurationDataEntry -Node "localhost" ` + -Key "CertificateFile" ` + -Value "M365DSC.cer" ` + -Description "Path of the certificate used to encrypt credentials in the file." $outputConfigurationData = $OutputDSCPath + "ConfigurationData.psd1" New-ConfigurationDataDocument -Path $outputConfigurationData } diff --git a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 index 4ff410ed1e..5467b8880e 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 @@ -941,6 +941,16 @@ function Export-M365DSCConfiguration #region Telemetry $data = [System.Collections.Generic.Dictionary[[String], [String]]]::new() $data.Add("Event", "Extraction") + + if (-not [System.String]::IsNullOrEmpty($TenantId)) + { + $data.Add("Tenant", $TenantId) + } + else + { + $tenant = $Credential.UserName.Split('@')[1] + $data.Add("Tenant", $tenant) + } $data.Add("Path", [System.String]::IsNullOrEmpty($Path)) $data.Add("FileName", $null -ne [System.String]::IsNullOrEmpty($FileName)) $data.Add("Components", $null -ne $Components) @@ -966,7 +976,7 @@ function Export-M365DSCConfiguration } # Clear the Connection Cache from MSCloudLoginAssistant - $Global:MsCloudLoginConnectionProfile = $null + #$Global:MsCloudLoginConnectionProfile = $null # Make sure we are not connected to Microsoft Graph on another tenant try From 87bf79fe230419fdee72de410916612328f1aecc Mon Sep 17 00:00:00 2001 From: nikcharlebois Date: Fri, 14 Jan 2022 13:22:19 -0500 Subject: [PATCH 2/3] Fixes for Version Parsing --- CHANGELOG.md | 4 ++++ .../Modules/M365DSCReport.psm1 | 24 +++++++++++++++---- .../Modules/M365DSCReverse.psm1 | 2 +- .../Microsoft365DSC/Modules/M365DSCUtil.psm1 | 6 ++++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 625babe659..ff02b56eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ * EXORoleAssignmentPolicy * Fixed logic to update roles assigned to an existing policy; FIXES #1538 +MISC + * Updated logic for Report generation so that it no longer requires the + same module version as defined in the configuration installed on the + system where the report is being generated from. # 1.22.112.1 diff --git a/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 index 192b8ce06a..e0b59c87dc 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 @@ -30,7 +30,11 @@ function New-M365DSCConfigurationToHTML if ([System.String]::IsNullOrEmpty($ParsedContent)) { $TemplateFile = Get-Item $ConfigurationPath - $ParsedContent = ConvertTo-DSCObject -Path $ConfigurationPath + $fileContent = Get-Content $ConfigurationPath -Raw + $startPosition = $fileContent.IndexOf(" -ModuleVersion") + $endPosition = $fileContent.IndexOf("`r", $startPosition) + $fileContent = $fileContent.Remove($startPosition, $endPosition - $startPosition) + $ParsedContent = ConvertTo-DSCObject -Content $fileContent $TemplateName = $TemplateFile.Name.Split('.')[0] } else @@ -211,7 +215,11 @@ function New-M365DSCConfigurationToExcel $report.Range("A1:C1").Borders.Weight = -4138 $row = 2 - $parsedContent = ConvertTo-DSCObject -Path $ConfigurationPath + $fileContent = Get-Content $ConfigurationPath -Raw + $startPosition = $fileContent.IndexOf(" -ModuleVersion") + $endPosition = $fileContent.IndexOf("`r", $startPosition) + $fileContent = $fileContent.Remove($startPosition, $endPosition - $startPosition) + $ParsedContent = ConvertTo-DSCObject -Content $fileContent foreach ($resource in $parsedContent) { $beginRow = $row @@ -391,11 +399,19 @@ function Compare-M365DSCConfigurations if (-not $SourceObject) { - [Array] $SourceObject = ConvertTo-DSCObject -Path $Source + $fileContent = Get-Content $Source -Raw + $startPosition = $fileContent.IndexOf(" -ModuleVersion") + $endPosition = $fileContent.IndexOf("`r", $startPosition) + $fileContent = $fileContent.Remove($startPosition, $endPosition - $startPosition) + [Array] $SourceObject = ConvertTo-DSCObject -Content $fileContent } if (-not $DestinationObject) { - [Array] $DestinationObject = ConvertTo-DSCObject -Path $Destination + $fileContent = Get-Content $Destination -Raw + $startPosition = $fileContent.IndexOf(" -ModuleVersion") + $endPosition = $fileContent.IndexOf("`r", $startPosition) + $fileContent = $fileContent.Remove($startPosition, $endPosition - $startPosition) + [Array] $DestinationObject = ConvertTo-DSCObject -Content $FileContent } # Loop through all items in the source array diff --git a/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 index 9b0a6fc6ce..13c936d058 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCReverse.psm1 @@ -334,7 +334,7 @@ function Start-M365DSCConfigurationExtract } [array]$ModuleVersion = Get-Module Microsoft365DSC $ModuleVersion = $ModuleVersion[0] - $DSCContent += " Import-DscResource -ModuleName 'Microsoft365DSC'`r`n`r`n" + $DSCContent += " Import-DscResource -ModuleName 'Microsoft365DSC' -ModuleVersion '$version'`r`n`r`n" $DSCContent += " Node localhost`r`n" $DSCContent += " {`r`n" diff --git a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 index 5467b8880e..5bd79fb54e 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 @@ -2148,7 +2148,11 @@ function Assert-M365DSCBlueprint if ((Test-Path -Path $LocalBluePrintPath)) { # Parse the content of the BluePrint into an array of PowerShell Objects - $parsedBluePrint = ConvertTo-DSCObject -Path $LocalBluePrintPath + $fileContent = Get-Content $LocalBluePrintPath -Raw + $startPosition = $fileContent.IndexOf(" -ModuleVersion") + $endPosition = $fileContent.IndexOf("`r", $startPosition) + $fileContent = $fileContent.Remove($startPosition, $endPosition - $startPosition) + $parsedBluePrint = ConvertTo-DSCObject -Content $fileContent # Generate an Array of Resource Types contained in the BluePrint $ResourcesInBluePrint = @() From ac3937c9379afa44f7d99779ebf625c56b851c90 Mon Sep 17 00:00:00 2001 From: nikcharlebois Date: Fri, 14 Jan 2022 15:21:50 -0500 Subject: [PATCH 3/3] Update MSFT_EXORoleAssignmentPolicy.psm1 --- .../MSFT_EXORoleAssignmentPolicy.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 index dd94fb3e8c..6ee291d4ed 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORoleAssignmentPolicy/MSFT_EXORoleAssignmentPolicy.psm1 @@ -261,7 +261,7 @@ function Set-TargetResource } elseif ($difference.SideIndicator -eq '<=') { - Write-Verbose -Message "Removing Role {$($difference.InputObject)} to Role Assignment Policy {$Name}" + Write-Verbose -Message "Removing Role {$($difference.InputObject)} from Role Assignment Policy {$Name}" Remove-ManagementRoleAssignment -Identity "$($difference.InputObject)-$Name" } }