Overview#
Checks whether the Microsoft Graph PowerShell SDK authentication module (Microsoft.Graph.Authentication) and the Exchange Online Management module (ExchangeOnlineManagement) are installed, installs anything that is missing from the PowerShell Gallery, and optionally updates existing installs to the latest release. With -IncludeDevTools it also installs PSScriptAnalyzer, which the repository's CI workflow uses.
Nothing is installed without your confirmation unless you pass -Confirm:$false, and -WhatIf shows the plan without changing anything.
Safety: Makes changes only when you pass an explicit switch; supports -WhatIf and -Confirm. Run Get-Help .\Install-Prerequisites.ps1 -Full for the complete help text.
Parameters#
| Parameter | What it does |
|---|---|
-Scope | Installation scope passed to Install-Module. CurrentUser (default) needs no elevation; AllUsers requires an elevated session. |
-Update | Update modules that are already installed to the newest version available in the PowerShell Gallery. |
-IncludeDevTools | Also install PSScriptAnalyzer for local linting. |
Examples#
PS> .\Install-Prerequisites.ps1Installs any missing module for the current user.
PS> .\Install-Prerequisites.ps1 -Update -IncludeDevTools -VerboseInstalls or updates every module, including PSScriptAnalyzer, and shows what happens along the way.
PS> .\Install-Prerequisites.ps1 -WhatIfShows which modules would be installed or updated without doing it.
Permissions, modules and notes#
Author : Omer Eltayeb Blog : https://www.oeltayeb.com GitHub : https://github.com/omer-eltayeb Version : 1.0.0 Requires : PowerShell 5.1 or 7.x, internet access to https://www.powershellgallery.com Permissions : None in Microsoft 365; local admin only when -Scope AllUsers is used Notes : On Windows PowerShell 5.1 make sure TLS 1.2 is enabled for the Gallery (the script sets it for the current session). If PowerShellGet is very old, run 'Install-Module PowerShellGet -Force' first and restart the console.
Full source#
<#
.SYNOPSIS
Installs or updates the PowerShell modules required by the scripts in this repository.
.DESCRIPTION
Checks whether the Microsoft Graph PowerShell SDK authentication module (Microsoft.Graph.Authentication)
and the Exchange Online Management module (ExchangeOnlineManagement) are installed, installs anything
that is missing from the PowerShell Gallery, and optionally updates existing installs to the latest
release. With -IncludeDevTools it also installs PSScriptAnalyzer, which the repository's CI workflow uses.
Nothing is installed without your confirmation unless you pass -Confirm:$false, and -WhatIf shows the
plan without changing anything.
.PARAMETER Scope
Installation scope passed to Install-Module. CurrentUser (default) needs no elevation; AllUsers requires
an elevated session.
.PARAMETER Update
Update modules that are already installed to the newest version available in the PowerShell Gallery.
.PARAMETER IncludeDevTools
Also install PSScriptAnalyzer for local linting.
.EXAMPLE
PS> .\Install-Prerequisites.ps1
Installs any missing module for the current user.
.EXAMPLE
PS> .\Install-Prerequisites.ps1 -Update -IncludeDevTools -Verbose
Installs or updates every module, including PSScriptAnalyzer, and shows what happens along the way.
.EXAMPLE
PS> .\Install-Prerequisites.ps1 -WhatIf
Shows which modules would be installed or updated without doing it.
.NOTES
Author : Omer Eltayeb
Blog : https://www.oeltayeb.com
GitHub : https://github.com/omer-eltayeb
Version : 1.0.0
Requires : PowerShell 5.1 or 7.x, internet access to https://www.powershellgallery.com
Permissions : None in Microsoft 365; local admin only when -Scope AllUsers is used
Notes : On Windows PowerShell 5.1 make sure TLS 1.2 is enabled for the Gallery (the script sets it for
the current session). If PowerShellGet is very old, run
'Install-Module PowerShellGet -Force' first and restart the console.
.LINK
https://learn.microsoft.com/powershell/microsoftgraph/installation
.LINK
https://learn.microsoft.com/powershell/exchange/exchange-online-powershell-v2
#>
#Requires -Version 5.1
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param(
[Parameter()]
[ValidateSet('CurrentUser', 'AllUsers')]
[string]$Scope = 'CurrentUser',
[Parameter()]
[switch]$Update,
[Parameter()]
[switch]$IncludeDevTools
)
$ErrorActionPreference = 'Stop'
#region Main
$requiredModules = @(
[PSCustomObject]@{ Name = 'Microsoft.Graph.Authentication'; Purpose = 'Microsoft Graph sign-in and Invoke-MgGraphRequest' }
[PSCustomObject]@{ Name = 'ExchangeOnlineManagement'; Purpose = 'Exchange Online and Security & Compliance PowerShell' }
)
if ($IncludeDevTools) {
$requiredModules += [PSCustomObject]@{ Name = 'PSScriptAnalyzer'; Purpose = 'Local linting (same rules as the CI workflow)' }
}
# Windows PowerShell 5.1 defaults to older TLS versions that the PowerShell Gallery no longer accepts.
if ($PSVersionTable.PSVersion.Major -lt 6) {
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12
}
$results = foreach ($module in $requiredModules) {
$installed = Get-Module -Name $module.Name -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
$action = 'None'
$versionAfter = $null
try {
if ($null -eq $installed) {
if ($PSCmdlet.ShouldProcess($module.Name, "Install module ($Scope)")) {
Write-Verbose "Installing $($module.Name) ..."
Install-Module -Name $module.Name -Scope $Scope -Repository PSGallery -Force -AllowClobber
$action = 'Installed'
}
}
elseif ($Update) {
$latest = Find-Module -Name $module.Name -Repository PSGallery
if ($latest.Version -gt $installed.Version) {
if ($PSCmdlet.ShouldProcess($module.Name, "Update $($installed.Version) -> $($latest.Version)")) {
Write-Verbose "Updating $($module.Name) from $($installed.Version) to $($latest.Version) ..."
Install-Module -Name $module.Name -Scope $Scope -Repository PSGallery -Force -AllowClobber
$action = 'Updated'
}
}
else {
$action = 'UpToDate'
}
}
else {
$action = 'AlreadyInstalled'
}
}
catch {
Write-Warning "Could not process $($module.Name): $($_.Exception.Message)"
$action = 'Failed'
}
$current = Get-Module -Name $module.Name -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
if ($null -ne $current) { $versionAfter = $current.Version.ToString() }
[PSCustomObject]@{
Module = $module.Name
Purpose = $module.Purpose
Action = $action
Version = $versionAfter
}
}
Write-Host ''
Write-Host 'Prerequisite check' -ForegroundColor Cyan
$results | Format-Table -AutoSize | Out-String | Write-Host
if (@($results | Where-Object { $_.Action -eq 'Failed' -or $null -eq $_.Version }).Count -gt 0) {
Write-Warning 'At least one module is missing. Re-run the script in an elevated session or check your Gallery connectivity.'
}
#endregion Main