Difference between revisions of "PowerShell API Wrapper Tutorial"

[unchecked revision][unchecked revision]
(Created page with "__NOTOC__ ++ Under construction ++ This tutorial aims to explain the usage of the MailStore Server Administration API through simple examples based on Windows PowerShell ...")
 
Line 2: Line 2:
 
++ Under construction ++
 
++ Under construction ++
  
This tutorial aims to explain the usage of the [[MailStore Server Administration API]] through simple examples based on Windows PowerShell scripts. Basic knowledge of MailStore Server, Windows and PowerShell is a necessary precondition.
+
This tutorial aims to explain the usage of the [[MailStore Server Administration API]] through simple Windows PowerShell example scripts. Basic knowledge of MailStore Server, Windows and PowerShell is a necessary precondition.
  
 
The API wrapper used in this tutorial is an example implementation of a MailStore Server Administration API client. As communication with the Administration API is done via web requests, it is possible to create different implementations that use the corresponding PowerShell cmdlets. However, such implementations are out of scope of this tutorial.
 
The API wrapper used in this tutorial is an example implementation of a MailStore Server Administration API client. As communication with the Administration API is done via web requests, it is possible to create different implementations that use the corresponding PowerShell cmdlets. However, such implementations are out of scope of this tutorial.
Line 20: Line 20:
 
<p class=msnote><span class=mswarning>'''Important Notice:''' Installation of a Windows Management Framework on systems that require a specific version of Windows PowerShell, such as Microsoft Exchange Servers, is not supported and may lead to massive system failures and data loss.</span></p>
 
<p class=msnote><span class=mswarning>'''Important Notice:''' Installation of a Windows Management Framework on systems that require a specific version of Windows PowerShell, such as Microsoft Exchange Servers, is not supported and may lead to massive system failures and data loss.</span></p>
  
After downloading and installing of Windows PowerShell (if necessary) please unzip the MailStore PowerShell API Wrapper and the example scripts (to ''C:\MailStore Server Scripting Tutorial\PowerShell\'' by default).
+
After downloading and installing Windows PowerShell (if necessary) please unzip the MailStore PowerShell API Wrapper and the example scripts (to ''C:\MailStore Server Scripting Tutorial\PowerShell\'' by default).
  
 
Neither the MailStore PowerShell API Wrapper nor the example scripts are digitally signed, therefore execution of such scripts has to be enabled in an administrative PowerShell session using
 
Neither the MailStore PowerShell API Wrapper nor the example scripts are digitally signed, therefore execution of such scripts has to be enabled in an administrative PowerShell session using
Line 40: Line 40:
 
== Getting Information about the MailStore PowerShell API Wrapper ==
 
== Getting Information about the MailStore PowerShell API Wrapper ==
  
The MailStore PowerShell API Wrapper provides several functions and variables to access the MailStore Server Administration API according to PowerShell conventions. Enter the following command to get information about these features:
+
The MailStore PowerShell API Wrapper provides several functions and variables to access the MailStore Server Administration API, following PowerShell conventions. Enter the following command to get information about these features:
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
Line 46: Line 46:
 
</source>
 
</source>
  
Via the module's properties, more detailed information can be gained:</br>
+
Via the module's properties, more detailed information can be gained. For example,
For example,
 
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
Line 53: Line 52:
 
</source>
 
</source>
  
returns the variables provides by the module.<br/>
+
returns the variables provides by the module. Via
Via
 
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
Line 73: Line 71:
 
</source>
 
</source>
  
The function ''New-MSSApiClient'' creates a new API client object which is used by ''Invoke-MSSApiCall'' for API calls. The values for ''-Username, -Password, -MailStoreServer, -Port'' and ''-Code'' used in the script are the function's defaults, only the switch ''-IgnoreInvalidSSLCerts'' has to be set if untrusted certificates are used, otherwise an error occurs.
+
The function ''New-MSSApiClient'' creates a new API client object which the ''Invoke-MSSApiCall'' function uses for API calls. The values for ''-Username, -Password, -MailStoreServer, -Port'' and ''-Code'' used in the script are the function's defaults, only the switch ''-IgnoreInvalidSSLCerts'' has to be set if untrusted certificates are used; otherwise an error occurs.
  
 
Apart from the API client object, ''Invoke-MSSApiCall'' needs an [[MailStore_Server_Administration_API_Commands|API command]] and its parameters if applicable. The command ''[[MailStore_Server_Administration_API_Commands#GetServerInfo|GetServerInfo]]'' in the script does not have any parameters and returns an object as follows:
 
Apart from the API client object, ''Invoke-MSSApiCall'' needs an [[MailStore_Server_Administration_API_Commands|API command]] and its parameters if applicable. The command ''[[MailStore_Server_Administration_API_Commands#GetServerInfo|GetServerInfo]]'' in the script does not have any parameters and returns an object as follows:
Line 91: Line 89:
 
== Calling API Wrapper Functions with Parameters ==
 
== Calling API Wrapper Functions with Parameters ==
  
For most MailStore Server Administration API commands you need to provide parameters. Of course, the MailStore PowerShell API Wrapper's ''Invoke-MSSApiCall'' function can submit these parameters, as demonstrated in the following script (''Example2.ps1'' in the tutorial package):
+
For most MailStore Server Administration API commands you need to provide parameters. Of course, the MailStore PowerShell API Wrapper's ''Invoke-MSSApiCall'' function can submit these parameters, as demonstrated by the following script (''Example2.ps1'' in the tutorial package):
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
Line 100: Line 98:
 
</source>
 
</source>
  
The scripts lists details about the users created in MailStore Server. Because the MailStore PowerShell API Wrapper converts MailStore Server Management API answers into objects, their properties can be used directly in the script's workflow.
+
The scripts lists details about the users created in MailStore Server. Because the MailStore PowerShell API Wrapper converts MailStore Server Management API responses into objects, their properties can be used directly in the script's workflow.
  
The API command  ''[[MailStore_Server_Administration_API_Commands#GetUserInfo|GetUserInfo]]'' used in the script needs a parameter ''userName''. The function ''Invoke-MSSApiCall'' expects parameters as a hashtable, e.g. ''@{parametername1 = value1; parametername2 = value2;...}''. Parameter names are case sensitive.
+
The API command  ''[[MailStore_Server_Administration_API_Commands#GetUserInfo|GetUserInfo]]'' used in the script requires a parameter ''userName''. The function ''Invoke-MSSApiCall'' expects parameters as a hashtable, e.g. ''@{parametername1 = value1; parametername2 = value2;...}''. Parameter names are case sensitive.
  
 
First, MailStore Server's user list is requested with the API command  ''[[MailStore_Server_Administration_API_Commands#GetUserList|GetUserList]]'' which returns an array of user entries as follows:
 
First, MailStore Server's user list is requested with the API command  ''[[MailStore_Server_Administration_API_Commands#GetUserList|GetUserList]]'' which returns an array of user entries as follows:
Line 125: Line 123:
 
== Calling API Wrapper Functions for Asynchronous API Commands ==
 
== Calling API Wrapper Functions for Asynchronous API Commands ==
  
Administration API commands, whose execution typically take more time, are executed asynchronously by the server. The MailStore PowerShell API Wrapper identifies calls of such [[MailStore_Server_Administration_API#Asynchronously_Executed_Commands|asynchronously executed API commands]] and executes them as [http://technet.microsoft.com/en-us/library/hh847783%28v=wps.620%29.aspx PowerShell Job] in the background.
+
Administration API commands, whose execution typically take more time, are executed asynchronously on the server. The MailStore PowerShell API Wrapper identifies calls of such [[MailStore_Server_Administration_API#Asynchronously_Executed_Commands|asynchronously executed API commands]] and executes them as [http://technet.microsoft.com/en-us/library/hh847783%28v=wps.620%29.aspx PowerShell Job] in the background.
  
 
== Processing API Wrapper PowerShell Jobs Synchronously ==
 
== Processing API Wrapper PowerShell Jobs Synchronously ==
  
A script's execution can be interrupted until a PowerShell Job created by the API wrapper is finished as demonstrated in the following script (''Example3.ps1'' in the tutorial package):
+
A script's execution can be interrupted until a PowerShell Job created by the API wrapper terminates as demonstrated by the following script (''Example3.ps1'' in the tutorial package):
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
Line 149: Line 147:
 
   Data  : System.Management.Automation.PSRemotingJob
 
   Data  : System.Management.Automation.PSRemotingJob
  
Contrary to objects returned by synchronous API command calls, the ''Token'' property is now set and contains a unique ID returned by the server that identifies the server process; it is important for event handling (see below). The ''Data'' property contains the PowerShell Job which processes the status objects returned by the server in the background.
+
In contrast to objects returned by synchronous API command calls, the ''Token'' property now contains a unique ID returned by the server that identifies the server process; it is important for event handling (see below). The ''Data'' property contains the PowerShell Job which processes the status objects returned by the server in the background.
  
This PowerShell Job requests the status of its corresponding server process in regular intervalls (500ms by default) and is terminated when that process is finished. Through the PowerShell cmdlet [http://technet.microsoft.com/en-us/library/hh849735.aspx Wait-Job] the scripts waits until the job has been completed, getting its results through [http://technet.microsoft.com/en-us/library/hh849718.aspx Receive-Job]:
+
This PowerShell Job requests the status of its corresponding server process in regular intervalls (500ms by default) and is terminated when that process is finished. Through the PowerShell cmdlet [http://technet.microsoft.com/en-us/library/hh849735.aspx Wait-Job] the scripts waits until the job has been completed, getting the job's results through [http://technet.microsoft.com/en-us/library/hh849718.aspx Receive-Job]:
  
 
   Type      : JSON
 
   Type      : JSON
Line 162: Line 160:
 
== Processing API Wrapper PowerShell Jobs Asynchronously ==
 
== Processing API Wrapper PowerShell Jobs Asynchronously ==
  
Instead of interrupting a script's execution, the PowerShell Jobs created by the API wrapper can be reacted to while they are running in the background. These jobs trigger a PowerShell EngineEvent with each status request that the script can subscribe to execute further code on each occurrence. For this, the previous script needs to be adapted only a bit (''Example4.ps1'' in the tutorial package):
+
Instead of interrupting a script's execution, the PowerShell Jobs created by the API wrapper can be reacted to while they are running in the background. These jobs trigger a PowerShell EngineEvent with each status request that the script can subscribe to execute further code on each occurrence. To demonstrate this, the previous script needs to be adapted only a bit (''Example4.ps1'' in the tutorial package):
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">

Revision as of 16:43, 7 February 2014

++ Under construction ++

This tutorial aims to explain the usage of the MailStore Server Administration API through simple Windows PowerShell example scripts. Basic knowledge of MailStore Server, Windows and PowerShell is a necessary precondition.

The API wrapper used in this tutorial is an example implementation of a MailStore Server Administration API client. As communication with the Administration API is done via web requests, it is possible to create different implementations that use the corresponding PowerShell cmdlets. However, such implementations are out of scope of this tutorial.

Please note: It is strongly recommended to use a non-productive test environment for this tutorial as well as for script development in general, in order to prevent loss of data or other problems. For example, the 30-day-trial version of MailStore Server is perfectly suited for this.

Installation of Necessary Components

The examples demonstrated here use the MailStore PowerShell API Wrapper and are compatible with Windows PowerShell 3.0 and higher. Depending on your version of Windows it might be necessary to download and install a compatible version of PowerShell first. You can find the components necessary for this tutorial here:

Please take note of the system requirements and further notices for the respective version of the Windows Management Framework.

Important Notice: Installation of a Windows Management Framework on systems that require a specific version of Windows PowerShell, such as Microsoft Exchange Servers, is not supported and may lead to massive system failures and data loss.

After downloading and installing Windows PowerShell (if necessary) please unzip the MailStore PowerShell API Wrapper and the example scripts (to C:\MailStore Server Scripting Tutorial\PowerShell\ by default).

Neither the MailStore PowerShell API Wrapper nor the example scripts are digitally signed, therefore execution of such scripts has to be enabled in an administrative PowerShell session using

  Set-ExecutionPolicy -ExecutionPolicy Unrestricted

Importing the MailStore PowerShell API Wrapper

The MailStore PowerShell API Wrapper is implemented as a PowerShell Script Module (MSS.PS.Lib.psm1) and can thus be imported in a PowerShell session via its manifest (MSS.PS.Lib.psd1) by using Import-Module.

Please open a PowerShell session and import the API wrapper module using this command:

  Import-Module "C:\MailStore Server Scripting Tutorial\PowerShell\API-Wrapper\MSS.PS.Lib.psd1"

Getting Information about the MailStore PowerShell API Wrapper

The MailStore PowerShell API Wrapper provides several functions and variables to access the MailStore Server Administration API, following PowerShell conventions. Enter the following command to get information about these features:

  Get-Module MSS.PS.Lib | fl

Via the module's properties, more detailed information can be gained. For example,

  (Get-Module MSS.PS.Lib).ExportedVariables

returns the variables provides by the module. Via

  Get-Help *MSS*

the MailStore PowerShell API Wrapper returns inline help for all its functions.

Calling API Wrapper Functions

The following example script (Example1.ps1 in the tutorial package) explains the basic usage of MailStore PowerShell API Wrapper functions.

  Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
  $mssapiclient = New-MSSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -Code JSON -IgnoreInvalidSSLCerts
  $return = Invoke-MSSApiCall $mssapiclient "GetServerInfo"
  $return | fl

The function New-MSSApiClient creates a new API client object which the Invoke-MSSApiCall function uses for API calls. The values for -Username, -Password, -MailStoreServer, -Port and -Code used in the script are the function's defaults, only the switch -IgnoreInvalidSSLCerts has to be set if untrusted certificates are used; otherwise an error occurs.

Apart from the API client object, Invoke-MSSApiCall needs an API command and its parameters if applicable. The command GetServerInfo in the script does not have any parameters and returns an object as follows:

 Type  : JSON
 Token : 
 Data  : @{version=8.1.2.9268; machineName=DEMO}

The object's Type property corresponds either to the -Code parameter of the API client object ("JSON" or "XML") or has the value "JOB" for asynchronous API commands (see below); it characterizes the type of the object contained in the Data property. The Token property is also only relevant for asynchronous API commands.

The Data property contains the result returned by MailStore Server, in this case as a JSON object:

 PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return.Data | fl
 version     : 8.1.2.9268
 machineName : DEMO
 

Calling API Wrapper Functions with Parameters

For most MailStore Server Administration API commands you need to provide parameters. Of course, the MailStore PowerShell API Wrapper's Invoke-MSSApiCall function can submit these parameters, as demonstrated by the following script (Example2.ps1 in the tutorial package):

  Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
  $mssapiclient = New-MSSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -Code JSON -IgnoreInvalidSSLCerts
  $users = (Invoke-MSSApiCall $mssapiclient "GetUserList").Data
  foreach ($user in $users) {(Invoke-MSSApiCall $mssapiclient "GetUserInfo" @{userName = $user.userName}).Data | fl}

The scripts lists details about the users created in MailStore Server. Because the MailStore PowerShell API Wrapper converts MailStore Server Management API responses into objects, their properties can be used directly in the script's workflow.

The API command GetUserInfo used in the script requires a parameter userName. The function Invoke-MSSApiCall expects parameters as a hashtable, e.g. @{parametername1 = value1; parametername2 = value2;...}. Parameter names are case sensitive.

First, MailStore Server's user list is requested with the API command GetUserList which returns an array of user entries as follows:

 userName          : abby.hernandez
 fullName          : Abby Hernandez
 distinguishedName : CN=Abby Hernandez,OU=tutorial,DC=example,DC=com

The script now iterates over this array using the userName property of each entry as a parameter for the API command GetUserInfo. For the entry listed above the result could be as follows:

 userName            : abby.hernandez
 fullName            : Abby Hernandez
 distinguishedName   : CN=Abby Hernandez,OU=tutorial,DC=example,DC=com
 authentication      : directoryServices
 emailAddresses      : {[email protected]}
 pop3UserNames       : {}
 privileges          : {login}
 privilegesOnFolders : {@{folder=abby.hernandez; privileges=System.Object[]}}

As can be seen in the privilegesOnFolders property, returned objects may be nested and may also contain further objects.

Calling API Wrapper Functions for Asynchronous API Commands

Administration API commands, whose execution typically take more time, are executed asynchronously on the server. The MailStore PowerShell API Wrapper identifies calls of such asynchronously executed API commands and executes them as PowerShell Job in the background.

Processing API Wrapper PowerShell Jobs Synchronously

A script's execution can be interrupted until a PowerShell Job created by the API wrapper terminates as demonstrated by the following script (Example3.ps1 in the tutorial package):

  Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
  $mssapiclient = New-MSSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -Code JSON -IgnoreInvalidSSLCerts
  $return = invoke-MSSApiCall $mssapiclient "VerifyStore" @{id = "1"}
  if ($return.Type -eq "JOB") {
      Wait-Job $return.Data
      Receive-Job $return.Data
  } else {
      $return.Data
  }

The API command VerifyStore called in the script returns an object with the Type property "JOB".

 Type  : JOB
 Token : sa9e8d780329f1e0c59503a2e041f7c72b
 Data  : System.Management.Automation.PSRemotingJob

In contrast to objects returned by synchronous API command calls, the Token property now contains a unique ID returned by the server that identifies the server process; it is important for event handling (see below). The Data property contains the PowerShell Job which processes the status objects returned by the server in the background.

This PowerShell Job requests the status of its corresponding server process in regular intervalls (500ms by default) and is terminated when that process is finished. Through the PowerShell cmdlet Wait-Job the scripts waits until the job has been completed, getting the job's results through Receive-Job:

 Type       : JSON
 Token      : 
 Data       : @{status=succeeded; progressPercentage=100; messages=System.Collections.ArrayList}
 RunspaceId : 2eca1237-4504-4b63-a153-d326adf8c744

Please note: The RunspaceId is generated by the PowerShell automatically and can be ignored here.

Processing API Wrapper PowerShell Jobs Asynchronously

Instead of interrupting a script's execution, the PowerShell Jobs created by the API wrapper can be reacted to while they are running in the background. These jobs trigger a PowerShell EngineEvent with each status request that the script can subscribe to execute further code on each occurrence. To demonstrate this, the previous script needs to be adapted only a bit (Example4.ps1 in the tutorial package):

  Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
  
  $mssapiclient = New-MSSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -Code JSON -IgnoreInvalidSSLCerts
  $return = invoke-MSSApiCall $mssapiclient "VerifyStore" @{id = "1"}
  $return | fl
  if ($return.Type -eq "JOB") {
      $mssevent = Register-EngineEvent -SourceIdentifier $return.Token -Action {write-host $event.MessageData.Data}
  } else {
      $return.Data
  }

Here the script subscribes to the event that is triggered by the background job via Register-EngineEvent, using the return object's Token property as SourceIdentifier. By that property the event relates to the triggering PowerShell Job and thus to the server process. The Action script block is itself created as a PowerShell Job that is executed with each triggering of the event. Through the MessageData property of the $event automatic variable the script block can access the return object provided by the background job. That object's Data property contains the status of the server process:

 @{status=running; progressPercentage=0; messages=System.Collections.ArrayList}

Via these mechanisms the script can execute further tasks while monitoring the server process in the background. Execution and handling of multiple asynchronous API commands is also possible this way.