Reporting on Client Access Server Configurations

Exchange 2010 and Exchange 2013 are rich with cmdlets providing you access to information regarding your Exchange environment.

However, as of Exchange 2013 CU6, there are 956 (!!) cmdlets. Knowing which cmdlets to use can be challenging. It can also be difficult to decide what information from a cmdlet's output is relevant.

Here is my attempt to consolidate output for Client Access Servers. This script is in daily use, and it works for me. I hope you find it useful.

If this script is executed on an Exchange Server, it will by default generate information for that server. You can change that by specifying the "-server <servername>" switch. The "-location <location-name>" switch is used to specify a physical location where a particular server resides. For example "London" or "Charlotte". The script defaults to using "location". FInally, if you specify "-Verbose", the script will output timing information. That is, how long the script took to execute and how long each cmdlet took to execute.

Enjoy!


##
## Dump-CasInformation.ps1
##
## Michael B. Smith
## September 8, 2014
## michael at TheEssentialExchange dot com
## http://Essential.Exchange/blog
##
## No warranties, express or implied. Use at your own risk.
##
[CmdletBinding(SupportsShouldProcess=$false, ConfirmImpact='None') ]

Param(
	[Parameter(Mandatory=$false)]
	[string] $location  = "location",

	[Parameter(Mandatory=$false)]
	[string] $server    = $env:ComputerName
)

Set-Strictmode -Version 2.0

$startScript = Get-Date
Write-Verbose "Dump-Casinformation script starts $($startScript | Get-Date -Format u)"

$location = $location.ToUpper()

if( ( Get-Command Get-ExchangeServer -EA 0 ) -eq $null )
{
	Write-Error "This script must be executed within an Exchange Management Shell"
	return
}

"****** GLOBAL  GLOBAL  GLOBAL ******" 

	$cmd = 'OutlookProvider'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-OutlookProvider

		$r | fl Name, CertPrincipalName, Server, TTL, 
			OutlookProviderFlags, 
			RequiredClientVersions, ExchangeVersion

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'ExchangeServer'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-ExchangeServer -Status

		$r | fl Name, Identity, Fqdn, Edition, 
			Site, OrganizationalUnit, ServerRole, 
			AdminDisplayVersion, ExchangeVersion, 
			Static*, Current*,
			Is*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

"****** $location  $location  $location ******"

	$cmd = 'ClientAccessServer'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-ClientAccessServer -Identity $server

		$r | fl Name, Identity, Fqdn,
			IsOutOfService,
			OutlookAnywhereEnabled,
			ClientAccessArray,
			ExchangeVersion,
			AlternateServiceAccountConfiguration,
			OutlookAny*, 
			AutoDiscover*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'OutlookAnywhere'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-OutlookAnywhere -server $server

		$r | fl Server, ServerName, Name, Identity, 
			MetabasePath, Path, 
			AdminDisplayVersion, ExchangeVersion,
			SSLOffloading,
			InternalHostname, InternalClientAuth*,
			InternalClientsRequireSSL,
			ExternalHostname, ExternalClientAuth*, 
			ExternalClientsRequireSSL,
			IISAuthenticationMethods,
			XropUrl,
			ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'RpcClientAccess'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-RpcClientAccess -server $server

		$r | fl Name, Server, Identity,
			Responsibility,
			MaximumConnections,
			EncryptionRequired,
			BlockedClientVersions,
			ExchangeVersion

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'ActiveSync'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-ActiveSyncVirtualDirectory -server $server

		$r | fl Name, Server, VirtualDirectoryName, 
			WebsiteName, WebsiteSSLEnabled, CompressionEnabled,
			MetabasePath, Path,
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*,
			ExternalUrl, ExternalAuth*,
			ActiveSyncServer,
			*AuthEnabled, ClientCertAuth,
			Mobile*,
			BadItemReportingEnabled, SendWatsonReport,
			Remote*,
			Extended*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'AutoDiscover'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-AutodiscoverVirtualDirectory -server $server

		if( -not [String]::IsNullOrEmpty( $r.InternalUrl ) )
		{
			Write-Warning "InternalUrl should be empty, instead is $($r.InternalUrl)"
		}
		if( -not [String]::IsNullOrEmpty( $r.ExternalUrl ) )
		{
			Write-Warning "ExternalUrl should be empty, instead is $($r.ExternalUrl)"
		}

		$r | fl Server, Name, Identity, 
			MetabasePath, Path, 
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			*Authentication, ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'ECP'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-EcpVirtualDirectory -server $server

		$r | fl Server, Name, Website, DisplayName, Identity, 
			MetabasePath, Path, 
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			DefaultDomain, GzipLevel, *Enabled,
			*Authentication, ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	if( ( Get-Command Get-MapiVirtualDirectory -EA 0 ) -ne $null )
	{
		## cmdlet not available in Exchange 2010

		$cmd = 'MAPI'
		"*** $cmd  $cmd  $cmd ***"
		$cmdStart = Get-Date
		Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

			$r = Get-MapiVirtualDirectory -server $server

			$r | fl Server, Name, Identity, 
				MetabasePath, Path, 
				AdminDisplayVersion, ExchangeVersion,
				InternalUrl, InternalAuth*, 
				ExternalUrl, ExternalAuth*, 
				IISAuth*,
				ExtendedPro*

		$cmdEnd = Get-Date
		$cmdDelta = $cmdEnd - $cmdStart
		Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
		Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"
	}
	elseif( $server -ne $env:ComputerName )
	{
		Write-Warning "Get-MapiVirtualDirectory is not available on this computer (so this computer is probably running Exchange 2010). If you are accessing a server running Exchange 2013 or higher, this information will be missing."
		" "
	}

#####

	$cmd = 'OAB'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-OabVirtualDirectory -server $server

		$r | fl Server, Name, Identity, RequireSSL,
			MetabasePath, Path, 
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			PollInterval, OfflineAddressBooks,
			*Authentication, ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'OWA'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

	## OWA is just too big to process effectively

		$r = Get-OwaVirtualDirectory -server $server

		$r | fl Server, ServerName, Name, Website, DisplayName, Identity, RequireSSL,
			MetabasePath, Path, 
			DefaultDomain, LogonFormat,
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			VirtualDirectoryType, GzipLevel,
			Exchange2003Url, FailbackUrl, 
			LegacyRedirectType, RedirectToOptimalOWAServer,
			*Authentication, ExtendedPro*
		"...attribute list truncated, use 'Get-OwaVirtualDirectory -server $server | fl *' for full information"
		" "

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'PowerShell'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

	## this will return 2 entries for each server.
	"Note: the PowerShell Virtual Directory results include two vDirs for each server."

		$r = Get-PowerShellVirtualDirectory -server $server

		$r | fl Server, Name, Identity, RequireSSL,
			MetabasePath, Path, 
			OwaVersion, AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			VirtualDirectoryType, 
			*Authentication, ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

#####

	$cmd = 'WebServices'
	"*** $cmd  $cmd  $cmd ***"
	$cmdStart = Get-Date
	Write-Verbose "Dump-Casinformation command $cmd starts $($cmdStart | Get-Date -Format u)"

		$r = Get-WebServicesVirtualDirectory -server $server

		$r | fl Server, Name, Identity,
			MetabasePath, Path, 
			AdminDisplayVersion, ExchangeVersion,
			InternalUrl, InternalAuth*, 
			ExternalUrl, ExternalAuth*, 
			InternalNLBBypassUrl, GzipLevel, MRSProxyEnabled,
			*Authentication, ExtendedPro*

	$cmdEnd = Get-Date
	$cmdDelta = $cmdEnd - $cmdStart
	Write-Verbose "Dump-CasInformation command $cmd ends $($cmdEnd | Get-Date -Format u)"
	Write-Verbose "Dump-CasInformation command $cmd took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

"****** DONE  DONE  DONE ******"

$scriptEnd = Get-Date
$cmdDelta = $scriptEnd - $startScript
Write-Verbose "Dump-CasInformation script ends $($scriptEnd | Get-Date -Format u)"
Write-Verbose "Dump-CasInformation script took $($cmdDelta.TotalSeconds.ToString( 'N2' )) seconds"

Follow me on Twitter at @essentialexch

 

Leave a Reply

Your email address will not be published. Required fields are marked *