Skip to content

Commit 8507a98

Browse files
committed
Added M365 connections to shared
split in functions Fix Spell Added EXO Connection script Fix requested Changes Simplify with functions and split Graph and EXO Changes requested Added docs added examples Verbose intalled module and parameter in singular added changes requested fix tipo fix after modify plural
1 parent 7dd28f5 commit 8507a98

File tree

3 files changed

+415
-0
lines changed

3 files changed

+415
-0
lines changed

Shared/M365/EXOConnection.ps1

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
<#
5+
.SYNOPSIS
6+
This script defines a function `Connect-EXOAdvanced` that establishes a connection to Exchange Online.
7+
It ensures that the required ExchangeOnlineManagement module (version 3.0.0 or higher by default) is installed and loaded.
8+
The function supports single and multiple session connections, with optional parameters to control the connection details display and session prefix.
9+
If the required module is not found, the script attempts to install it.
10+
The function returns the connection information or null if the connection fails.
11+
12+
.PARAMETER DoNotShowConnectionDetails
13+
Optional switch to hide connection details.
14+
.PARAMETER AllowMultipleSessions
15+
Optional switch to allow multiple sessions.
16+
.PARAMETER Prefix
17+
Optional string to specify a prefix for the session.
18+
.PARAMETER MinModuleVersion
19+
Optional parameter to specify the minimum version of the ExchangeOnlineManagement module (default and minimum supported version is 3.0.0).
20+
21+
.OUTPUTS
22+
Microsoft.Exchange.Management.ExoPowershellSnapin.ConnectionInformation. The connection information object for the Exchange Online session.
23+
24+
.EXAMPLE
25+
$exoConnection = Connect-EXOAdvanced
26+
This example establishes a connection to Exchange Online using the default settings.
27+
28+
.EXAMPLE
29+
$exoConnection = Connect-EXOAdvanced -AllowMultipleSessions
30+
This example establishes a connection to Exchange Online and allows multiple sessions.
31+
32+
.EXAMPLE
33+
$exoConnection = Connect-EXOAdvanced -AllowMultipleSessions -Prefix Con2
34+
This example establishes a connection to Exchange Online, allows multiple sessions, and specifies a prefix "Con2" for the session.
35+
36+
.EXAMPLE
37+
$exoConnection2 = Connect-EXOAdvanced -minModuleVersion 3.5.0
38+
This example establishes a connection to Exchange Online and specifies a minimum module version of 3.5.0.
39+
#>
40+
41+
. $PSScriptRoot\..\ModuleHandle.ps1
42+
43+
function Connect-EXOAdvanced {
44+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High")]
45+
param (
46+
[Parameter(Mandatory = $false, ParameterSetName = 'SingleSession')]
47+
[Parameter(Mandatory = $false, ParameterSetName = 'AllowMultipleSessions')]
48+
[switch]$DoNotShowConnectionDetails,
49+
[Parameter(Mandatory = $true, ParameterSetName = 'AllowMultipleSessions')]
50+
[switch]$AllowMultipleSessions,
51+
[Parameter(Mandatory = $false, ParameterSetName = 'AllowMultipleSessions')]
52+
[string]$Prefix = $null,
53+
[ValidateScript({
54+
if ($_ -lt [System.Version]'3.0.0.0') {
55+
throw "Minimum supported version: 3.0.0.0"
56+
}
57+
$true
58+
})]
59+
[Parameter(Mandatory = $false, ParameterSetName = 'SingleSession')]
60+
[Parameter(Mandatory = $false, ParameterSetName = 'AllowMultipleSessions')]
61+
[System.Version]$MinModuleVersion = '3.0.0.0'
62+
)
63+
64+
#Validate EXO 3.0 is installed and loaded
65+
$requestModule = Request-Module -Module "ExchangeOnlineManagement" -MinModuleVersion $MinModuleVersion
66+
67+
if (-not $requestModule) {
68+
Write-Host "We cannot continue without ExchangeOnlineManagement Powershell module" -ForegroundColor Red
69+
return $null
70+
}
71+
72+
#Validate EXO is connected or try to connect
73+
$connections = $null
74+
$newConnection = $null
75+
try {
76+
$connections = Get-ConnectionInformation -ErrorAction Stop | Where-Object { $_.State -eq 'Connected' }
77+
} catch {
78+
Write-Host "We cannot check connections. Error:`n$_" -ForegroundColor Red
79+
return $null
80+
}
81+
82+
if ($null -eq $connections -or $AllowMultipleSessions) {
83+
if ($connections.ModulePrefix -contains $Prefix) {
84+
Write-Host "You already have a session" -ForegroundColor Yellow -NoNewline
85+
if ($Prefix) {
86+
Write-Host " with the prefix $Prefix." -ForegroundColor Yellow
87+
} else {
88+
Write-Host " without prefix." -ForegroundColor Yellow
89+
}
90+
$newConnection = $connections | Where-Object { $_.ModulePrefix -eq $Prefix }
91+
} else {
92+
$prefixString = "."
93+
if ($Prefix) { $prefixString = " with Prefix $Prefix." }
94+
Write-Host "Not connected to Exchange Online$prefixString" -ForegroundColor Yellow
95+
96+
if ($PSCmdlet.ShouldProcess("Do you want to add it?", "Adding an Exchange Online Session")) {
97+
Write-Verbose "Connecting to Exchange Online session"
98+
try {
99+
Connect-ExchangeOnline -ShowBanner:$false -Prefix $Prefix -ErrorAction Stop
100+
} catch {
101+
Write-Host "We cannot connect to Exchange Online. Error:`n$_" -ForegroundColor Red
102+
return $null
103+
}
104+
try {
105+
$newConnections = Get-ConnectionInformation -ErrorAction Stop
106+
} catch {
107+
Write-Host "We cannot check connections. Error:`n$_" -ForegroundColor Red
108+
return $null
109+
}
110+
foreach ($testConnection in $newConnections) {
111+
if ($connections -notcontains $testConnection) {
112+
$newConnection = $testConnection
113+
}
114+
}
115+
}
116+
}
117+
if ($newConnection.count -gt 1) {
118+
Write-Host "You have more than one Exchange Online sessions with Prefix $Prefix." -ForegroundColor Red
119+
return $null
120+
}
121+
} else {
122+
Write-Verbose "You already have an Exchange Online session"
123+
if ($connections.count -gt 1) {
124+
Write-Host "You have more than one Exchange Online sessions please use just one session. You are not using AllowMultipleSessions" -ForegroundColor Red
125+
return $null
126+
}
127+
$newConnection = $connections
128+
}
129+
130+
Write-Verbose "Connected session to Exchange Online"
131+
$newConnection.PSObject.Properties | ForEach-Object { Write-Verbose "$($_.Name): $($_.Value)" }
132+
if (-not $DoNotShowConnectionDetails) {
133+
Show-EXOConnection -Connection $newConnection
134+
}
135+
return $newConnection
136+
}
137+
138+
function Show-EXOConnection {
139+
param (
140+
[Parameter(Mandatory = $true)]
141+
[Microsoft.Exchange.Management.ExoPowershellSnapin.ConnectionInformation]$Connection
142+
)
143+
Write-Host "`nConnected to Exchange Online"
144+
Write-Host "Session details"
145+
Write-Host "Tenant Id: $($Connection.TenantId)"
146+
Write-Host "User: $($Connection.UserPrincipalName)"
147+
if ($($Connection.ModulePrefix)) {
148+
Write-Host "Prefix: $($Connection.ModulePrefix)"
149+
}
150+
}

Shared/M365/GraphConnection.ps1

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
<#
5+
.SYNOPSIS
6+
This script defines a function `Connect-GraphAdvanced` that establishes a connection to Microsoft Graph.
7+
It ensures that the required modules are installed and loaded.
8+
The function accepts a list of scopes and modules, with optional parameters for tenant ID and connection details display.
9+
If the required modules are not found, the script attempts to install them.
10+
The function returns the connection information or null if the connection fails.
11+
12+
.PARAMETER Scopes
13+
Mandatory array of strings specifying the scopes for the connection.
14+
.PARAMETER Modules
15+
Mandatory array of strings specifying the modules required for the connection.
16+
.PARAMETER TenantId
17+
Optional array of strings specifying the tenant ID(s) for the connection.
18+
.PARAMETER DoNotShowConnectionDetails
19+
Optional switch to hide connection details.
20+
.PARAMETER MinModuleVersion
21+
Optional parameter to specify the minimum version of the Graph modules (default and minimum supported version 2.0.0).
22+
23+
.OUTPUTS
24+
Microsoft.Graph.PowerShell.Authentication.AuthContext. The connection information object for the Microsoft Graph session.
25+
26+
.EXAMPLE
27+
$graphConnection = Connect-GraphAdvanced -Scopes User.Read, Mail.Read -Modules Microsoft.Graph
28+
This example establishes a connection to Microsoft Graph with the scopes "User.Read" and "Mail.Read" using the "Microsoft.Graph" module.
29+
30+
.EXAMPLE
31+
$graphConnection = Connect-GraphAdvanced -Scopes Group.Read.All, User.Read.All -Modules Microsoft.Graph.Users, Microsoft.Graph.Groups
32+
This example establishes a connection to Microsoft Graph with the scopes "Group.Read.All" and "User.Read.All" using the "Microsoft.Graph.Users" and "Microsoft.Graph.Groups" modules.
33+
34+
.EXAMPLE
35+
$graphConnection = Connect-GraphAdvanced -Scopes Group.Read.All, User.Read.All -Modules Microsoft.Graph.Users, Microsoft.Graph.Groups -minModuleVersion 2.25.0
36+
This example establishes a connection to Microsoft Graph with the scopes "Group.Read.All" and "User.Read.All" using the "Microsoft.Graph.Users" and "Microsoft.Graph.Groups" modules, and specifies a minimum module version of 2.25.0.
37+
#>
38+
39+
. $PSScriptRoot\..\ModuleHandle.ps1
40+
41+
function Connect-GraphAdvanced {
42+
param (
43+
[Parameter(Mandatory = $true)]
44+
[string[]]$Scopes,
45+
[Parameter(Mandatory = $true)]
46+
[string[]]$Modules,
47+
[Parameter(Mandatory = $false)]
48+
[string[]]$TenantId = $null,
49+
[Parameter(Mandatory = $false)]
50+
[switch]$DoNotShowConnectionDetails,
51+
[ValidateScript({
52+
if ($_ -lt [System.Version]'2.0.0.0') {
53+
throw "Minimum supported version: 2.0.0.0"
54+
}
55+
$true
56+
})]
57+
[Parameter(Mandatory = $false)]
58+
[System.Version]$MinModuleVersion = '2.0.0.0'
59+
)
60+
61+
#Validate Graph is installed and loaded
62+
$requestModule = Request-Module -Module $Modules -MinModuleVersion $MinModuleVersion
63+
if (-not $requestModule) {
64+
Write-Host "We cannot continue without $Modules Powershell module" -ForegroundColor Red
65+
return $null
66+
}
67+
68+
#Validate Graph is connected or try to connect
69+
$connection = $null
70+
try {
71+
$connection = Get-MgContext -ErrorAction Stop
72+
} catch {
73+
Write-Host "We cannot check context. Error:`n$_" -ForegroundColor Red
74+
return $null
75+
}
76+
77+
if ($null -eq $connection) {
78+
Write-Host "Not connected to Graph" -ForegroundColor Yellow
79+
$connection = Add-GraphConnection -Scopes $Scopes
80+
} else {
81+
Write-Verbose "You have a Graph sessions"
82+
Write-Verbose "Checking scopes"
83+
if (-not (Test-GraphScopeContext -Scopes $connection.Scopes -ExpectedScopes $Scopes)) {
84+
Write-Host "Not connected to Graph with expected scopes" -ForegroundColor Yellow
85+
$connection = Add-GraphConnection -Scopes $Scopes
86+
} else {
87+
Write-Verbose "All scopes are present"
88+
}
89+
}
90+
91+
if ($connection) {
92+
Write-Verbose "Checking TenantId"
93+
if ($TenantId) {
94+
if ($connection.TenantId -ne $TenantId) {
95+
Write-Host "Connected to $($connection.TenantId). Not expected tenant: $TenantId" -ForegroundColor Red
96+
return $null
97+
} else {
98+
Write-Verbose "TenantId is correct"
99+
}
100+
}
101+
102+
$connection.PSObject.Properties | ForEach-Object { Write-Verbose "$($_.Name): $($_.Value)" }
103+
if (-not $DoNotShowConnectionDetails) {
104+
Show-GraphContext -Context $connection
105+
}
106+
}
107+
return $connection
108+
}
109+
110+
function Add-GraphConnection {
111+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High")]
112+
param (
113+
[Parameter(Mandatory = $true)]
114+
[string[]]$Scopes
115+
)
116+
117+
if ($PSCmdlet.ShouldProcess("Do you want to connect?", "We need a Graph connection with scopes $Scopes")) {
118+
Write-Verbose "Connecting to Microsoft Graph API using scopes $Scopes"
119+
try {
120+
Connect-MgGraph -Scopes $Scopes -NoWelcome -ErrorAction Stop
121+
} catch {
122+
Write-Host "We cannot connect to Graph. Error:`n$_" -ForegroundColor Red
123+
return $null
124+
}
125+
$connection = $null
126+
try {
127+
$connection = Get-MgContext -ErrorAction Stop
128+
} catch {
129+
Write-Host "We cannot check context. Error:`n$_" -ForegroundColor Red
130+
return $null
131+
}
132+
Write-Verbose "Checking scopes"
133+
if (-not $connection) {
134+
Write-Host "We cannot continue without Graph Powershell session" -ForegroundColor Red
135+
return $null
136+
}
137+
if (-not (Test-GraphScopeContext -Scopes $connection.Scopes -ExpectedScopes $Scopes)) {
138+
Write-Host "We cannot continue without Graph Powershell session without Expected Scopes" -ForegroundColor Red
139+
return $null
140+
}
141+
return $connection
142+
}
143+
}
144+
145+
function Test-GraphScopeContext {
146+
[OutputType([bool])]
147+
param (
148+
[Parameter(Mandatory = $true)]
149+
[string[]]$ExpectedScopes,
150+
[Parameter(Mandatory = $true)]
151+
[string[]]$Scopes
152+
)
153+
154+
$foundError = $false
155+
foreach ($expectedScope in $ExpectedScopes) {
156+
if ($Scopes -notcontains $expectedScope) {
157+
Write-Host "The following scope is missing: $expectedScope" -ForegroundColor Red
158+
$foundError = $true
159+
}
160+
}
161+
162+
Write-Verbose "All expected scopes are $(if($foundError){ "NOT "})present."
163+
return (-not $foundError)
164+
}
165+
166+
function Show-GraphContext {
167+
param (
168+
[Parameter(Mandatory = $true)]
169+
[Microsoft.Graph.PowerShell.Authentication.AuthContext]$Context
170+
)
171+
Write-Host "`nConnected to Graph"
172+
Write-Host "Session details"
173+
Write-Host "Tenant Id: $($Context.TenantId)"
174+
if ($graphConnection.AuthType) {
175+
Write-Host "AuthType: $($graphConnection.AuthType)"
176+
}
177+
if ($Context.Account) {
178+
Write-Host "Account: $($Context.Account)"
179+
}
180+
}

0 commit comments

Comments
 (0)