Use Exchange PowerShell to get statistical information for Exchange Server ActiveSync

Background:

To get information on EAS activity on an Exchange server, you will need to call Exchange PowerShell cmdlets. PowerShell is used for doing administrative work against Exchange. Each administrative task is done through an Exchange cmllet (command-let). Exchange PowerShell cmdlets can be called via .NET code through PowerShell automation. .NET PowerShell Automation refers to using .NET to leverage the PowerShell System.Management.Automation runspace in order to do calls to PowerShell cmdlets. So, the API to use is PowerShell and the methods to call would be the Exchange PowerShell cmdlets.

In versions of Exchange prior to Exchange 2007, there were many APIs which worked with Exchange. Many of those APIs did similar, but not all the same tasks and had different requirements. During the design phase of Exchange 2007, decisions were made to consolidate API access to Exchange down to just a few APIs and to eliminate many. This is why you will find that many older APIs are no longer supported. For mailbox access in general, Exchange Web Services (EWS) was deemed the primary go-ahead API and is heavily maintained and expanded upon since its debut in Exchange 2007. Extended MAPI is far too much used to be eliminated. For Exchange Administrators, something much more robust and scriptable than the older APIs was needed – an API and scripting ability which would be far beyond what currently existed and would be at least on-par with any other administrative platform – PowerShell was chosen for this. Many of the older APIs such as CDOEX, CDOEXM, Exoledb, Simple MAPI, WebDAV and others are not supported with new versions of Exchange.

PowerShell cannot only be used to issue commands and run scripts from a console, it can also be used as an API to run scripts on a local machine and additionally with PowerShell 2.0 on remote machines. All Exchange administrative functionality should be callable from script, from commands issued form the PowerShell Console or through .NET automation code. Even the Exchange administrative GUI uses these calls. Because of this, it should be possible to do just about any type of Exchange administrative task from your own custom code using just PowerShell automation calls – there may be limitations, however I have not run into any yet.

Exchange 2010:

If you’re planning on doing the reporting from a .NET application and are going against Exchange 2010, you would use Remote PowerShell calls against the Exchange CAS server. Your code would not need to run on an Exchange role machine. What would be need is that PowerShell 2.0 be installed, which it would be with our latest operating systems (Windows 7 and Windows 2008 R2).

How to call Exchange 2010 cmdlet's using Remote PowerShell in code
https://blogs.msdn.com/b/dvespa/archive/2009/10/22/how-to-call-exchange-2010-cmdlet-s-using-remote-powershell-in-code.aspx  

HOWTO: Using PowerShell in ASP.NET (.NET Framework 2.0)
https://blogs.msdn.com/b/akashb/archive/2009/01/30/howto-using-powershell-in-asp-net-net-framework-2-0.aspx  

What’s new in Windows PowerShell 2.0
https://blogs.technet.com/b/askperf/archive/2010/01/26/what-s-new-in-windows-powershell-2-0.aspx

Note that when doing remote PowerShell calls from a non-Exchange role server that you should avoid cmdlet aliases. Commands such as “select” may not work and you would need to use the full “select-object” instead.

Exchange 2007:  

If your planning on doing the reporting from a .NET application and are going against Exchange 2007, you would use Local PowerShell calls against the Exchange CAS server. Local Powershell calls against an Exchange 2007 server CAS need to be run from a machine which is in an Exchange 2007 server role; a basic box which has just the admin tools would be fine.

Howto: Calling Exchange PowerShell from an impersonated thread.
https://blogs.msdn.com/b/webdav_101/archive/2008/09/25/howto-calling-exchange-powershell-from-an-impersonated-thead.aspx

Links on Common PowerShell Automation Questions
https://blogs.msdn.com/b/webdav_101/archive/2008/09/26/links-on-common-powershell-automation-questions.aspx

Handling results of calling PowerShell - Multivalued and string arrays.
https://blogs.msdn.com/b/webdav_101/archive/2008/02/08/handling-results-of-calling-powershell-multivalued-and-string-arrays.aspx

EAS Informational PowerShell Cmdlets for Exchange 2010:

Understanding Exchange ActiveSync Reporting Services
https://technet.microsoft.com/en-us/library/bb201675.aspx#generating

Export-ActiveSyncLog
https://technet.microsoft.com/en-us/library/bb123821.aspx

Get-ActiveSyncMailboxPolicy
https://technet.microsoft.com/en-us/library/bb124900.aspx  

Get-ActiveSyncDevice
https://technet.microsoft.com/en-us/library/dd335068.aspx   

Get-ActiveSyncDeviceStatistics
https://technet.microsoft.com/en-us/library/aa996908.aspx  

Get-ActiveSyncDeviceClass
https://technet.microsoft.com/en-us/library/ff731393.aspx  

Get-ActiveSyncDeviceAccessRule
https://technet.microsoft.com/en-us/library/dd776124.aspx  

Here are some cmdlets which are helpful in gatering EAS connectivity settings:

Get-ActiveSyncMailboxPolicy
https://technet.microsoft.com/en-us/library/bb124900.aspx
 
Get-ActiveSyncDeviceAccessRule (2010 only)
https://technet.microsoft.com/en-us/library/dd776124.aspx

Get-ActiveSyncVirtualDirectory
https://technet.microsoft.com/en-us/library/aa996042.aspx

Troubleshooting .NET automation:

For troubleshooting issues which occur with doing powershell calls from .NET code, here are a few steps to try:

  • Run the same PowerShell call from th PowerShell shell and on the same box as the .NET code runs and using the same account to run the PowerShell call. This is important in determining if the issue is with the .NET code or not.
  • Run the same PowerShell call from th PowerShell shell and on the same box as the .NET code runs and using the same account to run the PowerShell call. Then start reducing the complexity of the call to its simplest form. 
  • If the issue only happens with .NET automation calls, then try using the simpest form of the cmdlet call and avoid cmdlet aliases. Be aware when to pass data as arguments and when to pass them as parameters.
  • Recheck the RBAC permissions being used to run the code against an Exchange 2010 server and the granted permissions against an Exchange 2007 server.