xExchInstall: Check/Install Prerequisites
Opened this issue · 6 comments
Details
Currently the xExchInstall resource doesn't check for prerequisites for Exchange 2013/2016/2019 and install them if necessary. This is pretty much the only thing that limits this DSC resource module from being a 100% end to end solution for deploying, configuring, and maintaining Exchange 2013/2016/2019.
Suggested solution
Add a prerequisite check for prerequisites i.e. .Net Framework, Visual C++ Redist. 2012 & 2013, UM Runtime, and necessary windows features (RSAT, etc.)
Hi Dana,
The install of prerequisite packages and features can be handled via other DSC resources. See this example that I used to deploy Exchange 2019 on Windows 2019 Server Core using DSC:
$ConfigurationData = @{
AllNodes = @(
@{
NodeName = '*'
<#
NOTE! THIS IS NOT RECOMMENDED IN PRODUCTION.
This is added so that AppVeyor automatic tests can pass, otherwise
the tests will fail on passwords being in plain text and not being
encrypted. Because it is not possible to have a certificate in
AppVeyor to encrypt the passwords we need to add the parameter
'PSDscAllowPlainTextPassword'.
NOTE! THIS IS NOT RECOMMENDED IN PRODUCTION.
See:
http://blogs.msdn.com/b/powershell/archive/2014/01/31/want-to-secure-credentials-in-windows-powershell-desired-state-configuration.aspx
#>
PSDscAllowPlainTextPassword = $true
},
@{
NodeName = 'e19core-1'
}
)
}
Configuration ExchangeSetup
{
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$ExchangeCredential
)
Import-DscResource -ModuleName StorageDsc
Import-DscResource -ModuleName xExchange
Import-DscResource -ModuleName WindowsDefender
Node $AllNodes.NodeName
{
File VCREDISTFile
{
Ensure = 'Present'
SourcePath = '\\rras-1\Binaries\vcredist_x64.exe'
DestinationPath = 'c:\Binaries\vcredist_x64.exe'
}
Package VCREDIST2013
{
Ensure = 'Present' # You can also set Ensure to 'Absent'
Path = 'c:\Binaries\vcredist_x64.exe'
Arguments = '/install /quiet'
Name = 'Microsoft Visual C++ 2013 x64'
ProductId = '929FBD26-9020-399B-9A7A-751D61F0B942'
DependsOn = '[File]VCREDISTFile'
}
WindowsFeature ServerMediaFoundation
{
Ensure = 'Present'
Name = 'Server-Media-Foundation'
}
# Note that RSAT-ADDS is only required if Setup will be running PrepareSchema/AD/etc
WindowsFeature RSATADDS
{
Ensure = 'Present'
Name = 'RSAT-ADDS'
}
File Ex2019File
{
Ensure = 'Present'
SourcePath = '\\rras-1\Binaries\ExchangeServer2019-x64.iso'
DestinationPath = 'c:\Binaries\ExchangeServer2019-x64.iso'
}
MountImage ExISO
{
ImagePath = 'c:\Binaries\ExchangeServer2019-x64.iso'
DriveLetter = 'X'
DependsOn = '[File]Ex2019File'
}
Package UCMA4
{
Ensure = 'Present'
Path = 'X:\UCMARedist\setup.exe'
Arguments = '/quiet'
Name = 'Microsoft Unified Communications Managed API 4.0, Runtime'
ProductId = '41D635FE-4F9D-47F7-8230-9B29D6D42D31'
DependsOn = '[MountImage]ExISO','[WindowsFeature]ServerMediaFoundation'
}
# Configure AV exclusions per: https://docs.microsoft.com/en-us/Exchange/antispam-and-antimalware/windows-antivirus-software
WindowsDefender ConfigureExclusions
{
IsSingleInstance = 'Yes'
ExclusionPath = @(
'C:\Windows\Cluster'
'C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB'
'C:\Program Files\Microsoft\Exchange Server\V15\FIP-FS'
'C:\Program Files\Microsoft\Exchange Server\V15\Logging'
'C:\Program Files\Microsoft\Exchange Server\V15\Mailbox'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Data\Adam'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Data\IpFilter'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Data\Queue'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Data\SenderReputation'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Data\Temp'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Pickup'
'C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Replay'
'C:\Program Files\Microsoft\Exchange Server\V15\UnifiedMessaging\Grammars'
'C:\Program Files\Microsoft\Exchange Server\V15\UnifiedMessaging\Prompts'
'C:\Program Files\Microsoft\Exchange Server\V15\UnifiedMessaging\Temp'
'C:\Program Files\Microsoft\Exchange Server\V15\UnifiedMessaging\Voicemail'
'C:\Program Files\Microsoft\Exchange Server\V15\Working\OleConverter'
'C:\inetpub\temp\IIS Temporary Compressed Files'
'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files'
'C:\Windows\System32\Inetsrv'
'C:\Windows\Temp\OICE_*'
)
ExclusionProcess = @(
'ComplianceAuditService.exe'
'Dsamain.exe'
'EdgeTransport.exe'
'fms.exe'
'hostcontrollerservice.exe'
'inetinfo.exe'
'Microsoft.Exchange.AntispamUpdateSvc.exe'
'Microsoft.Exchange.ContentFilter.Wrapper.exe'
'Microsoft.Exchange.Diagnostics.Service.exe'
'Microsoft.Exchange.Directory.TopologyService.exe'
'Microsoft.Exchange.EdgeCredentialSvc.exe'
'Microsoft.Exchange.EdgeSyncSvc.exe'
'Microsoft.Exchange.Imap4.exe'
'Microsoft.Exchange.Imap4service.exe'
'Microsoft.Exchange.Notifications.Broker.exe'
'Microsoft.Exchange.Pop3.exe'
'Microsoft.Exchange.Pop3service.exe'
'Microsoft.Exchange.ProtectedServiceHost.exe'
'Microsoft.Exchange.RPCClientAccess.Service.exe'
'Microsoft.Exchange.Search.Service.exe'
'Microsoft.Exchange.Servicehost.exe'
'Microsoft.Exchange.Store.Service.exe'
'Microsoft.Exchange.Store.Worker.exe'
'Microsoft.Exchange.UM.CallRouter.exe'
'MSExchangeCompliance.exe'
'MSExchangeDagMgmt.exe'
'MSExchangeDelivery.exe'
'MSExchangeFrontendTransport.exe'
'MSExchangeHMHost.exe'
'MSExchangeHMWorker.exe'
'MSExchangeMailboxAssistants.exe'
'MSExchangeMailboxReplication.exe'
'MSExchangeRepl.exe'
'MSExchangeSubmission.exe'
'MSExchangeTransport.exe'
'MSExchangeTransportLogSearch.exe'
'MSExchangeThrottling.exe'
'Noderunner.exe'
'OleConverter.exe'
'ParserServer.exe'
'Powershell.exe'
'ScanEngineTest.exe'
'ScanningProcess.exe'
'UmService.exe'
'UmWorkerProcess.exe'
'UpdateService.exe'
'W3wp.exe'
'wsbexchange.exe'
)
ExclusionExtension = @(
'.config'
'.chk'
'.edb'
'.jfm'
'.jrs'
'.log'
'.que'
'.dsc'
'.txt'
'.cfg'
'.grxml'
'.lzx'
)
}
xExchInstall InstallExchange
{
Path = 'X:\Setup.exe'
Arguments = '/mode:Install /role:Mailbox /IAcceptExchangeServerLicenseTerms /InstallWindowsComponents'
Credential = $ExchangeCredential
DependsOn = '[WindowsDefender]ConfigureExclusions','[MountImage]ExISO','[WindowsFeature]RSATADDS'
}
xExchExchangeServer EXServer
{
Identity = $Node.NodeName
Credential = $ExchangeCredential
ProductKey = 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
AllowServiceRestart = $true
DependsOn = '[xExchInstall]InstallExchange'
}
#Copy an certificate .PFX that had been previously exported, import it, and enable services on it
File CopyExchangeCert
{
Ensure = 'Present'
SourcePath = "\\rras-1\Binaries\Certificates\ExchangeCert.pfx"
DestinationPath = 'C:\Binaries\Certificates\ExchangeCert.pfx'
Credential = $ExchangeCredential
}
xExchExchangeCertificate Certificate
{
Thumbprint = '766358855A7361C6D99D4FB58903AB0833296B2A'
Credential = $ExchangeAdminCredential
Ensure = 'Present'
AllowExtraServices = $true
CertCreds = $ExchangeCertCredential
CertFilePath = 'C:\Binaries\Certificates\ExchangeCert.pfx'
Services = 'IIS','POP','IMAP','SMTP'
DependsOn = '[File]CopyExchangeCert'
}
###CAS specific settings###
#The following section shows how to configure commonly configured URL's on various virtual directories
xExchClientAccessServer CAS
{
Identity = $Node.NodeName
Credential = $ExchangeAdminCredential
AutoDiscoverServiceInternalUri = "https://$($casSettingsPerSite.InternalNamespace)/autodiscover/autodiscover.xml"
AutoDiscoverSiteScope = $casSettingsPerSite.AutoDiscoverSiteScope
}
xExchActiveSyncVirtualDirectory ASVdir
{
Identity = "$($Node.NodeName)\Microsoft-Server-ActiveSync (Default Web Site)"
Credential = $ExchangeAdminCredential
ExternalUrl = "https://$($casSettingsAll.ExternalNamespace)/Microsoft-Server-ActiveSync"
InternalUrl = "https://$($casSettingsPerSite.InternalNamespace)/Microsoft-Server-ActiveSync"
}
xExchEcpVirtualDirectory ECPVDir
{
Identity = "$($Node.NodeName)\ecp (Default Web Site)"
Credential = $ExchangeAdminCredential
ExternalUrl = "https://$($casSettingsAll.ExternalNamespace)/ecp"
InternalUrl = "https://$($casSettingsPerSite.InternalNamespace)/ecp"
}
xExchMapiVirtualDirectory MAPIVdir
{
Identity = "$($Node.NodeName)\mapi (Default Web Site)"
Credential = $ExchangeAdminCredential
ExternalUrl = "https://$($casSettingsAll.ExternalNamespace)/mapi"
InternalUrl = "https://$($casSettingsPerSite.InternalNamespace)/mapi"
IISAuthenticationMethods = 'Ntlm','OAuth','Negotiate'
}
xExchOabVirtualDirectory OABVdir
{
Identity = "$($Node.NodeName)\OAB (Default Web Site)"
Credential = $ExchangeAdminCredential
ExternalUrl = "https://$($casSettingsAll.ExternalNamespace)/oab"
InternalUrl = "https://$($casSettingsPerSite.InternalNamespace)/oab"
}
xExchOutlookAnywhere OAVdir
{
Identity = "$($Node.NodeName)\Rpc (Default Web Site)"
Credential = $ExchangeAdminCredential
ExternalClientAuthenticationMethod = 'Negotiate'
ExternalClientsRequireSSL = $true
ExternalHostName = $casSettingsAll.ExternalNamespace
IISAuthenticationMethods = 'Basic', 'Ntlm', 'Negotiate'
InternalClientAuthenticationMethod = 'Ntlm'
InternalClientsRequireSSL = $true
InternalHostName = $casSettingsPerSite.InternalNamespace
}
}
}
This would be the preferred way to install prerequisites when the main Exchange setup.exe
does not support downloading them from an external source and then install them.
We should add the configuration in previous comment as an example in the module.
@johlju, I can help with this. To make sure, we need to add the example that @mhendric provided on the DSC module itself of xExchInstall
https://github.com/dsccommunity/xExchange/tree/main/source/DSCResources/MSFT_xExchInstall or needs to be added in the examples folder: https://github.com/dsccommunity/xExchange/tree/main/source/Examples?
A new example that shows how to install prerequisites. It could be extended to existing example here https://github.com/dsccommunity/xExchange/blob/main/source/Examples/InstallExchange/InstallExchange.ps1
We should really have the correct folder structure for examples as well, but that can be fixed later.
Hmm, it seems there should be more examples that just extending the one I mentioned above since the example configuration above contain examples for several resources. So we might need to do the correct folder and file structure, see how it is made here: https://github.com/dsccommunity/SqlServerDsc/tree/main/source/Examples/Resources
Having the correct folder and file structure prepares for adding auto-documentation later to this repo (publish to Wiki).
we will work on it. thank you for the feedback