Automating Exchange Server Prerequisites
Microsoft Exchange 2019 Prerequisite PowerShell Script

Table of Contents
Fully Automating Exchange Server Prerequisites with a PowerShell Script
If you are planning to install Microsoft Exchange Server 2019 and later, therefore thinking of automating Exchange Server Prerequisites to deploy it quickly. We’ve got you covered.
Installing Microsoft Exchange Server manually consumes a lot of time because you have to download the different software packages from different sources.
After downloading and installing them, you have to install the required Windows features and then extend the schema, prepare AD, and all domains.
Doing this manually takes time, and if you miss anything, Exchange Setup won’t continue and prompt to install the missing feature.
In this guide, I’ll walk you through a fully automated PowerShell script that sets up all necessary components for Exchange Server 2019.
Such as Windows features, .NET Framework, C++ redistributables, UCMA, and URL Rewrite.
This will be done with the help of the Exchange Server 2019 Prerequisites Script, which is a Fully Automated build in PowerShell.
This Exchange PowerShell script is quick, easy, and safe, therefore error-free, for automating Exchange Server prerequisites to quickly deploy the Exchange Server.
What the Script Does to Automatically
Usually, you know that there are multiple software and features that need to be installed prior to installing the Exchange server.
This script will automatically take care of installing the following software and features.
- Installs .NET Framework 4.8
- Installs Visual C++ Redistributables (2012 &2013)
- Installs required Windows Server roles and features
- Installs the URL Rewrite module
- Installs UCMA 4.0
- Ensures you’re ready for Exchange schema/domain prep
Therefore, it also checks if some feature or software is already installed.
However, if it finds the software and feature installed already, it will skip the step and proceed further.
Automatically Prepare Your Domain Controller as Well
As you know, we have to install .NET Framework, C++ Redistributables on the Domain controller as well, along with a few other Windows features.
To automate that, you can run the following script before running the Exchange Server Automating Prerequisites script.
# Active Directory Prerequisites Full Installer
# By Techi Jack
Write-Host "Starting Microsoft Exchange AD Prerequisite Installer..." -ForegroundColor Cyan
# Function to check if a redistributable is installed
function Is-VCRedistInstalled {
param ([string]$DisplayName)
$keys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($key in $keys) {
if (Get-ItemProperty $key -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like "*$DisplayName*" }) {
return $true
}
}
return $false
}
# Function to check .NET Framework 4.8 or later
function Is-DotNetFramework48Installed {
$releaseKey = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Release
return ($releaseKey -ge 528040)
}
# Install .NET Framework 4.8 if not installed
if (-not (Is-DotNetFramework48Installed)) {
Write-Host "Installing .NET Framework 4.8..." -ForegroundColor Cyan
$dotNetUrl = "https://download.microsoft.com/download/2/4/8/24892799-1635-47E3-AAD7-9842E59990C3/ndp48-web.exe"
$dotNetPath = "$env:TEMP\ndp48-web.exe"
Invoke-WebRequest -Uri $dotNetUrl -OutFile $dotNetPath
Start-Process -FilePath $dotNetPath -ArgumentList "/quiet /norestart" -Wait
} else {
Write-Host ".NET Framework 4.8 or newer already installed, skipping..." -ForegroundColor Green
}
# C++ 2012 (x64)
if (-not (Is-VCRedistInstalled -DisplayName "Visual C++ 2012 x64")) {
Write-Host "Installing Visual C++ 2012 x64..." -ForegroundColor Cyan
$vc2012Url = "https://download.microsoft.com/download/1/6/b/16b06f60-3b20-4ff2-b699-5e9b7962f9ae/VSU_4/vcredist_x64.exe"
$vc2012Path = "$env:TEMP\vcredist2012_x64.exe"
Invoke-WebRequest -Uri $vc2012Url -OutFile $vc2012Path
Start-Process -FilePath $vc2012Path -ArgumentList "/install /quiet /norestart" -Wait
} else {
Write-Host "Visual C++ 2012 x64 already installed, skipping..." -ForegroundColor Green
}
# C++ 2013 (x64)
if (-not (Is-VCRedistInstalled -DisplayName "Visual C++ 2013 x64")) {
Write-Host "Installing Visual C++ 2013 x64..." -ForegroundColor Cyan
$vc2013Url = "https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe"
$vc2013Path = "$env:TEMP\vcredist2013x64.exe"
Invoke-WebRequest -Uri $vc2013Url -OutFile $vc2013Path
Start-Process -FilePath $vc2013Path -ArgumentList "/install /quiet /norestart" -Wait
} else {
Write-Host "Visual C++ 2013 x64 already installed, skipping..." -ForegroundColor Green
}
# Define required features
$features = @(
"RSAT-ADDS"
)
Write-Host "Checking and installing Windows prerequisites..." -ForegroundColor Cyan
foreach ($feature in $features) {
$status = Get-WindowsFeature -Name $feature
if ($status.Installed) {
Write-Host "$feature is already installed. Skipping..." -ForegroundColor Yellow
} else {
Write-Host "Installing $feature..." -ForegroundColor Green
Install-WindowsFeature -Name $feature -IncludeAllSubFeature -Verbose
}
}
Write-Host "All AD prerequisites handled successfully." -ForegroundColor Magenta
How to Use the Exchange Prerequisites Automating Script
You can copy the script from the below snippet and save it with any name with a .ps1 extension.
In our case, we saved it inside the script folder on the C drive.
# Exchange Server 2019 Prerequisites Full Installer
# By Techi Jack
Write-Host "Starting Microsoft Exchange Prerequisite Installer..." -ForegroundColor Cyan
# Function to check if a redistributable is installed
function Is-VCRedistInstalled {
param ([string]$DisplayName)
$keys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($key in $keys) {
if (Get-ItemProperty $key -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like "*$DisplayName*" }) {
return $true
}
}
return $false
}
# Function to check .NET Framework 4.8 or later
function Is-DotNetFramework48Installed {
$releaseKey = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Release
return ($releaseKey -ge 528040)
}
# Install .NET Framework 4.8 if not installed
if (-not (Is-DotNetFramework48Installed)) {
Write-Host "Installing .NET Framework 4.8..." -ForegroundColor Cyan
$dotNetUrl = "https://download.microsoft.com/download/2/4/8/24892799-1635-47E3-AAD7-9842E59990C3/ndp48-web.exe"
$dotNetPath = "$env:TEMP\ndp48-web.exe"
Invoke-WebRequest -Uri $dotNetUrl -OutFile $dotNetPath
Start-Process -FilePath $dotNetPath -ArgumentList "/quiet /norestart" -Wait
} else {
Write-Host ".NET Framework 4.8 or newer already installed, skipping..." -ForegroundColor Green
}
# C++ 2012 (x64)
if (-not (Is-VCRedistInstalled -DisplayName "Visual C++ 2012 x64")) {
Write-Host "Installing Visual C++ 2012 x64..." -ForegroundColor Cyan
$vc2012Url = "https://download.microsoft.com/download/1/6/b/16b06f60-3b20-4ff2-b699-5e9b7962f9ae/VSU_4/vcredist_x64.exe"
$vc2012Path = "$env:TEMP\vcredist2012_x64.exe"
Invoke-WebRequest -Uri $vc2012Url -OutFile $vc2012Path
Start-Process -FilePath $vc2012Path -ArgumentList "/install /quiet /norestart" -Wait
} else {
Write-Host "Visual C++ 2012 x64 already installed, skipping..." -ForegroundColor Green
}
# C++ 2013 (x64)
if (-not (Is-VCRedistInstalled -DisplayName "Visual C++ 2013 x64")) {
Write-Host "Installing Visual C++ 2013 x64..." -ForegroundColor Cyan
$vc2013Url = "https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe"
$vc2013Path = "$env:TEMP\vcredist2013x64.exe"
Invoke-WebRequest -Uri $vc2013Url -OutFile $vc2013Path
Start-Process -FilePath $vc2013Path -ArgumentList "/install /quiet /norestart" -Wait
} else {
Write-Host "Visual C++ 2013 x64 already installed, skipping..." -ForegroundColor Green
}
# Define required features
$features = @(
"Server-Media-Foundation", "NET-Framework-45-Features", "RPC-over-HTTP-proxy", "RSAT-Clustering",
"RSAT-Clustering-CmdInterface", "RSAT-Clustering-Mgmt", "RSAT-Clustering-PowerShell", "WAS-Process-Model",
"Web-Asp-Net45", "Web-Basic-Auth", "Web-Client-Auth", "Web-Digest-Auth", "Web-Dir-Browsing", "Web-Dyn-Compression",
"Web-Http-Errors", "Web-Http-Logging", "Web-Http-Redirect", "Web-Http-Tracing", "Web-ISAPI-Ext", "Web-ISAPI-Filter",
"Web-Lgcy-Mgmt-Console", "Web-Metabase", "Web-Mgmt-Console", "Web-Mgmt-Service", "Web-Net-Ext45", "Web-Request-Monitor",
"Web-Server", "Web-Stat-Compression", "Web-Static-Content", "Web-Windows-Auth", "Web-WMI", "Windows-Identity-Foundation",
"RSAT-ADDS", "NET-WCF-HTTP-Activation45", "NET-WCF-Pipe-Activation45"
)
Write-Host "Checking and installing Windows prerequisites..." -ForegroundColor Cyan
foreach ($feature in $features) {
$status = Get-WindowsFeature -Name $feature
if ($status.Installed) {
Write-Host "$feature is already installed. Skipping..." -ForegroundColor Yellow
} else {
Write-Host "Installing $feature..." -ForegroundColor Green
Install-WindowsFeature -Name $feature -IncludeAllSubFeature -Verbose
}
}
# URL Rewrite
$rewriteDll = "$env:SystemRoot\System32\inetsrv\rewrite.dll"
if (-not (Test-Path $rewriteDll)) {
Write-Host "Installing IIS URL Rewrite Module 2.1..." -ForegroundColor Yellow
$urlRewriteUrl = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi"
$urlRewritePath = "$env:TEMP\rewrite_2.1_x64.msi"
Invoke-WebRequest -Uri $urlRewriteUrl -OutFile $urlRewritePath
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$urlRewritePath`" /quiet /norestart" -Wait
Write-Host "URL Rewrite Module installed." -ForegroundColor Cyan
} else {
Write-Host "URL Rewrite already installed, skipping..." -ForegroundColor Green
}
function Is-UCMAInstalled {
$ucmaPath = "C:\Program Files\Microsoft UCMA 4.0"
return (Test-Path $ucmaPath)
}
$UcmaDownloadUrl = "https://download.microsoft.com/download/2/c/4/2c47a5c1-a1f3-4843-b9fe-84c0032c61ec/UcmaRuntimeSetup.exe"
$UcmaInstaller = "$env:TEMP\UcmaRuntimeSetup.exe"
if (-not (Is-UCMAInstalled)) {
Write-Host "UCMA 4.0 not detected." -ForegroundColor Cyan
if (-not (Test-Path $UcmaInstaller)) {
Write-Host "Downloading UCMA installer..." -ForegroundColor Cyan
Invoke-WebRequest -Uri $UcmaDownloadUrl -OutFile $UcmaInstaller -UseBasicParsing
} else {
Write-Host "UCMA installer already exists. Skipping download." -ForegroundColor Yellow
}
Write-Host "Installing UCMA 4.0..." -ForegroundColor Cyan
Start-Process -FilePath $UcmaInstaller -ArgumentList "/quiet" -Wait
Write-Host "UCMA 4.0 installation completed." -ForegroundColor Green
} else {
Write-Host "UCMA 4.0 is already installed. Skipping installation and download." -ForegroundColor Green
}
Write-Host "All prerequisites handled successfully." -ForegroundColor Magenta
- Make sure Windows Server 2019 or 2022 (latest patched)
- Admin rights (Run as Administrator)
- Internet access (to download dependencies
Open PowerShell as an Administrator
Navigate to the script folder and run the script
If you saved the script by the name of ExchangePrerequisites.ps1, run the following command
Example:
c:\scripts> .\ExchangePrerequisites.ps1
Once the script starts, you can follow the screen prompts to check the process.
It will automatically download and install the software and Windows features.
How Automating Exchange Server Prerequisites Helps
- It saves hours of manual configuration
- Avoids missed prerequisites or Exchange Setup errors
- Perfect for lab deployments, production, or consulting work
- Quite safe as it’s a fresh server, so you lose nothing
Quick Troubleshooting Tips
If the script is not running, then set the execution policy first by running the following cmdlet
Set-ExecutionPolicy RemoteSigned -Scope Process
If URL rewrite fails, make sure IIS is installed first
Therefore, if UCMA is not installing, check internet connectivity, or if the URL to the software changes, install it manually.
Note: However, this script will install the IIS feature first, so that URL Rewrite will not prompt for any error
Final Thoughts
If you’re setting up Exchange Server 2019 and want a quick, error-free setup, this script will make your job much easier. Bookmark this page or subscribe to my channel for more Exchange, Proxmox, and Mailcow content.
I hope you will also like some Microsoft Exchange tutorials
How to Renew Exchange Federation Certificate
Exchange Server Health Checker PowerShell Script
Therefore, if you face any issue with your Exchange Server, on-premises, or Hybrid Exchange
Feel free to contact us at info@techijack.com
Moreover, see every step in action, including real-time installation and what each component does.
