Hi, folks!
There is a good example of Exchange installation inside of help files for xExchange module but it’s actually not valid for Exchange 2016:
- no installation for server roles and features = configuration fails
- Exchange 2016 does not have separate client access role anymore = wrong installation parameters and setup fails
- UCMA is required to be installed = errors during prerequisite check up
- not optimal LCM parameters
- no certificate management
- there is no variables passing via command line = not suitable for unattended setup
- …
So here is the fixed version of one .
/Has been tested on VM with up-to-date domain joined 2012 R2 guest machine.
//If you are not yet familiar with PowerShell DSC it’s recommended to review some facts before setting up and then do some additional steps:
0) Step for lazy persons
. Download link for all-in-one zip file
1) Install the following update (only for PowerShell v3 and v4.0) :
PackageManagement PowerShell Modules Preview – March 2016
2) Import or verify that the required modules are available :
- xExchange . It’s a custom module for installation and configuration Exchange environment (installation, DAG, settings and more)
- WindowsFeature . Built-in DSC resource that ensures and installs windows server roles/features
- Package . Built-in DSC resource to install program packages (msi,exe and etc)
- xPendingReboot. Custom module that reboots system if it is in the “pending reboot” status.
- To list installed custom DSC resources:
Get-DscResource|? {$_.ModuleName -NotMatch "PSDesired"}
- To install custom DSC (internet connectivity is required):
- I prefer to save module for the further usage and then install or just copy to one of the PS module’s path
#save module to pre-created folder
Save-Module xExchange -Path C:\DSC\Modules
#Copy module to the one of the following folders (../Program Files/.. is recommended)
$env:PSModulePath
C:\Users\username\Documents\WindowsPowerShell\Modules;
C:\Program Files\WindowsPowerShell\Modules;
C:\Windows\system32\WindowsPowerShell\v1.0\Modules
3) Prepare folders. Script uses the following paths:
- “C:\Exch” – Exchange binaries,
- “C:\ExchInstall\Cert” – required files for import certificate
- “C:\UCMA” – UCMA installation files
4) Download Exchange media and copy setup files (C:\Exch in my case)
5) Extract UCMA package to another folder (script uses C:\UCMA)
6) (optional) Prepare certificate for securing MOF files. I use this module to create one and then export PFX and CER-files to “C:\ExchInstall\Cert”.
Note: If you don’t want to secure your MOF files you can comment out related strings in the main script (step 6, see comment blocks)
. .\New-SelfSignedCertificateEx.ps1
New-SelfsignedCertificateEx `
-Subject 'CN=localhost' `
-EKU 'Document Encryption' `
-KeyUsage 'KeyEncipherment, DataEncipherment' `
-SAN localhost `
-FriendlyName 'DSC certificate' `
-Exportable `
-StoreLocation 'LocalMachine' `
-StoreName 'My' `
-KeyLength 2048 `
-ProviderName 'Microsoft Enhanced Cryptographic Provider v1.0' `
-AlgorithmName 'RSA' `
-SignatureAlgorithm 'SHA256'
6) Create the new script (ps1) which contains the following strings
Note: RebootNodeIfNeeded has been set to “True” so LCM have rights to reboot your machine automatically.
<#
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|w|w|w|.|r|l|e|v|c|h|e|n|k|o|.|c|o|m|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
::Exchange 2016 Installation (DSC)
::Required modules: xExchange and xPendingReboot
#>
#Variables
param ()
#Domain and Netbios Names
$domainname=$args[0] #or get-domain if domain is existed.
$netbios=$DomainName.split(“.”)[0]
#Creds for Exchange install acoount
$pwd = ConvertTo-SecureString "Pass123" -AsPlainText -Force
$Creds = New-Object System.Management.Automation.PSCredential ("$netbios\Administrator", $pwd)
#Import the certificate for securing MOF (optional. related strings can be just commented out)
$CertPW=ConvertTo-SecureString “Pass123” -AsPlainText -Force
Import-PfxCertificate -Password $certpw -CertStoreLocation Cert:\LocalMachine\My -FilePath C:\ExchInstall\cert\publickey.pfx
#DSC starts here
Configuration InstallExchange
{
Import-DscResource -Module xExchange
Import-DscResource -Module xPendingReboot
Node $AllNodes.NodeName
{
#Sets certificate for LCM on every node
LocalConfigurationManager
{
CertificateId = $AllNodes.Thumbprint
RebootNodeIfNeeded = $true
ConfigurationMode = 'ApplyOnly'
}
#Installs Required Components for Exchange (note: there is 1 planned automatic reboot)
WindowsFeature ASHTTP
{
Ensure = 'Present'
Name = 'AS-HTTP-Activation'
}
WindowsFeature DesktopExp
{
Ensure = 'Present'
Name = 'Desktop-Experience'
}
WindowsFeature NetFW45
{
Ensure = 'Present'
Name = 'NET-Framework-45-Features'
}
WindowsFeature RPCProxy
{
Ensure = 'Present'
Name = 'RPC-over-HTTP-proxy'
}
WindowsFeature RSATClus
{
Ensure = 'Present'
Name = 'RSAT-Clustering'
}
WindowsFeature RSATClusCmd
{
Ensure = 'Present'
Name = 'RSAT-Clustering-CmdInterface'
}
WindowsFeature RSATClusMgmt
{
Ensure = 'Present'
Name = 'RSAT-Clustering-Mgmt'
}
WindowsFeature RSATClusPS
{
Ensure = 'Present'
Name = 'RSAT-Clustering-PowerShell'
}
WindowsFeature WebConsole
{
Ensure = 'Present'
Name = 'Web-Mgmt-Console'
}
WindowsFeature WAS
{
Ensure = 'Present'
Name = 'WAS-Process-Model'
}
WindowsFeature WebAsp
{
Ensure = 'Present'
Name = 'Web-Asp-Net45'
}
WindowsFeature WBA
{
Ensure = 'Present'
Name = 'Web-Basic-Auth'
}
WindowsFeature WCA
{
Ensure = 'Present'
Name = 'Web-Client-Auth'
}
WindowsFeature WDA
{
Ensure = 'Present'
Name = 'Web-Digest-Auth'
}
WindowsFeature WDB
{
Ensure = 'Present'
Name = 'Web-Dir-Browsing'
}
WindowsFeature WDC
{
Ensure = 'Present'
Name = 'Web-Dyn-Compression'
}
WindowsFeature WebHttp
{
Ensure = 'Present'
Name = 'Web-Http-Errors'
}
WindowsFeature WebHttpLog
{
Ensure = 'Present'
Name = 'Web-Http-Logging'
}
WindowsFeature WebHttpRed
{
Ensure = 'Present'
Name = 'Web-Http-Redirect'
}
WindowsFeature WebHttpTrac
{
Ensure = 'Present'
Name = 'Web-Http-Tracing'
}
WindowsFeature WebISAPI
{
Ensure = 'Present'
Name = 'Web-ISAPI-Ext'
}
WindowsFeature WebISAPIFilt
{
Ensure = 'Present'
Name = 'Web-ISAPI-Filter'
}
WindowsFeature WebLgcyMgmt
{
Ensure = 'Present'
Name = 'Web-Lgcy-Mgmt-Console'
}
WindowsFeature WebMetaDB
{
Ensure = 'Present'
Name = 'Web-Metabase'
}
WindowsFeature WebMgmtSvc
{
Ensure = 'Present'
Name = 'Web-Mgmt-Service'
}
WindowsFeature WebNet45
{
Ensure = 'Present'
Name = 'Web-Net-Ext45'
}
WindowsFeature WebReq
{
Ensure = 'Present'
Name = 'Web-Request-Monitor'
}
WindowsFeature WebSrv
{
Ensure = 'Present'
Name = 'Web-Server'
}
WindowsFeature WebStat
{
Ensure = 'Present'
Name = 'Web-Stat-Compression'
}
WindowsFeature WebStatCont
{
Ensure = 'Present'
Name = 'Web-Static-Content'
}
WindowsFeature WebWindAuth
{
Ensure = 'Present'
Name = 'Web-Windows-Auth'
}
WindowsFeature WebWMI
{
Ensure = 'Present'
Name = 'Web-WMI'
}
WindowsFeature WebIF
{
Ensure = 'Present'
Name = 'Windows-Identity-Foundation'
}
WindowsFeature RSATADDS
{
Ensure = 'Present'
Name = 'RSAT-ADDS'
}
#Installs UCMA. Don't forget to change path it if it is required
Package UCMA
{
Ensure= 'Present'
Name = 'Microsoft Unified Communications Managed API 4.0, Core
Runtime 64-bit'
Path= 'c:\UCMA\UcmaRuntimeSetup\ironmansetup.exe'
ProductID= 'ED98ABF5-B6BF-47ED-92AB-1CDCAB964447'
Arguments= '/q'
}
#Checks Exchange Setup Directory (can be changed it's necessary). No recurse.
File ExchangeBinaries
{
Ensure = 'Present'
Type = 'Directory'
Recurse = $false
SourcePath = 'C:\Exch'
DestinationPath = 'C:\Exch'
}
#Checks if a reboot is needed before installing Exchange
xPendingReboot BeforeExchangeInstall
{
Name = "BeforeExchangeInstall"
DependsOn = '[File]ExchangeBinaries'
}
#Does the Exchange install. Verify directory with exchange binaries
xExchInstall InstallExchange
{
Path = "C:\Exch\Setup.exe"
Arguments = "/mode:Install /role:Mailbox /OrganizationName:""$netbios"" /Iacceptexchangeserverlicenseterms"
Credential = $Creds
DependsOn = '[xPendingReboot]BeforeExchangeInstall'
}
#Sees if a reboot is required after installing Exchange
xPendingReboot AfterExchangeInstall
{
Name = "AfterExchangeInstall"
DependsOn = '[xExchInstall]InstallExchange'
}
}
}
#DSC Configuration data
$ConfigData=@{
AllNodes = @(
@{
NodeName = "*"
#Replace thumbprint with yours or use precreated cert
CertificateFile = "C:\ExchInstall\cert\publickey.cer"
Thumbprint = "FF0693E72BD283298323DF34B2A848F0F1B48E67"
PSDscAllowPlainTextPassword = $true
}
@{
NodeName = "localhost"
}
);
}
if ($Creds -eq $null)
{
#if creds are empty -> write to log Application/mozno udalit')
New-EventLog –LogName Application –Source “Exchange Installation”
Write-EventLog –LogName Application –Source “Exchange Installation” –EntryType Error –EventID 1 –Message “Credentials are empty”
}
#Compiles the example
InstallExchange -ConfigurationData $ConfigData -Creds $Creds
#Sets up LCM on target computers to decrypt credentials, and to allow reboot during resource execution
Set-DscLocalConfigurationManager -Path .\InstallExchange -Verbose
#Pushes configuration and waits for execution
Start-DscConfiguration -Path .\InstallExchange -Verbose -Wait
7) Run the script with the mandatory <domainname> parameter
Example:
.\InstallExchange.ps1 contoso.com
8) Wait while LCM applies DSC configuration.
To retrieve the the current status use:
Get-DSCLocalConfigurationManager
and
- read logs (Applications and Services Logs – Microsoft – Windows – Desired State Configuration)
- Exchange creates it’s own setup logs on your system drive . check them in case of unexpected errors.
Until then,
have a nice weekend!
P.S. I have updated this script with DAG configuration and etc.. I’ll publish a new post later. Be in touch.
Like this:
Like Loading...