Desired State Configuration is mostly awesome…

But, sometimes you can’t use it!

As i’m working on my script for Rebuild conf. I’m facing terribly issues with Exchange 2013 installation with DSC. I will show you how you can “install” Exchange 2013 remotely mostly with DSC..

First of all, you need to install Windows features and roles.. this is the easy part !

Configuration Rebuild {
    Node srvexch {
        WindowsFeature RPCoverHTTPproxy {
            Ensure = 'Present'
            Name = 'RPC-over-HTTP-proxy'
        }
        WindowsFeature RSATClusteringMgmt {
            Ensure = 'Present'
            Name = 'RSAT-Clustering-Mgmt'
        }
        WindowsFeature RSATClusteringPS {
            Ensure = 'Present'
            Name = 'RSAT-Clustering-PowerShell'
        }
        WindowsFeature RSATClusteringCmdInterface {
            Ensure = 'Present'
            Name = 'RSAT-Clustering-CmdInterface'
        }
        WindowsFeature RSATADDS {
            Ensure = 'Present'
            Name = 'RSAT-ADDS'
        }
        WindowsFeature ASHTTPActivation {
            Ensure = 'Present'
            Name = 'AS-HTTP-Activation'
        }
        WindowsFeature DesktopExperience {
            Ensure = 'Present'
            Name = 'Desktop-Experience'
        }
        WindowsFeature RSATClustering {
            Ensure = 'Present'
            Name = "RSAT-Clustering"
        }
        WindowsFeature NETFramework45Features {
            Ensure = 'Present'
            Name = 'NET-Framework-45-Features'
        }
        WindowsFeature WASProcessModel {
            Ensure = 'Present'
            Name = 'WAS-Process-Model'
        }
        WindowsFeature WebAspNet45 {
            Ensure = 'Present'
            Name = 'Web-Asp-Net45'
        }
        WindowsFeature WebBasicAuth {
            Ensure = 'Present'
            Name = 'Web-Basic-Auth'
        }
        WindowsFeature WebClientAuth {
            Ensure = 'Present'
            Name = 'Web-Client-Auth'
        }
        WindowsFeature WebDigestAuth {
            Ensure = 'Present'
            Name = 'Web-Digest-Auth'
        }
        WindowsFeature WebDirBrowsing {
            Ensure = 'Present'
            Name = 'Web-Dir-Browsing'
        }
        WindowsFeature WebDynCompression {
            Ensure = 'Present'
            Name = 'Web-Dyn-Compression'
        }
        WindowsFeature WebHttpErrors {
            Ensure = 'Present'
            Name = 'Web-Http-Errors'
        }
        WindowsFeature WebHttpLogging {
            Ensure = 'Present'
            Name = 'Web-Http-Logging'
        }

        WindowsFeature WebHttpRedirect {
            Ensure = 'Present'
            Name = 'Web-Http-Redirect'
        }
        WindowsFeature WebHttpTracing {
            Ensure = 'Present'
            Name = 'Web-Http-Tracing'
        }
        WindowsFeature WebISAPIExt {
            Ensure = 'Present'
            Name = 'Web-ISAPI-Ext'
        }
        WindowsFeature WebISAPIFilter {
            Ensure = 'Present'
            Name = 'Web-ISAPI-Filter'
        }
        WindowsFeature WebMgmtConsole {
            Ensure = 'Present'
            Name = 'Web-Mgmt-Console'
        }
        WindowsFeature WebLgcyMgmtConsole {
            Ensure = 'Present'
            Name = 'Web-Lgcy-Mgmt-Console'
        }
        WindowsFeature WebMetabase {
            Ensure = 'Present'
            Name = 'Web-Metabase'
        }
        WindowsFeature WebMgmtService {
            Ensure = 'Present'
            Name = 'Web-Mgmt-Service'
        }
        WindowsFeature WebNetExt45 {
            Ensure = 'Present'
            Name = 'Web-Net-Ext45'
        }
        WindowsFeature WebRequestMonitor {
            Ensure = 'Present'
            Name = 'Web-Request-Monitor'
        }
        WindowsFeature WebServer {
            Ensure = 'Present'
            Name = 'Web-Server'
        }
        WindowsFeature WebStatCompression {
            Ensure = 'Present'
            Name = 'Web-Stat-Compression'
        }
        WindowsFeature WebStaticContent {
            Ensure = 'Present'
            Name = 'Web-Static-Content'
        }
        WindowsFeature WebWindowsAuth {
            Ensure = 'Present'
            Name = 'Web-Windows-Auth'
        }
        WindowsFeature WebWMI {
            Ensure = 'Present'
            Name = 'Web-WMI'
        }
        WindowsFeature WindowsIdentityFoundation {
            Ensure = 'Present'
            Name = 'Windows-Identity-Foundation'
        }
        WindowsFeature TelnetClient {
            Ensure = 'Present'
            Name = 'Telnet-Client'
        }
    } # end node exch
}

After that you need to install a package as a prerequite.

Configuration Software {
    Node srvexch {
        Package OCRuntime {
            Name = "Runtime Exchange"
            Path = "C:\temp\Exchange\UcmaRuntimeSetup.exe"
            Productid = "ED98ABF5-B6BF-47ED-92AB-1CDCAB964447"
            Arguments = "/passive /norestart"
            Ensure = "Present"
            returncode = 0
        }
    } # end node exch
}

And this is where things are getting worst… You can’t use Package resource, as you need to execute the install with some administrators rights.

So i came up with this, after having enabled CredSSP for WinRM.

Script ExchangeInstall {
            GetScript = { #Do nothing 
            }
            TestScript = {$false}
            SetScript = {
                $secpassword = ConvertTo-SecureString "123456!" -AsPlainText -Force
                $Credentials = New-Object System.Management.Automation.PSCredential ("MSLYNC\Administrator", $secpassword)
                $PSSession = New-PSSession -Authentication Credssp -ComputerName srvexch -Credential $Credentials
                Invoke-Command -Session $PSSession -Scriptblock {
                    $Path = "C:\temp\Exchange\setup.EXE"
                    $Arguments = "/mode:Install /role:ClientAccess,Mailbox /OrganizationName:ExchangeOrganization /IAcceptExchangeServerLicenseTerms"
                    Start-Process -Filepath $Path -ArgumentList $Arguments -wait
                } -args $Credentials
                
            } 
        }

The idea was to use delegation authority to be able to use Administrator account for installation. It works great… but. But Exchange 2013 installation, try to enable WSMAN for IIS with a function called Configure-WSmanIISHosting during his installation and it breaks the CIM Session used by DSC.

So finally, after all theses improvements with PowerShell, DSC, remoting and everything else. You still need the old good PSexec outside any workflows, DSC or WinRM sessions!

C:\Lync\PSexec.exe \\srvexch -u MSLYNC\Administrator -p P4ssw0rd! -accepteula cmd /c C:\temp\Exchange\Setup.EXE /mode:Install /role:ClientAccess,Mailbox /OrganizationName:ExchangeOrganization /IAcceptExchangeServerLicenseTerms

It’s ugly, and i don’t like this solution.

This is sad, and i bet it’s the same for SQL Server, i don’t have time to test it currently, maybe you have already tried that ?

Maybe you have reached the goal of installing Exchange remotely through a WinRM or CIM Session ! Say it, i’m sure there is a way, i’m not good enough with this product… i know 🙁