microsoft / microsoft/CSS-Exchange
Finish and merge the shared M365 connection helper (PR #2090) — including Pester coverage
Nobody has claimed this yet.
- Dominant language
- PowerShell
- Stars
- 1.3k
- Forks
- 395
- Avg merge
- 14h 7m
- Merged PRs (30d)
- 5
Description
Parent: #2590
Complete PR #2090 so we have a single, correct, tested helper for Shared/M365/EXOConnection.ps1 (Connect-EXOAdvanced), Shared/M365/GraphConnection.ps1 (Connect-GraphAdvanced), and Shared/ModuleHandle.ps1 (Request-Module).
Housekeeping
- Squash PR #2090 to a single commit (requested by @dpaulson45 five times over 2024–2026; blocking merge).
Connect-EXOAdvanced — required additions
- 🚨
-AzureADAuthorizationEndpointUri— sovereign clouds (GCC High, DoD, 21Vianet, Germany) cannot connect without it. Splat only when non-empty. -
-ConnectionUri— required for MailPublicFolderSync + 21Vianet callers. Default tohttps://outlook.office365.com/powerShell-liveID. -
-Credential— required for non-interactive scenarios. Splat only when non-null. - Fix
-Prefixparameter set binding. Today it's bound only to theAllowMultipleSessionsset. Make it valid in theSingleSessionset too — every MailPublicFolderSync script uses-Prefix "Remote"on a single session. - Default
[string]$Prefix = '', not$null. Splat-Prefixonly when non-empty. - Session reuse check must consider prefix + tenant + UPN, not just
ModulePrefix. Mirror the tenant check that already exists inConnect-GraphAdvanced. -
Get-Module -ListAvailablefallback whenGet-InstalledModulereturns nothing (modules installed via MSI, side-loading, or provisioned images aren't visible to PowerShellGet). - New
Disconnect-EXOAdvancedcompanion — accepts the connection object the helper returned, disconnects only that session. Never touches sessions the helper didn't open. This closes the class of bugs seen inImport-MailPublicFolders.ps1(unguardedDisconnect-ExchangeOnline). - Document unattended usage in the function help —
ConfirmImpact = "High"requires the caller to pass-Confirm:$falsefor automation. - Document the return contract —
$nullon failure (do not throw). Callers should code againstif (-not $exo) { return }.
Connect-GraphAdvanced — required additions
-
-Environment(Global / USGov / USGovDoD / China) — sovereign-cloud parity withConnect-EXOAdvanced. - Verify same
Disconnect-GraphAdvancedcompanion story.
Request-Module (Shared/ModuleHandle.ps1) — required additions
-
-MaximumVersion— some callers need to pin around known-bad module releases. - Reconsider
Install-Module -AllowClobber— silently overrides other modules' cmdlets. At minimum, warn. -
Get-Module -ListAvailablefallback same as above.
Pester coverage (new — not currently in PR #2090)
@dpaulson45 asked for tests on 11/04/2024; they were never added.
Follow the mocking pattern proven safe in Sync-ModernMailPublicFolders.Tests.ps1 — no real connection to Exchange Online or Graph is made. Every network cmdlet must be mocked; a stub Connect-ExchangeOnline at test-scope throws if a code path forgets to mock it:
BeforeAll {
. $PSScriptRoot\..\M365\EXOConnection.ps1
# Safety net: fail loudly if any test forgets to mock the real cmdlet
function Connect-ExchangeOnline {
param($ConnectionUri, $Prefix, $Credential, $AzureADAuthorizationEndpointUri, $ShowBanner, $ErrorAction)
throw "Connect-ExchangeOnline must be mocked."
}
function Get-ConnectionInformation { throw "Get-ConnectionInformation must be mocked." }
function Disconnect-ExchangeOnline { throw "Disconnect-ExchangeOnline must be mocked." }
function Install-Module { throw "Install-Module must be mocked." }
}
Required test cases for Connect-EXOAdvanced:
- Success on a clean environment (no existing session): calls
Connect-ExchangeOnline -ErrorAction Stop -ShowBanner:$false, returns connection info. - Reuses an existing single session with matching prefix + tenant + UPN.
- Does not reuse a session whose tenant/UPN differs (regression guard).
-
-AllowMultipleSessionsopens a second session when one already exists with a different prefix. -
-Prefixis accepted in theSingleSessionparameter set. -
-AzureADAuthorizationEndpointUriis forwarded when specified; not forwarded when empty. -
-ConnectionUriis forwarded when specified. -
-Credentialis forwarded when specified. - Non-terminating
Connect-ExchangeOnlineerror (mock throws) → helper returns$null, does not report success. -
Import-Modulefailure → helper returns$null, never invokesConnect-ExchangeOnline. -
Request-Modulereturning$false→ helper returns$null. -
Disconnect-EXOAdvanceddisconnects only the session the helper opened; ignores sessions the helper didn't open.
Required test cases for Connect-GraphAdvanced:
- Scope mismatch triggers reconnect.
- Tenant mismatch triggers failure (as designed).
-
-Environmentforwarded toConnect-MgGraph. - Non-terminating
Connect-MgGrapherror → returns$null.
Required test cases for Request-Module:
-
Get-InstalledModulehit → returns$truewithout callingInstall-Module. -
Get-InstalledModulemiss +Get-Module -ListAvailablehit → returns$truewithout callingInstall-Module. -
Get-InstalledModulemiss + no available → callsInstall-Modulewith correct scope. -
-InstallAllUsersIfNotAvailablewithout admin returns$false. -
-MinModuleVersion/-MaximumVersionforwarded to bothGet-InstalledModuleandInstall-Module.
Done when: PR #2090 is merged with all boxes above checked and CI green.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing PR #2090 and the three named helper files: Shared/M365/EXOConnection.ps1, Shared/M365/GraphConnection.ps1, and Shared/ModuleHandle.ps1. Use the mocking pattern in PublicFolders/MailPublicFolderSync/Tests/Sync-ModernMailPublicFolders.Tests.ps1, then add the requested Pester coverage; done means every listed box is checked, PR #2090 is merged, and CI is green.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- powershell
- Domain
- authentication, testing, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100