Recently and in an effort to improve PowerShell performance for those connecting to Exchange Online, Microsoft released a series of cmdlets they are referring to as ExO v2. What you will find is that the cmdlets are NOT a complete rewrite of the entire set of cmdlets used for managing Exchange Online. They are however a rewrite of some of the most used and most intensive cmdlets that were VERY prone to timing out, getting throttled and generating all sorts of headaches while using them in a tenant. Some notes on these cmdlets can be found here:
Release Notes Here
Purpose
In this blog article, we will cover the basic requirements to just get the new module downloaded and on your computer. Then in the spirit of using PowerShell to solve issues, we’ll review PowerShell code that was written to make sure that the server or workstation you are on, is able to load the new module without issues.
Requirements: (as of the writing of this article)
- NuGet (Latest) – version 2.8.5.201
[Description] - PSGallery – Trusted as a PowerShell repository
[Description] - PackageManagement – Version 1.4.5+
[Description] - PowerShellGet – Version 2.0.0.0+
[Description]
How to vet these requirements:
The requirements listed above are listed in order and its order was derived by testing each component individually working backward from the new Exchange Online module and falling back as far as NuGet because a workstation was not updated at all and this was the base requirement for making this process work. Which, if translated, means that I tried to work with the new Exchange Online module on a new server and had to run into errors and install issues in order to come up with a smooth installation process. Then try the whole process once more on multiple servers to make sure I could actually perform the same steps consistently. The biggest hurdle is that with all the prerequisites, we need to close the PowerShell Window and reopen it in order to install the new cmdlet module and then import it into this new Window.
The Code
Below are the code blocks that are used to install each requirement and if the requirement is already met, a ‘[Passed]’ indicator is thrown. Each section is independent of the other, however they must be run in order for the process to work properly.
Nuget (most recent version) Install
# Prerequisite One: Upgrade NuGet PowerShell Module if needed:
$PackageProviders = (Get-PackageProvider -ListAvailable).Name
If ($PackageProviders -NotContains 'NuGet'){
Write-Host ' * Installing NuGet Package Provider ...' -ForegroundColor Yellow
Try {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$False
} Catch {
Write-Host 'Cannot update NuGet PowerShell module...' -ForegroundColor Yellow
Write-Host ' ... Exiting ...'-ForegroundColor Red
Break
}
} Else {
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite One: NuGet Module Check' -ForegroundColor White
}
Set PSGallery to a Trusted PowerShell gallery
# Prerequisite Two: Set PSGallery Repository to Trusted:
$GalleryPolicy = (Get-PSRepository -Name "PSGallery").InstallationPolicy
If ($GalleryPolicy -eq 'Untrusted') {
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted -ErrorAction STOP
$GalleryPolicy = (Get-PSRepository -Name "PSGallery").InstallationPolicy
If ($GalleryPolicy -eq 'Trusted') {
# Write-Host 'PASSED' -ForegroundColor Green -NoNewLine
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite Two: PSGallery Trusted Check' -ForegroundColor White
}
} Else {
# Write-Host 'PASSED' -ForegroundColor Green -NoNewLine
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite Two: PSGallery Trusted Check' -ForegroundColor White
}
Upgrade the Package Management Module if needed
# Prerequisite Three: PackageManagement is 1.4.5 or greater
Try {
$PackageManagementTest = Get-Package PackageManagement -MinimumVersion 1.4.5 -ErrorAction STOP
} Catch {
$PackageManagementTest = $Null
}
# If ([string]::IsNullOrWhiteSpace($PackageMgmtCheck)) {
If ([string]::IsNullOrWhiteSpace($PackageManagementTest)) {
# Resolve version issue:
Remove-Module PowerShellGet
Remove-Module PackageManagement
Install-Module PackageManagement -Force -SkipPublisherCheck
Import-Module PackageManagement
}
# $PostPackageMgmtCheck = Find-PackageProvider PackageManagement -MinimumVersion 1.4.5
Try {
$PackageManagementTest = Get-Package PackageManagement -MinimumVersion 1.4.5 -ErrorAction STOP
} Catch {
$PackageManagementTest = $Null
}
If ([string]::IsNullOrWhiteSpace($PackageManagementTest)) {
Write-Host 'PowerShellGet Upgrade Failed. Exiting ....' -ForegroundColor Yellow
Break
} Else {
# Write-Host 'PASSED' -ForegroundColor Green -NoNewLine
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite Three: PackageManagement Module Check' -ForegroundColor White
}
Upgrade the PowerShellGet Module if needed
# Prerequisite Four: PowerShell Get is 2.0.0.0 or newer:
$PSGetVerMajor = [int32]((Get-Module PowerShellGet).Version).Major
$PSGetModuleUpdate = $True
$PSGetUpdateRun = $True
If ($PSGetVerMajor -lt 2) {
Write-Host ' * Updating the PowerShellGet module which is required to download the ExO v2 module.' -ForegroundColor Green
Try {
Update-Module PowershellGet -ErrorAction Stop
} Catch {
$PSGetUpdateRun = $False
}
# If Update fails, then try to install instead:
$PSGetVerMajor = [int32]((Get-Module PowerShellGet).Version).Major
If ($PSGetVerMajor -lt 2) {
Remove-Module PowerShellGet
Remove-Module Packagemanagement
$PSGetModuleUpdate = $True
Try {
Install-module PowerShellGet -MinimumVersion 2.0.0.0 -Force -Confirm:$False -SkipPublisherCheck -ErrorAction STOP
} Catch {
Write-Host "Error message - $_.Exception.Message" -ForegroundColor Yellow
$PSGetModuleUpdate = $False
}
}
$PSGetVerMajor = [int32]((get-module PoweRshellGet).Version).Major
If ($PSGetVerMajor -lt 2) {
# Write-Host 'PASSED' -ForegroundColor Green -NoNewLine
write-host '[' -ForegroundColor Yellow -NoNewLine;Write-Host 'FAILED' -ForegroundColor Red -NoNewline;Write-Host ']' -ForegroundColor Yellow -NoNewLine
Write-Host ': Prerequisite Four: PowerShellGet Check.' -ForegroundColor White -NoNewLine
Write-Host ' Try to close the PowerShell window and try once more, or update PowerShellGet manually.' -ForegroundColor Yellow
} Else {
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite Four: PowerShellGet Check' -ForegroundColor White
$PSGetUpdateRun = $False
}
} Else {
write-host '[' -ForegroundColor Cyan -NoNewLine;Write-Host 'PASSED' -ForegroundColor Green -NoNewline;Write-Host ']' -ForegroundColor Cyan -NoNewLine
Write-Host ': Prerequisite Four: PowerShellGet Check' -ForegroundColor White
$PSGetUpdateRun = $False
}
If (!$PSGetModuleUpdate){
Write-Host 'PowerShellGet module upgrade failed, please fix manually or rerun this script to try again.' -ForegroundColor Yellow
Write-Host 'Exiting ....' -ForegroundColor Red
Break
}
IF ($PSGetUpdateRun) {
Write-Host ''
Write-Host '** Please perform the following steps:' -ForegroundColor Green
Write-Host '--------------------------------------' -ForegroundColor White
Write-Host '(1) Close this PowerShell window' -ForegroundColor Yellow
Write-Host '(2) Open a new PowerShell window as an Administrator' -ForegroundColor Yellow
Write-Host '(3) Run this script again' -ForegroundColor Yellow
Start-Sleep 10
Break
}
Sample Run Through
If all of the requirements are installed, we should see all checks pass with flying colors:
Otherwise on the first run we may see this:
Which could require a second run depending on the server:
When the prerequisites are completely installed, close the PowerShell window, reopen it and rerun the script and now all the prerequisites are all completed:
