Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xExchInstall: Check/Install Prerequisites #425

Open
danagarcia opened this issue Oct 3, 2019 · 6 comments
Open

xExchInstall: Check/Install Prerequisites #425

danagarcia opened this issue Oct 3, 2019 · 6 comments
Labels
documentation The issue is related to documentation only. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub help wanted The issue is up for grabs for anyone in the community.

Comments

@danagarcia
Copy link

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
Copy link
Contributor

mhendric commented Oct 3, 2019

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
Copy link
Member

johlju commented Oct 3, 2021

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 johlju added documentation The issue is related to documentation only. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub help wanted The issue is up for grabs for anyone in the community. labels Oct 3, 2021
@mhincapie
Copy link
Contributor

mhincapie commented Oct 8, 2021

@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
Copy link
Member

johlju commented Oct 10, 2021

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
Copy link
Member

johlju commented Oct 10, 2021

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
Copy link
Contributor

we will work on it. thank you for the feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation The issue is related to documentation only. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub help wanted The issue is up for grabs for anyone in the community.
Projects
None yet
Development

No branches or pull requests

4 participants