Latest version: 3.9, February 15th, 2024
I’m pleased to announce the availability of Install-Exchange15.ps1, a PowerShell script to perform a fully automated unattended setup of Exchange Server 2013, Exchange Server 2016, or Exchange Server 2019 (Desktop and Core) is supported).
The script takes care of:
- Installing requires Windows Server features
- Install Exchange Server prerequisites, e.g., .NET Framework 4.5.2/4.6.1/4.6.2/4.7.1/4.7.2/4.8/4.8.1 and Visual C++ Runtime 2012 or 2013, depending on roles, OS, and Exchange version to install.
- Install additional prerequisites and prepare Active Directory.
- Optionally install Exchange Server 2013 / 2016 / 2019.
- Optionally, install required fixes and perform post configuration, like setting your Power Plan to High Performance, reconfiguring the pagefile to best practices (memory + 10MB with a maximum of 32GB+10MB) if it is system managed, and performing .NET framework optimizations. Custom post-configuration is possible by modifying the script.
- On Windows Server 2016 and later, it will configure Windows Defender exclusions when present.
- For Exchange 2016 CU22 and Exchange 2019 CU11 and later, will install the required URL Rewrite 2 module.
- Finally, the script will clean things up, like removing the state file and setting the startup of Transport Service back to Automatic.
Usage
This script version requires a domain-joined Windows Server, an account to perform the installation (and optionally prepare Active Directory), and the location where the Exchange Server 2013/2016/2019 installation files are stored (e.g., a UNC path).
The syntax is as follows:
Install-Exchange15.ps1 -[InstallMultiRole|InstallMailbox|InstallEdge|InstallCAS|NoSetup|Recover] [-Organization <string>] [-MDBName <string>] [-MDBDBPath <string>] [-MDBLogPath <string>] [-InstallPath <string>] [-SourcePath <string>] [-TargetPath <string>] [-Credentials <pscredential>] [-IncludeFixes] [-NoNet461] [-NoNet471] [-NoNet472] [-NoNet48] [-NoNet481] [-DoNotEnableEP] [-DoNotEnableEP_FEEWS] [-UseWMF3] [-DisableSSL3] [-DisableRC4] [-DiagnosticData] [-SCP <string>] [-EdgeDNSSuffix <string>] [-Lock] [-SkipRolesCheck] [-AutoPilot] [<CommonParameters>]
Install-Exchange15.ps1 -InstallMultiRole -SourcePath <string> [-Organization <string>] [-InstallPath <string>] [-TargetPath <string>] [-AutoPilot] [-Credentials <pscredential>] [-IncludeFixes] [-NoNet461] [-NoNet471] [-NoNet472] [-NoNet48] [-NoNet481] [-DoNotEnableEP] [-DoNotEnableEP_FEEWS] [-UseWMF3] [-DisableSSL3] [-DisableRC4] [-DiagnosticData] [-Lock] [-SkipRolesCheck] [-Phase <int>] [<CommonParameters>]
A short description of the parameters:
- Organization (optional): Specifies the name of the Exchange organization to create. When omitted, the step to prepare Active Directory (PrepareAD) will be skipped.
- InstallMailbox: Specifies you want to install the Mailbox server role. This applies to Exchange 2013 as well as Exchange 2016.
- InstallCAS: Specifies you want to install the CAS role. This applies to Exchange 2013 only, ignored when installing Exchange 2016.
- InstallMultiRole: Specifies you want to install both Mailbox server and CAS roles. Applies to Exchange 2013 only.
- InstallEdge: Specifies to install the Edge Transport rule (Exchange 2013/2016).
- MDBName (optional): Specifies the name of the initially created database.
- MDBDBPath (optional): Specifies the database path of the initially created database (requires MDBName).
- MDBLogPath (optional): Specifies the log path of the initially created database (requires MDBName).
- InstallPath (optional): Specifies (temporary) location of where to locate – and when downloaded store – prerequisite files, the state file, and log files. The default location is C:\Install. You can also use a UNC path to use a central location, given the credentials have sufficient permissions to write at this location. This is ideal when you want the script to use previously downloaded hotfix files, for example, as some required hotfixes are quite large (e.g. KB3206632 for WS2016 ~ 1GB, KB2919355 for WS2012R2 ~ 700MB).
- NoSetup (optional): Specifies you only want to install prerequisites (and optionally prepare the Exchange organization), Exchange setup and post-configuration steps are not performed. You still need to specify SourcePath because the Exchange version will determine the prerequisites to install.
- Recover: Specifies you want to install this server in Recovery mode. The script will check if an Exchange server object is already defined.
- SourcePath: Specifies the location of the Exchange 2013 installation files. This can point to the location of setup.exe, or you can specify the Exchange ISO file.
- TargetPath: Specifies the location where to install the Exchange 2013.
- AutoPilot (switch): Specifies you want to automatically restart, log on using the credentials specified, and continue the installation. When not specified, you will need to restart, log on, and start the script manually each time (without parameters).
- Credentials (optional): Specifies credentials to use for automatic logon. Use DOMAIN\User or user@domain. When not specified, you will be prompted to enter credentials.
- IncludeFixes (optional): Depending on the operating system and detected Exchange version to install, will download and install recommended hotfixes.
- DiagnosticData (optional): This switch determines the initial Data Collection mode for deploying Exchange 2019 CU11, Exchange 2016 CU22, or later builds.
- DoNotEnableEP Do not enable Extended Protection on Exchange 2019 CU14+
- DoNotEnableEP_FEEWS Do not enable Extended Protection on the Front-End EWS virtual directory on Exchange 2019 CU14+
- SCP (optional) allows you to reconfigure the Service Connection Point record for Autodiscover after the Exchange setup has finished. Specify the full URI, e.g. https://autodiscover.contoso.com/autodiscover/autodiscover.xml. Use ‘-‘ to clear the SCP entries of the server.
- Lock (optional) locks the system when running script.
- NoNet481 (optional) prevents installing .NET Framework 4.8.1 and uses 4.8 when deploying Exchange 2019 CU14+
- NoNet48 (optional) to use .NET Framework 4.7.2, even when installing an Exchange version that is supported with .NET Framework 4.8.
- NoNET471 (optional) to use .NET Framework 4.6.2, even when installing an Exchange version which is supported with .NET Framework 4.7.1.
- NoNET472 (optional) to use .NET Framework 4.7.1, even when installing an Exchange version which is supported with .NET Framework 4.7.2.
- NoNET461 (optional) to use .NET Framework 4.5.2, even when installing an Exchange version which is supported with .NET Framework 4.6.1 or higher.
- DisableSSL3 (optional) to disable SSL3 protocol as per KB187498.
- DisableRC4 (optional) to disable RC4 cipher as per KB2868725.
- SkipRolesCheck (optional) to bypass membership checks for Schema Admin and Enterprise Admin roles.
- EdgeDNSSuffix specifies the DNS suffix to configure on the primary NIC.
Note that the script uses an XML file to store the (original) parameters used to start the script but also to keep track of the the process. Of course, if required, you can use predefined XML files to run the script without parameters.
Note that when not present, the script will try to download the prerequisites from the internet. When that isn’t possible or to save bandwidth, you can put them in the location defined by InstallPath and the script will detect and use them.
The post-configuration is currently adding IFilters for OneNote and Publisher (Mailbox) only. There are comments in the script where to add your own additional post-configuration steps.
For example, assume we want to start a fully unattended install of an Exchange Server 2013 Client Access server, using a network location for the Exchange Server 2013 source files. After setting the Execution Policy to Unrestricted and storing the script locally, we start the script using:
.\Install-Exchange15.ps1 –InstallCAS –SourcePath
'\\server\share\isos\Microsoft\Exchange2013\mu_exchange_server_2013_x64_dvd_1112105'
–AutoPilot –Verbose
The script will perform some checks and since AutoPilot was specified without using the Credentials parameter, the script will ask for credentials.

After entering the credentials, the required features will be installed. Since OrganizationName wasn’t specified, Active Directory preparation will be skipped.

After rebooting, the system will automatically log on using the credentials specified earlier and start the script (RunOnce registry key is utilized for this purpose). It will read the last known state from the XML file and will continue with the next phase, which is downloading (when not present) and installing the Exchange prerequisites.

Next, after rebooting and the automatic logon, Exchange will be installed from the source location.

When done, the system will perform post-configuration and finalization steps.
When running in AutoPilot mode, the system will automatically perform reboots and logons between the steps. Note that it may seem like a lot of reboots, but rebooting after installing Windows features and Exchange prerequisites is required anyway, so I also put reboots after the other milestones.
Customization
If you want to perform post-setup configuration of Exchange running Exchange cmdlets from the script, you need to tailor it to your needs. Locate the line which reads:
#Load-ExchangeModule
Uncomment this line so a proper Exchange Management Shell session will be set up to the local Exchange server. You can insert Exchange-related cmdlets after the Load-ExchangeModule line to configure your server. Be advised that you need to port modifications to new versions of the installation script.
Recovery
The script also supports recovery mode (/mode:RecoverServer). After checking the Exchange server object is present in Active Directory, installation will proceed as normal, with the exception of running setup in recovery mode. For example:
.\Install-Exchange15.ps1 -Recover -Autopilot -SourcePath \server1\sources\ex2019cu13.iso
Update
The script also supports update mode (/mode:Update). After checking the Exchange server object is present in Active Directory, and checking for presence of Exchange installation, installation will proceed as normal, with the exception of running setup in Update mode.
Feedback
Feedback is welcomed through the comments. If you have scripting suggestions or questions, do not hesitate to use the contact form.
Download
You can download Install-Exchange15.ps1 from TechNet or GitHub.
Revision History
See Technet Gallery page.

Good job Michel.
LikeLike
Thanks
nice script to save time
LikeLike
I saw your “TODO” in the script and figure this could help:
http://www.powershellmagazine.com/2013/02/15/pstip-validating-active-directory-user-credentials/
LikeLike
Thanks!
LikeLike
Great works!
Thanks Michel
LikeLike
Pingback: Microsoft Exchange Server 2013 Unattended Installation Script - Mark Fugatt - Exchange and OCS Blog - Site Home - TechNet Blogs
Pingback: NeWay Technologies – Weekly Newsletter #31 – February 21, 2013NeWay | NeWay
Hi Michael
filter office pack and sp1 aren’t required for 2013
you can remove them from the script(its a TechNet error for basic office filtering not required)
LikeLike
They are part of the official requirements. So, until that changes I’m inclined to leave them in there. People are free to comment them out in the installation script.
LikeLike
great:)
you know who writes those docs right?
well, this is what he said…
Scott Schnoll
January 14, 2013 at 20:49
The Office Filter packs are not needed on Exchange 2013. The Search Foundation component includes all of the filters for Office already. I would also use the /InstallWindowsComponents setup switch and skip the manual installs of IIS and related components.
check the bottom here:
http://www.jaapwesselius.com/2013/01/04/installing-exchange-server-2013part-i/
LikeLike
Pingback: The UC Architects » Episode 18: Get Us Drunk, and We’re Yours!
Great job done.
LikeLike
Pingback: Spr33 » Microsoft Exchange Server 2013 Unattended Instal Script
Pingback: Exchange 2013 Unattended Installation Script (Updated) | EighTwOne (821) | JC's Blog-O-Gibberish
Hi.. Great Job and thank you for sharing this.
I´m getting following error…
C:\Install\Install-Exchange2013.ps1 : Unexpected OS Version (6.2)
In Zeile:1 Zeichen:1
+ .\Install-Exchange2013 -Organization ‘EXLAB’ -InstallMailbox -MDBDBPath ‘D:\DB1’ …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Install-Exchange2013.ps1
LikeLike
Current version WS2012 only; WS2008R2 in the works ..
LikeLike
Hi Michael,
i´m running Windows 2012 Server Standard.
PS C:\Users\administrator.EX13> Get-WmiObject Win32_OperatingSystem | Select Version
Version
——-
6.2.9200
Any ideas?
LikeLike
I figured it out. I had to put 6.2 in the Switch section in quotation marks. Now the script is running….
LikeLike
That shouldn’t be necessary .. English WS2012 OS?
LikeLike
German OS.
LikeLike
New version should be good for your OS:
LikeLike
Pingback: Installing Exchange 2013 prerequisites | Andy Heywood Online
I am having problems with the script when installing from a newly built 2012 server it fails to install the UCMA 4.0 runtime as the windows feature Server-Media-Foundation is not getting installed before UCMA 4.0 and it seems to be a prerequisite for this even though its not published. Have you seen this before?
LikeLike
Using the latest script? Does it have (direct) internet access? If not, put the prerequisites in the installation folder (they will be picked up from there). I let Exchange setup install the Windows features etc. I haven’t seen it before; are you installing separate Mailbox roles only?
LikeLike
I have downloaded all the prerequisite files manually and it launches the ucma 4.0 setup but then fails and when I manually run the ucma 4.0 setup it tells me I am missing the windows feature ‘media foundation’. This is before the exchange setup part of your script so the /installwindowsfeature isn’t relevant.
I got around it by un-commenting out the windows feature install of your script and adding server-media-foundation into that list of features.
LikeLike
Of course; I will publish an update after I return from vacation (no RDP to home lab atm for testing).
LikeLike
Updated script: https://eightwone.com/2013/05/14/exchange-2013-unattended-installation-script-v1-1
LikeLike
Thanks for the script! I ran into a couple snags. One being the UCMA issue that you appear to be aware of. The other was that the Exchange installation was failing due to the ‘ol DiscoverySearchMailbox problems. The problem is the script wasn’t providing any visibility into the fact that the installation wasn’t completing successfully. As far as it knew everything went through fine, but the ClientAccess role wasn’t being installed (and I think the mailbox role was only partially installed).
I was able to launch setup through the GUI and it gave me the errors which I could then troubleshoot.
On an unrelated note – would it be possible to provide an option to NOT uninstall RSAT-ADDS-Tools after completion? 🙂
LikeLike
Updated script: https://eightwone.com/2013/05/14/exchange-2013-unattended-installation-script-v1-1
LikeLike
Pingback: Exchange 2013 Unattended Installation Script v1.1 | EighTwOne (821)
Pingback: Exchange 2013 Unattended Installation Script v1.5 | EighTwOne (821)
Greetings! I know this is somewhat off topic but I was wondering if
you knew where I could get a captcha plugin for my comment form?
I’m using the same blog platform as yours and I’m having problems finding one?
Thanks a lot!
LikeLike
Excellent script Michel!
LikeLike
Note: There looks to be a PowerShell v2 bug (as it works as expected in PSv3, ie WS2012). Cause is that on WS2008R2, you can’t either specify InstallCAS or InstallMailbox, only both. Apparantly, PSv2 can’t figure out what parameter set to use (should use “CM” variant) so it ends in AmbigiousParameterset. Note that when running help .\Install-Exchange2013.ps1 is shows that only specifying InstallMailbox or InstallCAS is a valid syntax. Standby while I look for a suited workaround.
LikeLike
Hi
To day I found this link and downloaded the script.
Im testing the script with server2012 but get stuck with this error, how do I get around it
Checking Forest Functional Level
The following exception occurred while retrieving member “get”: “Unknown error (0x80005000)”
At C:\install\Install-Exchange2013.ps1:411 char:15
+ return( ([ADSI]”LDAP://cn=partitions,cn=configuration,$RootDSE”).get(“ms …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : CatchFromBaseGetMember
Check-Sanity : Forest is not Functional Level 2003 or later
At C:\install\Install-Exchange2013.ps1:906 char:5
+ Check-Sanity
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Sanity
LikeLike
Seems like an AD issue. Is the system domain joined? Are you logged on using a domain account?
LikeLike
Hi, yes you have right, was logged on with wrong account, it seems to work now.
on this site you say that version 1.55 is the latest but if open the script it say’s 1.54 is that correct or is it a typo in the script file.
Thank’s for your answer
Robban
LikeLike
Thanks for catching that. Forgot to update header. Corrected; please use the the 1.55 one to prevent confusion.
LikeLike
Regarding “KB2758857: Insecure library loading could allow remote code execution (supersedes KB2533623)” – it supersedes KB2533623 for W2008 only, not for W2008R2.
And the Exchange prerequisites page still says KB2533623 is required.
LikeLike
To check if this feature is installed, you should use
If( ! (Get-WindowsFeature $Feat).Installed )
instead of
If( !( Get-WindowsFeature ($Feat)))
Also, (at least for some features) reboot was required before they showed up as installed.
Great script, thanks!
LikeLike
Thanks. On your remark: No – Get-WindowsFeature returns both features installed and available to be installed; I need to know if it’s installed or not.
LikeLike
Great script!
I installed a Exchange 2013 server with this script today and after the install i wanted to apply CU2
i got the following 3 errors
RSAT-Clustering-CmdInterface
FilterPack64bit
filterpack2010sp1-kb2460041-x64-fullfile-en-us
are not installed.
Can you please fix this
thnx
LikeLike
Filterpacks aren’t required. What version are you trying to install, RTM/CU1? If so, why? You can install CU2 immediately, no need install RTM first then upgrade.
LikeLike
Michel,
I installed RTM and then tried to upgrade to CU2 (yes i know next time install CU right away, but i forgot that CU2 was released) and de setup from CU2 gave me the error that i need to istall the 3 components above
LikeLike
If I recall correctly, the filter packs will only result in a warning. They aren’t required. That issue with RSAT-Clustering-CmdInterface is a bit of quirk (it’s not required with fresh CU2 installs, just confirmed as I’m reinstalling some of my lab servers atm)
LikeLike
Maybe it is just me but i wasn’t able to update to CU2
if you have time install a RTM with the script and try to install CU2
LikeLike
Pingback: Exchange Server 2013 CU2 Service Templates for Virtual Machine Manager - Building Clouds Blog - Site Home - TechNet Blogs
This is a great script. As FYI, it fails if there are spaces in the arguments, such as in the MDB path or the Exchange setup path. Once I removed them, it worked fine.
LikeLike
Parameter values which contain spaces should be quoted.
LikeLike
Pingback: Exchange 2013 Unattended Installation Script (Updated) | EighTwOne (821) | JC's Blog-O-Gibberish
Great script Michel.
Can you please check the spaces?
TargetPath ‘D:\Program Files\Microsoft\Exchange Server\V15’
but installed in: D:\Program,Files\Microsoft\Exchange,Server\V15
LikeLike
Thanks for the heads-up!
LikeLike
Hi Michel, see below log details. Please note the LogFolderPath is also incorrect: Command Line:./Install-Exchange2013.ps1 -InstallMultiRole -MDBName DAG01_DB01 -MDBDBPath D:\DAG_01\DB -MDBLogPath D:\DAG_01\Log -SourcePath D:\Install\E2K13CU3 -TargetPath ‘D:\Program Files\Microsoft\Exchange Server\V15’ -AutoPilot -Credentials $Cred -IncludeFixes -Verbose Transcript started, output file is C:\Install\Install-Exchange2013.ps1_20140215102622.logVERBOSE: Disabling File Security Warning dialogVERBOSE: Disabling Automatic LogonChecking for pending reboot ..VERBOSE: Current phase is 4 of 6Installing Exchange 2013Installing Microsoft Exchange Server 2013VERBOSE: Executing D:\Install\E2K13CU3\setup.exe /mode:install /roles:Mailbox,ClientAccess /IAcceptExchangeServerLicenseTerms /InstallWindowsComponents /MdbName:DAG01_DB01 /DBFilePath:”D:\DAG_01\DB\DAG01_DB01.edb” /LogFolderPath:”D:\DAG_01\Log\DAG01_DB01\Log” /TargetDir:D:\Program Files\Microsoft\Exchange Server\V15 /DoNotStartTransportInstall-Exchange2013_ : Problem installing At D:\Install\Install-Exchange2013.ps1:943 char:13+ Install-Exchange2013_+ ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Install-Exchange2013_ **********************Windows PowerShell transcript endEnd time: 20140215103102********************** Regards,Franck Date: Sat, 15 Feb 2014 09:37:26 +0000To: franckwolf@hotmail.comFrom: comment-reply@wordpress.comSubject: [New comment] Exchange 2013 Unattended Installation Script (Updated)
WordPress.com
Michel de Rooij commented: “Thanks for the heads-up!”
LikeLike
Sadly unable to make this work at all. Brand new 2012 R2 server with Exchange 2013 SP1, doesn’t have access to the Internet so have saved UCMA locally.
Running as Autopilot, runs once, reboots machine, runs through script again, then reboots … Nothing happens.
Re-run script manually, reboots machine … Nothing happens.
Re-run script manually, actually installs UCMA, reboots … Nothing happens.
Would appear that the pre-requisites in particular the Windows Features never install, as a result of not being connected to the Internet.
LikeLike
When doing an “offline” install, make sure you put the requirement components in the folder you specified with InstallPath (default C:\Install) – it will pick them up from there. The “Windows Features” come with the Operating System, and should be able to install regardless. Currently, for WS2012R2 the required files are (you could distill them from the script as well):
* NDP451-KB2858728-x86-x64-AllOS-ENU.exe
* UcmaRuntimeSetup.exe
* FilterPack64bit.exe
* filterpack2010sp1-kb2460041-x64-fullfile-en-us.exe
Note: The Filter Pack files need only to be present when you specify InstallFilterPack.
I’ll make a note of perhaps checking for the existence of these files upfront, as it will now – as you found out- abort halfway when it can’t download or find the file/patch. Note that the log file contains information on the reason of prematurely ending the installation. When the script has aborted and you want to continue running it, just kick it off from an elevated PowerShell prompt; no need to include any parameters except for InstallPath if you selected a different path than the default one.
LikeLike
Thanks Michel, didn’t think NDP451-KB2858728-x86-x64-AllOS-ENU.exe was required for WS2012R2.
Also possible that due to being an offline installation that the windows features being called by the exchange setup is failing as well as they don’t have a source specified.
LikeLike
Not required, but highly recommended (alternative is 4.5 with a set of hotfixes only available through support).
Installing Windows features does not require original source files (like in early versions of Windows)
LikeLike
Still having issue here whereby the autopilot function doesn’t rerun after reboot the server … and I have to re-run the script at every single stage. Win2013R2SP1.
LikeLike
Check if the credentials provided are working (used to automatically log on) in the event log. Otherwise, when the XML is still there (in the InstallPath), it will re-use it so throw it away when you want to have another ‘fresh’ go.
LikeLike
It automatically logs me in without issue, just doesn’t run the script.
LikeLike
When you run it with the Verbose option, the log will contain a line starting with “RunOnce: $RunOnce”
Now either that reg. key doesn’t get set (policies, permissions?) or the cmd won’t go on your system for some reason ..
If you want me to have a look please provide the log file (michel [at] eightwone.com )
LikeLike
Thanks Michel, I’ll rebuild my test farm and send it over.
LikeLike
Hi squiggleh,
i ran into the same issue. Are you running an englisch OS? I used a german one. I had to put some values in quotes.
Search for $MajorOSVersion…
Switch ($State[“InstallPhase”]) {
1 {
Write-Output “Installing Operating System prerequisites”
Install-WindowsFeatures $MajorOSVersion
If( $MajorOSVersion -ne “6.1”) {
# Skip phase 2 for WS2012
$State[“InstallPhase”]++
Hope that helps.
LikeLike
I’ll give it a go flex … I’m running en-gb, not en-us.
LikeLike
@flex: I’m having a deja-vu 😦 I have a hunch where it goes bad .. I think it has to do with the US using “.” for decimal seperator and DE (amonst other countries) not. I’ll fetch a German WS2012R2 to check my theory.
LikeLike
Nope, wasn’t it. Next update will include the string’ed comparisons.
LikeLike
Rebuilt my farm … The log file never contains anything related to Run/RunOnce even with the Verbose switch. I have to continually re-run the command again and again.
LikeLike
My bad (in v1.7) – look for the line (in the line no. 1124 region)
# Enable-RunOnce
and change it to
Enable-RunOnce
LikeLike
great script.
On windows 2008 R2 SP1, I keep getting this error
Installing Exchange 2013 prerequisites
Processing Windows Management Framework 3.0 (KB2506143)
Package-Install : Problem installing Windows Management Framework 3.0
At C:\Users\Administrator\Desktop\Install-Exchange2013.ps1:996 char:32
+ Package-Install <<<< "KB2506143" "Windows Management Framework 3.0" "Windows6.1-KB2506143-x64.msu" "
http://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.1-KB2506143-x64.msu" ("/quie
t", "/norestart")
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Package-Install
Despite the fact that I have the following files in the c:\Install directory.
437878_intl_i386_zip.exe
filterpack2010sp1-kb2460041-x64-fullfile-en-us.exe
FilterPack32bit.exe
FilterPack64bit.exe
Install-Exchange2013.ps1_20140504222556.log
Install-Exchange2013.ps1_state.xml
NDP451-KB2858728-x86-x64-AllOS-ENU.exe
UcmaRuntimeSetup.exe
Windows6.1-KB2506143-x64.msu
Windows6.1-KB2533623-x64.msu
Windows6.1-KB974405-x64.msu
Can you please list out the files needed in the c:\install for offline installer?
Thanks
LikeLike
Those are mentioned here:
LikeLike
Thank you. I am able re-start the installation using elevated powershell privileges.
I have a quick followup question. What do I need to change in the code to make sure the pre-reqs are picked from the c:\install if already present?
Installation works fine in WS2012 R2. But on WS2012 I keep seeing this.
Processing Microsoft .NET Framework 4.51 ({7DEBE4EB-6B40-3766-BB35-5CBBC385DA37})
Package-Install : Problem installing Microsoft .NET Framework 4.51
At C:\Users\Administrator\Desktop\Install-Exchange2013.ps1:988 char:21
+ Package-Install “{7DEBE4EB-6B40-3766-BB35-5CBBC385DA37}” “Mi …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Package-Install
LikeLike
Issue has been localized – .NET 4.51 kb2858728 contains (thus reports) different KB for WS2008R2 (kb958488) than WS2012 (kb2881468). Should be fixed in 1.71 (May14), please give that one a go and let me know your mileage.
LikeLike
Hello ,
I’m in WS2012 R2
And the install is stopped at the download of Microsoft .NET framework 4.51
I have checked on the net for the KB2881468 and i saw that is not supported for WS2012r2
How can modify the script for complete my installation of MSExchange2013 ?
Thank you !
LikeLike
The KB for .NET 4.51 is different for WS2012R2.
Search for NDP451-KB2858728-x86-x64-AllOS-ENU.exe instead of NDP451-KB2858728-x86-x64-AllOS-ENU.exe. Do note however that since version 1.73 the script installs .NET 4.52, as this is now the recommended version for Exchange 2013. For supportability, see https://technet.microsoft.com/en-us/library/ff728623%28v=exchg.150%29.aspx
LikeLike
Oh ! i think found the bug !
At line 1402 : If( $MajorOSVersion -eq $WS2008R2_MAJOR) {
Need to replace for $WS2012R2_MAJOR
because of line 1410 are the same condition !
Tell me if it’s true please ! 🙂
Thank you
LikeLike
Ok it’s not that !
But my proble is that the script don’t reconize me as WS2012R2 and he want to force the install of KBKB2881468
Normally he must install the KB
LikeLike
What does this return?
Get-WmiObject Win32_OperatingSystem | Select Version
LikeLike
6.3.9600
LikeLike
I’m depoying on WS2012R2 all the time. Are you using a localized version of the OS perhaps?
LikeLike
Hello, This is why on Windows 2012 R2 the autologin does not work. If you see the log, it tells you if you use the -verbose switch. Any idea how to get the autologin to work, I am not sure how many times to run the script because it is not autologin and running the script. Thanks for your help Michael.
Transcript started, output file is C:\Install\Install-Exchange2013.ps1_20140509092028.log
VERBOSE: Disabling File Security Warning dialog
VERBOSE: Disabling Automatic Logon
Checking for pending reboot ..
VERBOSE: Current phase is 1 of 6
Installing Operating System prerequisites
LikeLike
This is as designed. The script disables autologin right after starting to prevent situations where the script will automatically start (again) should the server restart in unforeseen ways (i.e. before it ends) to prevent ending up in a loop. Before the scripts configures RunOnce etc. and initiating a reboot, it will enable AutoLogin again (except for the last phase) – that’s also logged.
LikeLike
Michael you’re absolutely right. I hadn’t noticed that the autologin is re-enabled towards the end of the script. For me, it never continued after reboot but knowing what phase had completed was good enough. Kept running the script until I got to phase 6. Have production environment up and running and currently testing backups and Lync 2013 OWA IM and Presence integration. Although I am having an issue with OWA IM and Presence integration…IM sign-in is failing. Do you have any good points you can pass on or links to helpful articles…my problem from seeing the Lync logs is that for some reason, my Mailbox server is trying to make the connection to Lync although the CAS service is on a totally different server. Thanks Michael.
LikeLike
Autologin (RunOnce) issue fixed – please try last version (1.71 / May14)
LikeLike
Your script is truly a work of art!!! Such A joy to read. There’s so much to take away from this one script!!! Thank you for this!!! Keep up the good work!!!
LikeLike
Yes, there’s a lot in there 🙂
LikeLike
Pingback: Exchange 2013 Unattended Installation Script (Updated) | EighTwOne (821) | JC's Blog-O-Gibberish
Pingback: Script Updates | EighTwOne (821)
Hey Michael,
So i can see this working for my initial server for a brand new organization, but can you advise how i would use your script for installing other multi roles servers? For instance should i simply omit one of the peramters, and if so which one? so far i’m reading if you define organization then it creates the organization name, which is my scenario is i seperately implemented schema already, but if not then it attempts a AD schema prep. i would imagine i wouldn’t want either for the additional multirole servers?
Edgar
LikeLike
Preparing Active Directory seperately is not uncommon. If you omit the Organization parameter, it will skip the preparation (e.g. PrepareAD), for example:
$Cred=Get-Credentials
.\Install-Exchange2013 -InstallMultiRole -AutoPilot -Credentials $Cred
LikeLike
Hi,
Fantastic Script – saves a lot of time and messing around. Seems to work very well for what I need.
One thing to note however, if I choose to set my own database name during the build such as “LAB Database 7” it will actually show as LAB,Database,7 on the ECP… Is this something that can be ironed out at all?
Thanks,
Dave
LikeLike
Um, good catch – I’ll have a look
LikeLike
I can’t seem to get this to run regardless of the switches I use. Here’s my latest attempt:
.\Install-Exchange2013.ps1 -InstallMultiRole -SourcePath C:\ExchangeCu5 -IncludeFixes
-InstallFilterPack
Installing Microsoft Exchange Server 2013
WARNING: \setup.exe not found
PS C:\ExchangeCu5> dir setup.exe
Directory: C:\ExchangeCu5
Mode LastWriteTime Length Name
—- ————- —— —-
-a— 10/05/2014 5:14 PM 27824 setup.exe
Help?
LikeLike
When you run it with the -Verbose parameter, what is it trying to execute? Just checked with a local path (C:\ExchangeSetup) as I usually run it directory off an UNC path, and see no issues. Could it be blocked from running?
LikeLike
Excellent work! Thank you for your contributions to the community.
LikeLike
Michel,
First off, thank you for this script. Excellent work!
Next, I am curious why when I run “.\Install-Exchange2013 -NoSetup -Autopilot” multiple times (to prep the OS), the server restarts regardless of what roles, features or other prerequisites have been previously installed.
I know one wouldn’t not normally run this command multiple times but it leads me to believe that: 1) Something isn’t installing correctly; or 2) The script does not have a built-in check to stop if all prereqs are found to be installed.
The server I am testing on is a domain-joined Windows Server 2012 R2 Standard with all available updates installed.
Can you help me to understand what I perceive to be a bug?
Lastly, I received an error during the install. Below is the message from the log. Please help.
Install-Exchange2013_ : Problem installing Exchange
At C:\Tools\Scripts\Install-Exchange2013.ps1:1108 char:13
+ Install-Exchange2013_
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Install-Exchange2013_
**********************
Thanks again.
Todd
LikeLike
The script is based on certain phases (i.e. prereqs, prep, install, etc). I currently do not have shortcuts built-in when things. Also, you should not need to fire the script manually when specifying AutoPilot, unless there is something no in order with automatic logon. This is also the reason why you are not left with a prompt when install fails for some reason – I don’t want to end up with an unlocked desktop with logged on credentials.
The error looks like an unsuccesfull install. I just do a basic check – for any setup issues, Exchange setup logs should provide more information.
LikeLike
Michel,
The AutoPilot “auto login” piece worked fine. It seems as though when the prereqs were found to be installed that script ended. But there is no indication why it did not proceed. The log only states “WARNING: Unified Communications Managed API 4.0 Runtime already installed” and the transcript ends. No XML created, no other indication that the script will continue or needs to continue. Therefore, I perceive it to be a bug. I ran AutoPilot several times and never received a different result or output, so I stopped using the AutoPilot switch. That’s when I actually started seeing progress with script and received the installation error that I provided in my original comment.
Regarding that error, I checked the Exchange setup logs and found the issue … missing organization name.
I think I supposed too much when I thought that installing Exchange in a new domain with this script that the default organization name of “First Organization” would be used.
Suggestion: Document this a bit more and/or make the Organization switch required for your script when no organization is present (i.e. prompt for org name if one is needed).
Next, apparently, if we do not run in AutoPilot mode, we have to run the same command over and over and over until all of the “phases” are completed.
Suggestion: When not using AutoPilot, create a pause instead of having the script stop altogether; or make this very clear in your documentation that we need to run the script several times (and how many times that may be based on the number of phases there are). There isn’t anything currently that I could find in the script that states the commands needs to be run several times.
Lastly, if the install fails, for whatever reason, the next time I run the script (no matter what new switches I add), the XML file seems to take precedence because it contains information (switch values) from the previous run(s). This caused me some frustration when trying to run the script after I found the cause of the install failure and tried to add the Organization switch. The value I added for Organization did not get updated in the XML file, therefore, the install continued to fail. I had to remove/rename the XML file and start all over with phase 1 by running the script again.
Thankfully, I have a lab to test out how to run this script through trial and error. The script isn’t perfect but what is (we always seem to be chasing our tail on one thing or another). I can see that it will save me A LOT of time (and potential mistakes) once I have it figured.
Michel, this is a great script! I appreciate it very much and your contributions to the community.
Thank you.
Todd
LikeLike
Hi Todd,
Thanks for your feedback. Checking if AD is already prepared or not in relation to the Organization parameter was already on the ‘to do’ list 🙂
On not using AutoPilot .. “When not specified, you will need to restart, logon and start the script manually each time (without parameters).” Agreed that that could use some rephrasing, thanks. Regarding success/failure, I was thinking
Lastly, if the install fails, for whatever reason, I was more thinking on opening up setup logs (cause that is what most people do), leaving the system locked.
On the XML parameter precedence, duly noted 🙂
Cheers!
LikeLike
Found a minor bug. In line 1151 or thereabouts script checks the version of the MSExchangeIS service’s exe to determine installed Exchange version. Problem is that the IS service is not present for dedicated CAS servers so the script fails to install recommended hotfixes.
Line: $ImagePathVersion= File-DetectVersion ( (Get-WMIObject -Query ‘select * from win32_service where name=”MSExchangeIS”‘).PathName.Trim(‘”‘) )
Switching to a common service like MSExchangeServiceHost should resolve. Will confirm once I’ve installed my mailbox servers.
Nice script, thanks for making it available by the way.
LikeLike
Good one, thanks for catching that .. but who installs non-multirole servers nowadays anyway 🙂
LikeLike
Just me it would seem. Over 2000 downloads and nobody else noticed the bug. 🙂
Thanks again for the script. Saved me a ton of work.
LikeLike
Great Script !!! It successfully install Exchange 2013 when ran under Administrator account. Does this support System ( “NTAuthority”) account?
LikeLike
You need to install it using a domain account with proper permissions (eg for schema/org prep)
LikeLike
Pingback: Thoughts on Exchange and comparisons | Dave Stork's IMHO
Hi Michel,
If I don’t specify MDBDB and MDBDBPath and Logs, does this mean that script will not create databases?
Or in other words, how can I use the screenshot without creating databases?
Cheers!
LikeLike
In that case it will create the default database and logs in the default locations using the default name (Mailbox ).
LikeLike
Thanks Michel
LikeLike
Hi Michel,
Bumping into an issue, where forest functional level can’t get verified.
I’m trying to install Exchange 2013 CU6 on Windows Server 2012.
There is already one Exchange 2010 and Exchange 2013 CU6 server installed in the same domain.
Servers are installed in CHILD domain of this greenfield AD forest deployment.
Below the cmdlet and output:
PS D:\Software> .\Install-Exchange2013.ps1 -InstallMultiRole -SourcePath “D:\Software\Exchange2013_Extracted” -TargetPat
h “D:\ExchSrvr” -AutoPilot -IncludeFixes -InstallFilterPack -Verbose
VERBOSE: Script D:\Software\Install-Exchange2013.ps1 called using [InstallMultiRole, True] [SourcePath,
D:\Software\Exchange2013_Extracted] [TargetPath, D:\ExchSrvr] [AutoPilot, True] [IncludeFixes, True]
[InstallFilterPack, True] [Verbose, True]
VERBOSE: Using parameterSet CM
VERBOSE: Running on OS build 6.2.9200
VERBOSE: No state file found at C:\Install\Install-Exchange2013.ps1_state.xml
Performing sanity checks ..
VERBOSE: Checking Operating System .. 6.2.9200
Checking running mode ..
Checking if we can access Exchange setup ..
Exchange setup version: 15.00.0995.028 (Unknown Version)
Checking roles to install
Checking domain membership status ..
Checking NIC configuration ..
Checking temporary installation folder ..
Checking Exchange Forest Schema Version
Exchange Forest Schema Version is
Checking Exchange Domain Version
Exchange Domain version is 13236
Checking domain mode
Domain is in native mode
Checking Forest Functional Level
The following exception occurred while retrieving member “get”: “There is no such object on the server.
”
At D:\Software\Install-Exchange2013.ps1:496 char:15
+ return( ($ForestRoot.get(“msDS-Behavior-Version”) ))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : CatchFromBaseGetMember
Check-Sanity : Forest is not Functional Level 2003 or later
At D:\Software\Install-Exchange2013.ps1:1031 char:5
+ Check-Sanity
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Sanity
When I run the functions separately, I get result for domain level, but not for Forest level
PS D:\Software> Function Get-ExchangeForestLevel {
$RootDSE= ([ADSI]””).distinguishedName
return ( ([ADSI]”LDAP://CN=ms-Exch-Schema-Version-Pt,CN=Schema,CN=Configuration,$RootDSE”).rangeUpper )
}
Function Get-ExchangeDomainLevel {
$RootDSE= ([ADSI]””).distinguishedName
return( ([ADSI]”LDAP://CN=Microsoft Exchange System Objects,$RootDSE”).objectVersion )
}
PS D:\Software> Get-ExchangeDomainLevel
13236
PS D:\Software> Get-ExchangeForestLevel
PS D:\Software>
I’m able to connect to Configuration partition using ADSIEDIT with the same credentials.
LikeLike
Good one, duly noted on issue list.
LikeLike
Hi,
I am having problems with the script crashing out after the 1st reboot with:
Exchange Domain version is
Checking domain mode
Domain is in native mode
Checking Forest Functional Level
Forest Functional Level is 2003 or later
Checking provided credentials
Check-Sanity : Provided credentials don’t seem to be valid
At C:\MSX2K13\Install-Exchange2013.ps1:1030 char:5
+ Check-Sanity
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Sanity
I have moved all the files into new folders and allowed full access to them. Also run the powershell as domain admin (with ent admin etc) and still same – any ideas?
LikeLike
“Provided credentials don’t seem to be valid”
Provide valid (domain) credentials as parameter (-Credentials)
LikeLike
Hi Michel,
at first: Really great job!
I have the same issue with the provided credentials. Even with the parameter.
Do you have some more ideas?
Thank you and regards,
Benjamin
LikeLike
Michel Hi,
It looks like the script was originally designed and tested only with “single forest / single domain” scenario.
That’s why a number of folks are having issues especially with the Forest level functions.
I took the liberty to change the script as follows, this way the forest level checks in “single forest / multiple domain” scenario, especially if the Exchange is to be installed on one of the child domains.
Lines 493 down:
### Begin Changes
Function Get-ForestFunctionalLevel {
#$RootDSE= ([ADSI]””).distinguishedName
$RootDSE= (Get-ADRootDSE).rootDomainNamingContext
write-host $RootDSE
return( ([ADSI]”LDAP://cn=partitions,cn=configuration,$RootDSE”).get(“msDS-Behavior-Version”) )
}
Function Test-DomainNativeMode {
$RootDSE= ([ADSI]””).distinguishedName
return( ([ADSI]”LDAP://$RootDSE”).ntMixedDomain )
}
Function Test-ExchangeOrganization( $Organization) {
#$RootDSE= ([ADSI]””).distinguishedName
$RootDSE= (Get-ADRootDSE).rootDomainNamingContext
return( [ADSI]”LDAP://CN=$Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,$RootDSE”)
}
Function Get-ExchangeForestLevel {
#$RootDSE= ([ADSI]””).distinguishedName
$RootDSE= (Get-ADRootDSE).rootDomainNamingContext
return ( ([ADSI]”LDAP://CN=ms-Exch-Schema-Version-Pt,CN=Schema,CN=Configuration,$RootDSE”).rangeUpper )
}
### End Changes
This works well on a Windows 2013 R2 server. If you need to run this on an older version of Windows you may need to also import the ActiveDirectory module at the beginning of the script. The “Get-RootDSE” function requires the AD module.
By the way, it is a great script and saved us a lot of time already.
Regards,
-Ilker
LikeLike
I installed Exchange with this successfully. However I wonder why the BITS feature is removed, isn’t that necessary for succesful Windows updates?
Also, the event log is filled with endless records about performance counters that have failed to update.
Some events:
– Event 2, Session “FastDocTracingSession” failed to start with the following error: 0xC0000035
– Event 106, numerous times, e.g.:
Performance counter updating error. Counter name is Per-Tenant KeyToRemoveBudgets Cache Size, category name is MSExchangeRemotePowershell. Optional code: 3. Exception: The exception thrown is : System.InvalidOperationException: The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
Performance Counters Layout information: FileMappingNotFoundException for category MSExchangeRemotePowershell : Microsoft.Exchange.Diagnostics.FileMappingNotFoundException: Cound not open File mapping for name Global\netfxcustomperfcounters.1.0msexchangeremotepowershell. Error Details: 2
Could this be related to the removal of BITS or is it something else?
LikeLike
The BITS feature is not installed by default, so I remove it after the installation process.
Event 2 and event 106 do not seem (absence of) BITS related, nor ring a bell.
For 2, it seems this can be ignore, see https://social.technet.microsoft.com/Forums/en-US/7eb12b89-ae9b-46b2-bd34-e50cd52a4c15
For 106, see if reloading perfcounters works for you https://support.microsoft.com/en-us/kb/2870416.
LikeLike
Pingback: PowerShell Scripts for your Exchange and Office 365 Toolkit
Pingback: IT/DEV Connections 2015 Wrap-Up | EighTwOne (821)