dsccommunity / ExchangeDsc

This module contains DSC resources for deployment and configuration of Microsoft Exchange Server.
MIT License
80 stars 49 forks source link

xExchInstall: Check/Install Prerequisites #425

Open danagarcia opened 5 years ago

danagarcia commented 5 years ago

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.)

mhendric commented 5 years ago

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
        }
    }
}
johlju commented 3 years ago

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.

mhincapie commented 3 years ago

@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?

johlju commented 3 years ago

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.

johlju commented 3 years ago

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).

mhincapie commented 3 years ago

we will work on it. thank you for the feedback