Friday, January 29, 2016

Enable Remote PowerShell Connections via HTTPS

Hi folks,

I just wanted to share with you a quick script to enable PowerShell connectivity via HTTPS instead of the default HTTP. This may be especially useful when you are trying to manage your Exchange environment via Internet and publish it via proxy. You can read more details about configuration of HTTPS in this article.

Below is the code which you will need to run on your Exchange 2013/2016 box that will enable configuration of Basic authentication which needs to be used in conjunction with SSL:

$Server = $(Get-WmiObject Win32_Computersystem).name
Get-PowerShellVirtualDirectory -Server $Server |Set-PowerShellVirtualDirectory -BasicAuthentication:$true

After configuration I have executed the following code:

Get-PowerShellVirtualDirectory -Server $Server |select *auth*

It produced output as below:




Note that values next to InternalAuthenticationMethods and ExternalAuthenticationMethods should be set to Basic.

After this you can launch remote PowerShell session and have it connected to the HTTPS URL of your PowerShell virtual directory. Make sure that you specify Authentication parameter as Basic as well as you add AllowRedirection parameter as below (I also add the last line to ensure that I can see mailboxes within the whole AD forest if it's a multi-domain one):


$cred = Get-Credential

$session = New-PSSession -ConfigurationName Microsoft.Exchange -Authentication Basic -ConnectionUri https://mail.contoso.com/powershell/ -AllowRedirection -Credential $cred
Import-PSsession $session
Set-ADServerSettings -ViewEntireForest:$true

Enjoy!

Wednesday, January 20, 2016

Kerberos and User account as ASA

Hi folks,

In this brief post I would love to share you a little about configuration of Kerberos authentication on Exchange 2013 CAS server behind the load balancers. This protocol is more secure and better scalable than NTLM. I won't go into too many details here on how to configure it. This Technet article fully descrbies how to configure Kerberos authentication for Outlook Anywhere (including MAPI/HTTP) and this one provides great guideline on how to configure it in co-existence with Exchange 2010.

The best way of configuring ASA is to use a computer account as password for it is automatically managed. However, here I will discuss using user account as an ASA. The particular step of our interest is:

.\RollAlternateServiceAccountPassword.ps1 -ToSpecificServer ex01.contoso.com -GenerateNewPasswordFor contoso\userASA

This command deploys ASA credentials on the first CAS servers and is also used to reset ASA account password. Unfortunately, you need to do with your user service accounts every now and then. Please note that you can't use AD tools to reset password and therefore only the above command will do you a magic.

In order to successfully change password for this account you will need to ensure that your admin account used for this activity has the following permissions on the ASA user account:

- Change Password
- Reset Password

If they are not preset you may get an error as below:


I hope you will find this post helpful in your Exchange configuration adventures.

Enjoy!

Tuesday, January 19, 2016

Exchange 2013 Re-Install and Failed Certificates

Hi folks,

I have recently was working on the re-installation of Exchange 2013 binary files on a server. After configuring Mailbox role: Transport service setup failed and other service wound't installed.

This is where c:\ExchangeSetupLogs\ExchangeSetup.log (setup log generated by Exchange setup program) came to my rescue. Looking into the file I have located the following records:

[01/19/2016 14:09:38.0912] [2] Installing certificate signed by CA NAME/rpa is incorporated by reference, FULL SUBJECT NAME'.  Certificate is valid from 7/10/2014 11:14:39 AM until 1/7/2016 4:09:08 PM.
[01/19/2016 14:09:38.0912] [2] [ERROR] The certificate is expired.
[01/19/2016 14:09:38.0912] [2] [ERROR] The certificate is expired.
[01/19/2016 14:09:38.0912] [2] Ending processing Install-ExchangeCertificate
[01/19/2016 14:09:38.0927] [2] Active Directory session settings for 'Install-AuthCertificate' are: View Entire Forest: 'True', Configuration Domain Controller: 'DC01.contoso.com', Preferred Global Catalog: 'DC01.contoso.com', Preferred Domain Controllers: '{ DC01.contoso.com }'
[01/19/2016 14:09:38.0927] [2] User specified parameters:  -DomainController:'DC01.contoso.com'
[01/19/2016 14:09:38.0927] [2] Beginning processing Install-AuthCertificate
[01/19/2016 14:09:38.0958] [2] Ending processing Install-AuthCertificate
[01/19/2016 14:09:38.0958] [1] The following 1 error(s) occurred during task execution:
[01/19/2016 14:09:38.0958] [1] 0.  ErrorRecord: The certificate is expired.
[01/19/2016 14:09:38.0958] [1] 0.  ErrorRecord: System.Security.Cryptography.CryptographicException: The certificate is expired.
   at Microsoft.Exchange.Configuration.Tasks.Task.ThrowError(Exception exception, ErrorCategory errorCategory, Object target, String helpUrl)
   at Microsoft.Exchange.Configuration.Tasks.Task.WriteError(Exception exception, ErrorCategory category, Object target)
   at Microsoft.Exchange.Management.SystemConfigurationTasks.InstallExchangeCertificate.InternalProcessRecord()
   at Microsoft.Exchange.Configuration.Tasks.Task.<ProcessRecord>b__b()
   at Microsoft.Exchange.Configuration.Tasks.Task.InvokeRetryableFunc(String funcName, Action func, Boolean terminatePipelineIfFailed)
[01/19/2016 14:09:38.0958] [1] [ERROR] The following error was generated when "$error.Clear(); 
          Install-ExchangeCertificate -services IIS -DomainController $RoleDomainController
          if ($RoleIsDatacenter -ne $true -And $RoleIsPartnerHosted -ne $true)
          {
            Install-AuthCertificate -DomainController $RoleDomainController
          }
        " was run: "System.Security.Cryptography.CryptographicException: The certificate is expired.
   at Microsoft.Exchange.Configuration.Tasks.Task.ThrowError(Exception exception, ErrorCategory errorCategory, Object target, String helpUrl)
   at Microsoft.Exchange.Configuration.Tasks.Task.WriteError(Exception exception, ErrorCategory category, Object target)
   at Microsoft.Exchange.Management.SystemConfigurationTasks.InstallExchangeCertificate.InternalProcessRecord()
   at Microsoft.Exchange.Configuration.Tasks.Task.<ProcessRecord>b__b()
   at Microsoft.Exchange.Configuration.Tasks.Task.InvokeRetryableFunc(String funcName, Action func, Boolean terminatePipelineIfFailed)".
[01/19/2016 14:09:38.0958] [1] [ERROR] The certificate is expired.
[01/19/2016 14:09:38.0958] [1] [ERROR-REFERENCE] Id=BridgeheadExchangeCertificate___36d297b411f94919bc8c6ba9c9c39131 Component=EXCHANGE14:\Current\Release\Shared\Datacenter\Setup
[01/19/2016 14:09:38.0958] [1] Setup is stopping now because of one or more critical errors.

The key records were that Exchange setup has stumbled over the expired Exchange certificate. Therefore in order to fix it I had to scrap it from the local certificate store. To do this I have added Certificates console to MMC and pointed it to the Computer store of the local computer. Prior to this I uninstalled Exchange binaries (it uninstalled only Transport Services role) and IIS.



Then I navigated to the Personal store and Certificates container and removed expired certificate along with certs generated during previous installation attempts.



After removing a faulty certs I restarted a server and executed installation command as follows:

setup.exe /mode:install /roles:Mailbox,ClientAccess /IAcceptExchangeServerLicenseTerms /InstallWindowsComponents /DoNotStartTransport

As the result all the roles were successfully installed and server got into the fully functional state.

I hope it helps you if you're stuck with the same issue as I did.

Enjoy!


Monday, January 11, 2016

Deleting Mailbox Database in Multiforest Domain

Hi folks,

I would love to share my first Exchange adventure that I had in 2016. I needed to remove a mailbox database from the 2013 mailbox server that won't host mailboxes.

I have removed all kinds of the mailboxes from the database by moving them to another database. For details you can read this article as it's not worthy of time to go into the details which are already recorded and published. To make sure that nothing is left on the DB I have even retrieved all the soft deleted mailboxes (result of removal or move of mailbox to the other DB) by using this command:

Get-MailboxDatabase | Get-MailboxStatistics | Where { $_.DisconnectReason -eq "SoftDeleted" } | ft DisplayName,Database,MailboxGuid -AutoSize

I removed them by running the following command against each Mailbox GUID:

Remove-StoreMailbox -Identity XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX -Confirm:$false -Database DB001 -MailboxState SoftDeleted

But when running Remove-MailboxDatabase I was greeted by the following error:


Scratching my head lead me to remember that my AD forest has more than one domain with mailboxes. It lead me to this thread which contained a magic silver bullet to resolve this issue. All I needed to do is to run the following command:

Set-ADServerSettings -ViewEntireForest:$true

This allows to see mailboxes in the whole forest instead of only AD domain where Exchange servers are located. After connecting my PowerShell session to the whole forest I could retrieve mailboxes in the database by running and moving them to another DB:

Get-Mailbox -Database DB001|New-MoveRequest -TargetDatabase DB003

After all move requests have been successfully completed I removed them and removing mailbox DB was successful after I ran:

Remove-MailboxDatabase DB001 -Confirm:$false

Enjoy!