-->

Thursday, April 3, 2025

Exchange - 2019 CU15 Install Error mmc.exe and where.exe

I had a customer trying to upgrade their Exchange 2019 Servers from CU14 to CU15 and hit an error during the Management Tools step. The installer complained about the mmc.exe and where.exe files. 

For reference "where.exe" is part of PowerShell. Basically the installer is looking in two places for those two files and they're either missing or corrupt.

Here's the full error:

The following error was generated when "$error.Clear(); 
          if (Test-Path ($Env:SystemRoot + "\system32\mmc.exe")) {Copy-Item -Path ($RoleInstallPath+"Bin\mmc.exe.config") -Destination (Split-Path (where.exe mmc)) -Force}
        " was run: "System.Management.Automation.ParameterBindingException: Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Destination'. Specified method is not supported. ---> System.NotSupportedException: Specified method is not supported.
   at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue)
   --- End of inner exception stack trace ---
   at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue)
   at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameters(UInt32 parameterSets, Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
   at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
   at System.Management.Automation.CommandProcessor.Prepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)".

**Note** This issue happens quite often when installing EXCH Management Tools on Windows 10/11 as well and the fix is the same. I've also seen it with Exchange 2016.

The Fix:

First we need to check if both the where.exe and mcc.exe files exist in the following directories:

\windows\system32

\windows\syswow64

If not, copy them from a working server and run the install again.


If that doesn't work, we'll need to rename the c:\windows\syswow64\mmc.exe to mmc.old by using the TrustedInstaller account.

You can run CMD as TrustedInstaller with psexec:

Grab PsTools - Sysinternals | Microsoft Learn

In an elevated command prompt run: 

psexec -I -s cmd.exe

A new cmd window will open.

Running a “whoami” in that window should show nt authority\system as the user.

Then rename the mmc file like so:

cd c:\windows\syswow64

rename mmc.exe mmc.old

Now run the CU15 install and it should complete!

Tuesday, February 18, 2025

Exchange - Migrating EXCH 2016 to 2019 Guide

Alot of my customers are scrambling to get ready for Exchange SE (Subscription Edition) which requires Exchange 2019 CU14/CU15 for the in-place upgrade. Seriously, I've led 14 migrations in the past 6 months. The reason they're in a hurry is because Exchange 2016/2019 goes End Of Life (EOL) October 14, 2025. Exchange SE has been released. See how very little time there is to perform an upgrade before you're out of support?

Another issue is Microsoft throttles mail flow from out-of-date Exchange Hybrid servers...there's no word yet on when 2019 CU14/CU15 will be throttled, but since it will be EOL, I'd assume it would come pretty quickly after 10/2025.

A word on Edge Servers: if you still have them, and you're in a Hybrid, now would be a great time to get rid of them. Can they be useful? Yeah...sorta. Are they needed in a Hybrid? No! With email, less hops are better, so if you're building new Mailbox Servers, it would be beneficial to update inbound NAT for SMTP (TCP port 25) to point to the Exchange 2019 Mailbox server(s) and remove the unnecessary management and complexity of your environment.

Steps to upgrade Exchange Mailbox Servers and Edge Servers from 2016 to 2019/SE

Network and Directory Server Requirements for Exchange 2019/SE

Component

Requirement

Domain controllers

All domain controllers in the forest need to be running one of the following versions of Windows Server:

 

Windows Server 2025 Standard or Datacenter

 

Windows Server 2019 Standard or Datacenter

 

Windows Server 2016 Standard or Datacenter

 

Windows Server 2012 R2 Standard or Datacenter

Active Directory Forest

The Active Directory Forest functional level is Windows Server 2012 R2 or higher.

Active Directory site

The Active Directory site where you install the Exchange Server must contain at least one writeable domain controller that's also a global catalog server; or else, the installation will fail. Furthermore, you can't install the Exchange server and then remove the domain controller from the Active Directory site.

IPv6

Exchange 2019 supports IPv6 only when IPv4 is also installed and enabled on the Exchange server.

 

If you deploy Exchange in this configuration, and your network supports IPv4 and IPv6, all Exchange servers can send data to and receive data from devices, servers, and clients that use IPv6 addresses.

Exchange Server 2019 system requirements, Exchange 2019 Requirements, Exchange 2019 Memory Requirements, Exchange 2019 Client Compatibility | Microsoft Learn

Hardware Plans for Exchange Server 2019/SE

1. Mailbox Server Role:

·         CPU: Minimum 4 cores (8 cores recommended) at 2.6 GHz or higher

·         Memory: 128 GB RAM (recommended, but not required – can match current EXCH 2016 Server)

·         OS Disk: 120 GB SSD

·         Disk Space: At least 30 GB of free disk space on the drive where Exchange is to be installed, at least 200 MB of free disk space on the system drive, at least 500 MB of free disk space for message queue database.

·         Database and Log Disks: Separate disks for databases and logs, recommended using SSDs or high-performance HDDs

·         Network: 1 Gbps Ethernet (10 Gbps recommended)

 2. Edge Transport Server Role (If Applicable):

·         CPU: Minimum 2 cores (4 cores recommended) at 2.6 GHz or higher

·         Memory: 64 GB RAM (recommended, but not required – can match current EXCH 2016 Server)

·         OS Disk: 120 GB SSD

·         Transport Database Disk: Separate disk for the transport database, SSD recommended

·         Network: 1 Gbps Ethernet (10 Gbps recommended)

Supported operating systems for Exchange 2019/SE

  • Windows Server 2025 Datacenter
  • Windows Server 2022 Standard
  • Windows Server 2019

Virtual Machine Plans

If you are opting for virtual machines, ensure that the virtual environment can support the same specifications as the hardware requirements mentioned above.

**Note** The Exchange Health Checker will flag specific settings when using VMs, pay attention to those call-outs and spec accordingly to avoid performance issues.

Exchange Server virtualization | Microsoft Learn

Exchange and Edge Server Naming Convention.

Per organization.

Prerequisites for Installing Exchange Server 2019/SE Mailbox Servers on Windows Server 2019/2022/2025

From a Domain Controller (AD rights are required)

Prepare Active Directory and Extend the Active Directory schema

The account you use must be a member of the Schema Admins and Enterprise Admins security groups to run /PrepareSchema, and a member of the Enterprise Admins security group to run /PrepareAD.

o   E:\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareSchema

o   E:\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareAD

**Note** If you only have one domain you skip this step, but if your Exchange Servers or recipients live in a child domain, you will need to prep that domain separately:

To prepare all domains, run:

o   E:\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON / /PrepareAllDomains

To target a specific domain, run:

o   E:\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareDomain[:<DomainFQDN>]

On the Exchange Boxes:

1)      Install Other Necessary Components

E    Ensure that the server has the latest updates from Windows Update.

  • The target server must be a member of an Active Directory domain.

    Configure the server with a static IP address.

    Ensure time synchronization with an DC server.

2)      Install the following software:

·         .NET Framework 4.8

·         Visual C++ Redistributable Package for Visual Studio 2012

·         Visual C++ Redistributable Package for Visual Studio 2013

o   Both files will be named vcredist_x64 – best to rename with the version

·         Unified Communications Managed API 4.0

·         IIS URL Rewrite Module


Pre-requisite script (Setup Assist)


Review the optional Setup Assist script to prepare Exchange 2019. This script is provided “as is” and is not supported, so be sure to test this script in your environment before using it in production.

3)      Install Required Windows Roles and Features

Install-WindowsFeature RSAT-ADDS

 Install-WindowsFeature Server-Media-Foundation, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-HTTP-Activation45, NET-WCF-Pipe-Activation45, NET-WCF-TCP-Activation45, NET-WCF-TCP-PortSharing45, 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

IF APPLICABLE - Exchange 2019/SE Edge Transport servers on Windows Server 2019/2022/2025


1)      Install the following software:

a. .NET Framework 4.8

b. Visual C++ Redistributable Package for Visual Studio 2012

c. Run this command from Windows PowerShell

·         Install-WindowsFeature ADLDS

Follow the below documents to install the Exchange and Edge server Step by Step.

Using Unattended mode

Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /mode:Install /r:MB

https://learn.microsoft.com/en-us/exchange/plan-and-deploy/deploy-new-installations/unattended-installs?view=exchserver-2019

**Note** Extended Protection is enabled by default on CU14+. If you do not currently have Extended Protection enabled on Exchange 2016, you need to install 2019 with it off. You must install with the command-line using the following command:

Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /mode:Install /r:MB /DoNotEnableEP

Install Exchange Mailbox servers using the Setup wizard

Install Exchange Mailbox servers using the Setup wizard | Microsoft Learn

Install Exchange Edge Transport servers using the Setup wizard

Install Exchange Edge Transport servers using the Setup wizard | Microsoft Learn


Enter your Exchange Server product key

Enter your Exchange Server product key | Microsoft Learn

**Note** Your Exchange 2019 license key will carry over to SE at this time (CU2 will change that next year)

If you get a pending reboot error, open Regedit and navigate to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

Delete the “PendingFileRenameOperations” key

On Exchange Mailbox Servers

A.      Set Client Access URI:

As soon as your new 2019 server reboots, immediately set it into Maintenance mode to prevent it from causing client warnings. Then, run Set-ClientAccessService -AutoDiscoverServiceInternaluri to either set the SCP URI to $null or align it to your existing Exchange HTTPS namespace https://autodiscover.domain.com/AutoDiscover/Autodiscover.xml so that clients continue to connect to 2016 until you are fully ready to go.

Start Maintenance Mode on a Single Exchange Server:

$Computer = $ENV:ComputerName

Set-ServerComponentState $Computer -Component HubTransport –State Draining -Requester Maintenance

Set-ServerComponentState $Computer -Component ServerWideOffline -State Inactive -Requester Maintenance

Stop Maintenance Mode:

$Computer = $ENV:ComputerName

Set-ServerComponentState $Computer -Component ServerWideOffline -State Active -Requester Maintenance

Set-ServerComponentState $Computer -Component HubTransport -State Active -Requester Maintenance

Restart-Service MSExchangeTransport

Restart-Service MSExchangeFrontEndTransport

Get-ServerComponentState $Computer

 

B.      Configure the URLs on new Servers.

PowerShell commands to set the URLs for various virtual directories on Exchange 2019 servers.

Note: Change "EX19-01" with your new Exchange 2019 Server name, and “mail.domain.com” to match your namespace. Execute these commands on each new Exchange 2019 server.

Set OWA Virtual Directory:

Set-OwaVirtualDirectory -Identity "EX19-01\owa (Default Web Site)" -InternalUrl "https://mail.domain.com/owa" -ExternalUrl "https://mail.domain.com/owa"

Set ECP Virtual Directory:

Set-EcpVirtualDirectory -Identity "EX19-01\ecp (Default Web Site)" -InternalUrl "https://mail.domain.com/ecp" -ExternalUrl "https://mail.domain.com/ecp"

Set ActiveSync Virtual Directory:

Set-ActiveSyncVirtualDirectory -Identity "EX19-01\Microsoft-Server-ActiveSync (Default Web Site)" -InternalUrl "https://mail.domain.com/Microsoft-Server-ActiveSync" -ExternalUrl "https://mail.domain.com/Microsoft-Server-ActiveSync" 

Set OAB Virtual Directory:

Set-OabVirtualDirectory -Identity "EX19-01\OAB (Default Web Site)" -InternalUrl "https://mail.domain.com/OAB" -ExternalUrl "https://mail.domain.com/OAB" 

Set EWS Virtual Directory:

Set-WebServicesVirtualDirectory -Identity "EX19-01\EWS (Default Web Site)" -InternalUrl "https://mail.domain.com/EWS/Exchange.asmx" -ExternalUrl "https://mail.domain.com/EWS/Exchange.asmx" 

Set MAPI Virtual Directory:

Set-MapiVirtualDirectory -Identity "EX19-01\mapi (Default Web Site)" -InternalUrl "https://mail.domain.com/mapi" -ExternalUrl "https://mail.domain.com/mapi" 

Set Outlook Anywhere:

Set-OutlookAnywhere -Identity "EX19-01\Rpc (Default Web Site)" -InternalHostname "mail.domain.com" -ExternalHostname "mail.domain.com" -ExternalClientsRequireSsl $true -InternalClientsRequireSsl $true

Set Client Access URI:

Set-ClientAccessService -Identity "EX19-01" -AutoDiscoverServiceInternalUri https://autodiscover.domain.com/AutoDiscover/Autodiscover.xml.

 

You can also run a script to check and set all virtual directories: PowerShell Script to Configure Exchange Server URLs (practical365.com)

C.      Disable legacy TLS

We strongly recommend disabling TLS 1.0 and 1.1 in your organization as part of your migration. Be sure to read the guidance for this carefully since mistakes can cause problems.

Exchange Server TLS configuration best practices

How to enable Transport Layer Security (TLS) 1.2 on clients

Enable TLS 1.2 on servers

D.      Configure anti-virus exclusions

If deploying file-level scanners on Exchange servers, make sure that the appropriate exclusions, such as directory exclusions, process exclusions, and file name extension exclusions, are in place for both scheduled and real-time scanning.

When configuring antivirus software for Exchange Server, be sure to exclude all the items described here and here. If using Windows Defender, you can use a script we built to make this easier.

 

E.       Export and install the 3rd party SSL certificate on new Exchange Servers.


F.       In the EMS on an Exchange 2016 Server, run:

Get-ExchangeCertificate | Format-Table Subject,Thumbprint

It will list your certs, and you will need the SAN (or public) cert:

Subject                                                   Thumbprint

-------                                                      ----------

CN=mail.domain.com                           BF09E758DF562307138D888697D3A766BDBEBF46

CN=EX16-01                                         C232F4D642F74B9DC7E4ED33D4AB56E68C10CA76

CN=Microsoft Exchange Serve...           411A27BA64FD140523E4D1CF088589C228CA9C5E

CN=WMSvc-SHA2-EX16-01                D894B092E2ABE925E7104A0C9DFF6C448182CA30

G.      Copy the thumbprint and then, run:

$cert = Export-ExchangeCertificate -Thumbprint BF09E758DF562307138D888697D3A766BDBEBF46 -BinaryEncoded -Password (Get-Credential).password

**Note** Change the thumbprint to match the output from step 1.

H.      Then run:

[System.IO.File]::WriteAllBytes('\\EX16-01\C$\Users\<user>\Desktop\mail_domain_com.pfx', $cert.FileData)

**Note** This will export the cert on the desktop of the current server. Change “EX16-01” to the name of your Exchange 2016 Server; change \<user>\ to your username; change mail_domain_com.pfx' to the filename of your preference.

I.         Next, run:

Import-ExchangeCertificate -Server EX19-01 -FileData ([System.IO.File]::ReadAllBytes('\\EX16-01\C$\Users\<user>\Desktop\mail_domain_com.pfx')) -Password (Get-Credential).password  -PrivateKeyExportable $true

**Note** Change “EX1901” to the name of your new Exchange 2019 Server; change “EX1601” to the name of your Exchange 2016 server where you saved the cert file; change \<user>\ to your username; change mail_domain_com.pfx' to the filename you chose in step 3.

J.        Now, assign services on the new server:

Enable-ExchangeCertificate -Server EX19-01 –Thumbprint BF09E758DF562307138D888697D3A766BDBEBF46 –Services IIS,SMTP

**Note** Change the thumbprint to match the output from step 1.

K.       Repeat the Import/enabling on your other Exchange 2019 Mailbox servers.

**Note** This SAN certificate should be Installed and assigned SMTP service on Edge servers as well.

L.       Migrate all the arbitration mailboxes to new Exchange Server

Get-mailbox –Arbitration -Database <Old2016DatabaseNameGoesHere> | New-MoveRequest –TargetDatabase <New2019DatabaseNameGoesHere>

M.    Configure connectors

The next step is to configure Connectors. Send Connectors will carry over from previous Exchange Servers.

Receive connectors

Exchange 2019 has the same default receive connectors as Exchange 2016. Only custom Receive Connectors such as Relay, will need to be re-built.

SMTP relay receive connector

Configure an SMTP relay receive connector on Exchange 2019 with the same configuration as 2016. This is required for any on-premises applications that need to relay emails through Exchange 2019.

**Note** If you use DNS names for relay, you will need to update those records.

We will use this script to Copy a selected receive connector and it's configuration and permissions to other Exchange Servers.

Copy-ReceiveConnector/Copy-ReceiveConnector.ps1 at master · Apoc70/Copy-ReceiveConnector · GitHub

Copy receive connector to another Exchange Server - ALI TAJRAN

Send connectors

Replace the 2016 servers with 2019 servers in the ‘SourceTransportServers’ for Send connectors.

If routing via Edge, use your new 2019 Edge servers as SourceTransport.

In an Exchange hybrid environment, we need to make sure that TLSCertificateName is configured correctly on our Connectors in both Exchange Server and Exchange Online. The Hybrid Configuration Wizard (HCW) is responsible for making the required changes on hybrid connectors.

Run in Exchange Management Shell

**Note** These two cmdlets will show you all the Send and Receive Connectors that currently use a TLS Certificate.

Get-ReceiveConnector | ? TlsCertificateName -ne $null | FL Identity,TlsCertificateName

Get-SendConnector | ? TlsCertificateName -ne $null | FL Identity,TlsCertificateName

Check the TLS Certificate Name for the new certificate

$cert = Get-ExchangeCertificate -Thumbprint "‎ef 7a 47 18 fa 6e c1 f6 05 61 c2 cc 9e 37 42 a2 93 10 d0 67"

$tlscertificatename = "<i>$($cert.Issuer)<s>$($cert.Subject)"

If the TLS Certificate Name changes, you can use these commands to set the new TLS Cert Name on the Send/Receive Connectors

Get-ReceiveConnector | ? TlsCertificateName -ne $null | Set-ReceiveConnector -TlsCertificateName $tlscertificatename

Get-SendConnector | ? TlsCertificateName -ne $null | Set-SendConnector -TlsCertificateName $tlscertificatename

If Applicable:

Subscribe Exchange 2019 Mailbox server with new 2019 Edge servers

Required ports:

Port 50636 should be opened from mailbox toward edge

Port 25 should be opened both directions

I.        Export XML file from edge transport server:

New-EdgeSubscription -FileName "C:\Temp\Edge2019Subscription.xml"

 

II.      Copy XML file from Edge to Mailbox server and run the below command. Kindly ensure that path is correct where you have saved the XML file.

New-EdgeSubscription -CreateInboundSendConnector $false -CreateInternetSendConnector $false -FileData ([byte[]]$(Get-Content -Path "C:\Temp\EdgeSubscriptionInfo.xml" -Encoding Byte -ReadCount 0)) -Site "Enter the site name"

**Note** Change “Enter site name” with your AD site

III.    Restart the Microsoft Exchange EdgeSync service on mailbox server

 

IV.    Run the below command from a mailbox server.

Start-edgesynchronization

Test-edgesynchronization

Procedures for Edge Subscriptions | Microsoft Learn

Run HCW and mark 2019 servers as Hybrid Servers.

Download, install and run the HCW from one of the new Exchange 2019 servers.

Exchange Hybrid Configuration Wizard step by step guide

HCW Choose Exchange Hybrid Configuration feature | Microsoft Learn

Send a Test Email to Check Relay

  1. Open Exchange Management Shell (EMS):
    • Launch the EMS on your Exchange 2019 server.
  1. Use the Send-MailMessage Cmdlet:
    • The Send-MailMessage cmdlet can be used to send a test email. Here’s an example command:
    • Send-MailMessage -From "test@yourdomain.com" -To "recipient@externaldomain.com" -Subject "Test Email" -Body "This is a test email to check relay." -SmtpServer "your.smtp.server"

Replace the placeholders with appropriate values:

      • test@yourdomain.com: The email address you are sending from.
      • recipient@externaldomain.com: The email address you are sending to.
      • your.smtp.server: The SMTP server address of your Exchange 2019 server.
  1. Verify the Email:
    • Check the recipient’s inbox to ensure the test email was received.
    • Review the mail flow logs on your Exchange 2019 server to confirm the email was relayed correctly.

 Run the Exchange Server Health Checker

Health Checker identifies potential critical issues. We strongly recommend running it and thoroughly review its findings. You should implement all recommendations to avoid potential outages or performance issues. Health Checker isn’t just for migration. It’s for ongoing management of Exchange Server. Keep it handy, as it is one of your most valued admin tools.

Helpful Documents.

Upgrading your organization from current versions to Exchange Server SE - Microsoft Community Hub

Exchange On-Premises Best Practices for Migrations from 2010 to 2016 - Microsoft Community Hub

Best Practices for Migrating from Exchange Server 2013 to Exchange Server 2019 - Microsoft Community Hub

Remove legacy Exchange versions

Decommissioning Exchange Server 2016 | Microsoft Community Hub

Decommissioning Exchange Server 2013 | Microsoft Community Hub