Merge pull request #155 from CriticalSolutionsNetwork/Bugfix-Sharepoint-Online-Issue-from-EOY-2024
Bugfix sharepoint online issue from eoy 2024
This commit is contained in:
		| @@ -6,6 +6,14 @@ The format is based on and uses the types of changes according to [Keep a Change | |||||||
|  |  | ||||||
| ### Added | ### Added | ||||||
|  |  | ||||||
|  | - Added additional error handling to connect function to identify problematic steps when they occur. | ||||||
|  | - Added new method of verifying spo tenant for Connect-SPOService branch of connect function. | ||||||
|  | - Added method to avoid "assembly already loaded" error in PNP Powershell function on first run, subsequent runs in the same session will still throw the error. | ||||||
|  |  | ||||||
|  | ## [0.1.26] - 2024-08-04 | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
| - Added `New-M365SecurityAuditAuthObject` function to create a new authentication object for the security audit for app-based authentication. | - Added `New-M365SecurityAuditAuthObject` function to create a new authentication object for the security audit for app-based authentication. | ||||||
|  |  | ||||||
| ### Changed | ### Changed | ||||||
| @@ -19,7 +27,6 @@ The format is based on and uses the types of changes according to [Keep a Change | |||||||
|  |  | ||||||
| - Fixed test 1.3.1 as notification window for password expiration is no longer required. | - Fixed test 1.3.1 as notification window for password expiration is no longer required. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## [0.1.24] - 2024-07-07 | ## [0.1.24] - 2024-07-07 | ||||||
|  |  | ||||||
| ### Added | ### Added | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1 | |||||||
|  |  | ||||||
|  |  | ||||||
| <# | <# | ||||||
|     $ver = "v0.1.26" |     $ver = "v0.1.27" | ||||||
|     git checkout main |     git checkout main | ||||||
|     git pull origin main |     git pull origin main | ||||||
|     git tag -a $ver -m "Release version $ver refactor Update" |     git tag -a $ver -m "Release version $ver refactor Update" | ||||||
|   | |||||||
| @@ -20,6 +20,17 @@ function Assert-ModuleAvailability { | |||||||
|                 else { |                 else { | ||||||
|                     Write-Verbose "$ModuleName module is already at required version or newer." |                     Write-Verbose "$ModuleName module is already at required version or newer." | ||||||
|                 } |                 } | ||||||
|  |                 if ($ModuleName -eq "Microsoft.Graph") { | ||||||
|  |                     # "Preloading Microsoft.Graph assembly to prevent type-loading issues..." | ||||||
|  |                     Write-Verbose "Preloading Microsoft.Graph assembly to prevent type-loading issues..." | ||||||
|  |                     try { | ||||||
|  |                         # Run a harmless cmdlet to preload the assembly | ||||||
|  |                         Get-MgGroup -Top 1 -ErrorAction SilentlyContinue | Out-Null | ||||||
|  |                     } | ||||||
|  |                     catch { | ||||||
|  |                         Write-Verbose "Could not preload Microsoft.Graph assembly. Error: $_" | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 if ($SubModules.Count -gt 0) { |                 if ($SubModules.Count -gt 0) { | ||||||
|                     foreach ($subModule in $SubModules) { |                     foreach ($subModule in $SubModules) { | ||||||
|                         Write-Verbose "Importing submodule $ModuleName.$subModule..." |                         Write-Verbose "Importing submodule $ModuleName.$subModule..." | ||||||
| @@ -30,11 +41,9 @@ function Assert-ModuleAvailability { | |||||||
|                     Write-Verbose "Importing module $ModuleName..." |                     Write-Verbose "Importing module $ModuleName..." | ||||||
|                     Import-Module -Name $ModuleName -RequiredVersion $RequiredVersion -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null |                     Import-Module -Name $ModuleName -RequiredVersion $RequiredVersion -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|         } |         } | ||||||
|         catch { |         catch { | ||||||
|             throw "Assert-ModuleAvailability:`n$_" |             throw "Assert-ModuleAvailability:`n$_" | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -2,135 +2,143 @@ function Connect-M365Suite { | |||||||
|     [OutputType([void])] |     [OutputType([void])] | ||||||
|     [CmdletBinding()] |     [CmdletBinding()] | ||||||
|     param ( |     param ( | ||||||
|         [Parameter( |         [Parameter(Mandatory = $false)] | ||||||
|             Mandatory = $false |  | ||||||
|         )] |  | ||||||
|         [string]$TenantAdminUrl, |         [string]$TenantAdminUrl, | ||||||
|         [Parameter( |  | ||||||
|             Mandatory = $false |         [Parameter(Mandatory = $false)] | ||||||
|         )] |         [CISAuthenticationParameters]$AuthParams, | ||||||
|         [CISAuthenticationParameters]$AuthParams, # Custom authentication parameters |  | ||||||
|         [Parameter( |         [Parameter(Mandatory)] | ||||||
|             Mandatory |  | ||||||
|         )] |  | ||||||
|         [string[]]$RequiredConnections, |         [string[]]$RequiredConnections, | ||||||
|         [Parameter( |  | ||||||
|             Mandatory = $false |         [Parameter(Mandatory = $false)] | ||||||
|         )] |  | ||||||
|         [switch]$SkipConfirmation |         [switch]$SkipConfirmation | ||||||
|     ) |     ) | ||||||
|     if (!$SkipConfirmation) { |  | ||||||
|         $VerbosePreference = "Continue" |     $VerbosePreference = if ($SkipConfirmation) { 'SilentlyContinue' } else { 'Continue' } | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         $VerbosePreference = "SilentlyContinue" |  | ||||||
|     } |  | ||||||
|     $tenantInfo = @() |     $tenantInfo = @() | ||||||
|     $connectedServices = @() |     $connectedServices = @() | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         if ($RequiredConnections -contains "Microsoft Graph" -or $RequiredConnections -contains "EXO | Microsoft Graph") { |         if ($RequiredConnections -contains 'Microsoft Graph' -or $RequiredConnections -contains 'EXO | Microsoft Graph') { | ||||||
|             Write-Verbose "Connecting to Microsoft Graph" |             try { | ||||||
|             if ($AuthParams) { |                 Write-Verbose 'Connecting to Microsoft Graph...' | ||||||
|                 # Use application-based authentication |                 if ($AuthParams) { | ||||||
|                 Connect-MgGraph -CertificateThumbprint $AuthParams.ClientCertThumbPrint -AppId $AuthParams.ClientId -TenantId $AuthParams.TenantId -NoWelcome | Out-Null |                     Connect-MgGraph -CertificateThumbprint $AuthParams.ClientCertThumbPrint -AppId $AuthParams.ClientId -TenantId $AuthParams.TenantId -NoWelcome | Out-Null | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     Connect-MgGraph -Scopes 'Directory.Read.All', 'Domain.Read.All', 'Policy.Read.All', 'Organization.Read.All' -NoWelcome | Out-Null | ||||||
|  |                 } | ||||||
|  |                 $graphOrgDetails = Get-MgOrganization | ||||||
|  |                 $tenantInfo += [PSCustomObject]@{ | ||||||
|  |                     Service    = 'Microsoft Graph' | ||||||
|  |                     TenantName = $graphOrgDetails.DisplayName | ||||||
|  |                     TenantID   = $graphOrgDetails.Id | ||||||
|  |                 } | ||||||
|  |                 $connectedServices += 'Microsoft Graph' | ||||||
|  |                 Write-Verbose 'Successfully connected to Microsoft Graph.' | ||||||
|             } |             } | ||||||
|             else { |             catch { | ||||||
|                 # Use interactive authentication with scopes |                 throw "Failed to connect to Microsoft Graph: $($_.Exception.Message)" | ||||||
|                 Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null |  | ||||||
|             } |             } | ||||||
|             $graphOrgDetails = Get-MgOrganization |  | ||||||
|             $tenantInfo += [PSCustomObject]@{ |  | ||||||
|                 Service    = "Microsoft Graph" |  | ||||||
|                 TenantName = $graphOrgDetails.DisplayName |  | ||||||
|                 TenantID   = $graphOrgDetails.Id |  | ||||||
|             } |  | ||||||
|             $connectedServices += "Microsoft Graph" |  | ||||||
|             Write-Verbose "Successfully connected to Microsoft Graph.`n" |  | ||||||
|         } |         } | ||||||
|         if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO" -or $RequiredConnections -contains "EXO | Microsoft Graph") { |  | ||||||
|             Write-Verbose "Connecting to Exchange Online..." |         if ($RequiredConnections -contains 'EXO' -or $RequiredConnections -contains 'AzureAD | EXO' -or $RequiredConnections -contains 'Microsoft Teams | EXO' -or $RequiredConnections -contains 'EXO | Microsoft Graph') { | ||||||
|             if ($AuthParams) { |             try { | ||||||
|                 # Use application-based authentication |                 Write-Verbose 'Connecting to Exchange Online...' | ||||||
|                 Connect-ExchangeOnline -AppId $AuthParams.ClientId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -Organization $AuthParams.OnMicrosoftUrl -ShowBanner:$false | Out-Null |                 if ($AuthParams) { | ||||||
|  |                     Connect-ExchangeOnline -AppId $AuthParams.ClientId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -Organization $AuthParams.OnMicrosoftUrl -ShowBanner:$false | Out-Null | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     Connect-ExchangeOnline -ShowBanner:$false | Out-Null | ||||||
|  |                 } | ||||||
|  |                 $exoTenant = (Get-OrganizationConfig).Identity | ||||||
|  |                 $tenantInfo += [PSCustomObject]@{ | ||||||
|  |                     Service    = 'Exchange Online' | ||||||
|  |                     TenantName = $exoTenant | ||||||
|  |                     TenantID   = 'N/A' | ||||||
|  |                 } | ||||||
|  |                 $connectedServices += 'EXO' | ||||||
|  |                 Write-Verbose 'Successfully connected to Exchange Online.' | ||||||
|             } |             } | ||||||
|             else { |             catch { | ||||||
|                 # Use interactive authentication |                 throw "Failed to connect to Exchange Online: $($_.Exception.Message)" | ||||||
|                 Connect-ExchangeOnline -ShowBanner:$false | Out-Null |  | ||||||
|             } |             } | ||||||
|             $exoTenant = (Get-OrganizationConfig).Identity |  | ||||||
|             $tenantInfo += [PSCustomObject]@{ |  | ||||||
|                 Service    = "Exchange Online" |  | ||||||
|                 TenantName = $exoTenant |  | ||||||
|                 TenantID   = "N/A" |  | ||||||
|             } |  | ||||||
|             $connectedServices += "EXO" |  | ||||||
|             Write-Verbose "Successfully connected to Exchange Online.`n" |  | ||||||
|         } |         } | ||||||
|         if ($RequiredConnections -contains "SPO") { |  | ||||||
|             Write-Verbose "Connecting to SharePoint Online..." |         if ($RequiredConnections -contains 'SPO') { | ||||||
|             if ($AuthParams) { |             try { | ||||||
|                 # Use application-based authentication |                 Write-Verbose 'Connecting to SharePoint Online...' | ||||||
|                 Connect-PnPOnline -Url $AuthParams.SpAdminUrl -ClientId $AuthParams.ClientId -Tenant $AuthParams.OnMicrosoftUrl -Thumbprint $AuthParams.ClientCertThumbPrint | Out-Null |                 if ($AuthParams) { | ||||||
|  |                     Connect-PnPOnline -Url $AuthParams.SpAdminUrl -ClientId $AuthParams.ClientId -Tenant $AuthParams.OnMicrosoftUrl -Thumbprint $AuthParams.ClientCertThumbPrint | Out-Null | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     Connect-SPOService -Url $TenantAdminUrl | Out-Null | ||||||
|  |                 } | ||||||
|  |                 $tenantName = if ($AuthParams) { | ||||||
|  |                     (Get-PnPSite).Url | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     $sites =  Get-SPOSite | ||||||
|  |                     # Get the URL from the first site collection | ||||||
|  |                     $url = $sites[0].Url | ||||||
|  |                     # Use regex to extract the base URL up to the .com portion | ||||||
|  |                     $baseUrl = [regex]::Match($url, 'https://[^/]+.com').Value | ||||||
|  |                     # Output the base URL | ||||||
|  |                     $baseUrl | ||||||
|  |                 } | ||||||
|  |                 $tenantInfo += [PSCustomObject]@{ | ||||||
|  |                     Service    = 'SharePoint Online' | ||||||
|  |                     TenantName = $tenantName | ||||||
|  |                 } | ||||||
|  |                 $connectedServices += 'SPO' | ||||||
|  |                 Write-Verbose 'Successfully connected to SharePoint Online.' | ||||||
|             } |             } | ||||||
|             else { |             catch { | ||||||
|                 # Use interactive authentication |                 throw "Failed to connect to SharePoint Online: $($_.Exception.Message)" | ||||||
|                 Connect-SPOService -Url $TenantAdminUrl | Out-Null |  | ||||||
|             } |             } | ||||||
|             # Assuming that Get-SPOCrossTenantHostUrl and Get-UrlLine are valid commands in your context |  | ||||||
|             if ($AuthParams) { |  | ||||||
|                 $spoContext = Get-PnPSite |  | ||||||
|                 $tenantName = $spoContext.Url |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 $spoContext = Get-SPOCrossTenantHostUrl |  | ||||||
|                 $tenantName = Get-UrlLine -Output $spoContext |  | ||||||
|             } |  | ||||||
|             $tenantInfo += [PSCustomObject]@{ |  | ||||||
|                 Service    = "SharePoint Online" |  | ||||||
|                 TenantName = $tenantName |  | ||||||
|             } |  | ||||||
|             $connectedServices += "SPO" |  | ||||||
|             Write-Verbose "Successfully connected to SharePoint Online.`n" |  | ||||||
|         } |         } | ||||||
|         if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") { |  | ||||||
|             Write-Verbose "Connecting to Microsoft Teams..." |         if ($RequiredConnections -contains 'Microsoft Teams' -or $RequiredConnections -contains 'Microsoft Teams | EXO') { | ||||||
|             if ($AuthParams) { |             try { | ||||||
|                 # Use application-based authentication |                 Write-Verbose 'Connecting to Microsoft Teams...' | ||||||
|                 Connect-MicrosoftTeams -TenantId $AuthParams.TenantId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -ApplicationId $AuthParams.ClientId | Out-Null |                 if ($AuthParams) { | ||||||
|  |                     Connect-MicrosoftTeams -TenantId $AuthParams.TenantId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -ApplicationId $AuthParams.ClientId | Out-Null | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     Connect-MicrosoftTeams | Out-Null | ||||||
|  |                 } | ||||||
|  |                 $teamsTenantDetails = Get-CsTenant | ||||||
|  |                 $tenantInfo += [PSCustomObject]@{ | ||||||
|  |                     Service    = 'Microsoft Teams' | ||||||
|  |                     TenantName = $teamsTenantDetails.DisplayName | ||||||
|  |                     TenantID   = $teamsTenantDetails.TenantId | ||||||
|  |                 } | ||||||
|  |                 $connectedServices += 'Microsoft Teams' | ||||||
|  |                 Write-Verbose 'Successfully connected to Microsoft Teams.' | ||||||
|             } |             } | ||||||
|             else { |             catch { | ||||||
|                 # Use interactive authentication |                 throw "Failed to connect to Microsoft Teams: $($_.Exception.Message)" | ||||||
|                 Connect-MicrosoftTeams | Out-Null |  | ||||||
|             } |             } | ||||||
|             $teamsTenantDetails = Get-CsTenant |  | ||||||
|             $tenantInfo += [PSCustomObject]@{ |  | ||||||
|                 Service    = "Microsoft Teams" |  | ||||||
|                 TenantName = $teamsTenantDetails.DisplayName |  | ||||||
|                 TenantID   = $teamsTenantDetails.TenantId |  | ||||||
|             } |  | ||||||
|             $connectedServices += "Microsoft Teams" |  | ||||||
|             Write-Verbose "Successfully connected to Microsoft Teams.`n" |  | ||||||
|         } |         } | ||||||
|         # Display tenant information and confirm with the user |  | ||||||
|         if (-not $SkipConfirmation) { |         if (-not $SkipConfirmation) { | ||||||
|             Write-Verbose "Connected to the following tenants:" |             Write-Verbose 'Connected to the following tenants:' | ||||||
|             foreach ($tenant in $tenantInfo) { |             foreach ($tenant in $tenantInfo) { | ||||||
|                 Write-Verbose "Service: $($tenant.Service)" |                 Write-Verbose "Service: $($tenant.Service) | Tenant: $($tenant.TenantName)" | ||||||
|                 Write-Verbose "Tenant Context: $($tenant.TenantName)`n" |  | ||||||
|                 #Write-Verbose "Tenant ID: $($tenant.TenantID)" |  | ||||||
|             } |             } | ||||||
|             $confirmation = Read-Host "Do you want to proceed with these connections? (Y/N)" |             $confirmation = Read-Host 'Do you want to proceed with these connections? (Y/N)' | ||||||
|             if ($confirmation -notLike 'Y') { |             if ($confirmation -notlike 'Y') { | ||||||
|                 Write-Verbose "Connection setup aborted by user." |  | ||||||
|                 Disconnect-M365Suite -RequiredConnections $connectedServices |                 Disconnect-M365Suite -RequiredConnections $connectedServices | ||||||
|                 throw "User aborted connection setup." |                 throw 'User aborted connection setup.' | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     catch { |     catch { | ||||||
|         $CatchError = $_ |         $VerbosePreference = 'Continue' | ||||||
|         $VerbosePreference = "Continue" |         throw "Connection failed: $($_.Exception.Message)" | ||||||
|         throw $CatchError |     } | ||||||
|  |     finally { | ||||||
|  |         $VerbosePreference = 'Continue' | ||||||
|     } |     } | ||||||
|     $VerbosePreference = "Continue" |  | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user