Difference between revisions of "PowerShell API Wrapper Tutorial"

[unchecked revision][checked revision]
m
 
(25 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
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.
+
<div class=msnote>'''Important notice:''' The PowerShell API wrapper for the MailStore Server Administration API provided on this website is to be regarded as an example implementation of an API client. This wrapper should help system administrators and developers to quickly understand how MailStore Server Administration API calls work and how to use them in their own scripts.<br/>
 +
Please understand that beyond this documentation no further support for the Powershell API wrapper is provided. Unless stated otherwise, the PowerShell API wrapper as well as all related example scripts are released under the terms and conditions of the [[wikipedia:MIT_License|MIT License]].</div>
  
<p class=msnote>'''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.</p>
+
 
 +
This tutorial aims to explain the usage of the [[Administration API - Using the API|Administration API]] through simple Windows PowerShell example scripts. Basic knowledge of MailStore Server, Windows and PowerShell is a necessary precondition. In order to prevent loss of data, service interruption or other problems, it is highly recommended to use a non-productive test environment for this tutorial as well as for script development in general. The {{go.mailstore.com|target{{=}}website&context{{=}}server-trial-download|30-day-trial version}} of MailStore Server is perfectly suited for this.
  
 
== Installation of Necessary Components ==
 
== 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:
 
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:
  
* [ftp://ftp.mailstore.com/pub/Scripts/PowerShell/v9/MailStore_Server_Scripting_Tutorial.zip MailStore PowerShell API Wrapper and tutorial example scripts]
+
* [[Media:MailStore_Server_Scripting_Tutorial.zip|MailStore PowerShell API Wrapper and tutorial example scripts]]
* [http://www.microsoft.com/en-us/download/details.aspx?id=34595 Windows Management Framework 3.0] (contains PowerShell 3.0)
+
* [https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/overview?view=powershell-5.1 Windows Management Framework] for your Operating System which includes the PowerShell
* [http://www.microsoft.com/en-us/download/details.aspx?id=40855 Windows Management Framework 4.0] (alternatively, contains PowerShell 4.0)
 
  
 
Please take note of the system requirements and further notices for the respective version of the Windows Management Framework.
 
Please take note of the system requirements and further notices for the respective version of the Windows Management Framework.
Line 60: Line 60:
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
   Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
 
   Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
   $mssapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
+
   $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
   $return = Invoke-MSApiCall $mssapiclient "GetServerInfo"
+
   $return = Invoke-MSApiCall $msapiclient "GetServerInfo"
 
   $return | fl
 
   $return | fl
 
</source>
 
</source>
  
The function ''New-MSApiClient'' creates a new API client object which the ''Invoke-MSApiCall'' function uses for API calls. The values for ''-Username, -Password, -MailStoreServer and -Port'' 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-MSApiClient'' creates a new API client object, which is used by the ''Invoke-MSApiCall'' function for API calls. The values for ''-Username, -Password, -MailStoreServer and -Port'' 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-MSApiCall'' 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:
 
  
  Type  : JSON
+
Apart from the API client object, ''Invoke-MSApiCall'' needs an [[Administration API - Function Reference|API command]] and its parameters if applicable. The command ''[[Administration API - Function Reference#GetServerInfo|GetServerInfo]]'' in the script does not have any parameters and returns a JSON object as follows:
  Token :
 
  Data  : @{error=; token=; statusVersion=2; statusCode=succeeded; percentProgress=; statusText=; result=; logOutput=}
 
  
The ''Type'' property characterizes the type of the object contained in the ''Data'' property. If the result has been returned immediately by the server, the object's ''Type'' property has the value "JSON". If the server needs some time to answer the request (mostly for asynchronous API commands, see below), the value is "JOB".  The ''Token'' property is only relevant in the latter case.
+
   PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return | fl
 
 
The ''Data'' property contains the status of the API call returned by MailStore Server as a JSON object:
 
 
 
   PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return.Data | fl
 
 
   error          :  
 
   error          :  
 
   token          :  
 
   token          :  
Line 84: Line 76:
 
   percentProgress :  
 
   percentProgress :  
 
   statusText      :  
 
   statusText      :  
   result          : @{version=9.0.3.9845; machineName=PC001}
+
   result          : @{version=9.1.0.10258; machineName=PC001}
 
   logOutput      :  
 
   logOutput      :  
  
 
If the call has succeeded, the status object's ''result'' property contains another JSON object with the data returned by the function:
 
If the call has succeeded, the status object's ''result'' property contains another JSON object with the data returned by the function:
  
   PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts> $return.data.result | fl
+
   PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return.result | fl
   version    : 9.0.3.9845
+
   version    : 9.1.0.10258
 
   machineName : PC001
 
   machineName : PC001
 
+
 
=== Calling API Wrapper Functions with Parameters ===
+
=== Providing Parameters ===
 
For most MailStore Server Administration API commands you need to provide parameters. Of course, the MailStore PowerShell API Wrapper's ''Invoke-MSApiCall'' function can submit these parameters, as demonstrated by 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-MSApiCall'' function can submit these parameters, as demonstrated by the following script (''Example2.ps1'' in the tutorial package):
  
Line 99: Line 91:
 
   Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
 
   Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
 
   $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
 
   $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
   $users = (Invoke-MSApiCall $msapiclient "GetUsers").Data.result
+
   $users = (Invoke-MSApiCall $msapiclient "GetUsers").result
   foreach ($user in $users) {(Invoke-MSApiCall $msapiclient "GetUserInfo" @{userName = $user.userName}).Data.result | fl}
+
   foreach ($user in $users) {(Invoke-MSApiCall $msapiclient "GetUserInfo" @{userName = $user.userName}).result | fl}
 
</source>
 
</source>
  
 
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 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 requires a parameter ''userName''. The function ''Invoke-MSApiCall'' expects parameters as a hashtable, e.g. ''@{parametername1 = value1; parametername2 = value2;...}''. Parameter names are case sensitive.
+
The API command  ''[[Administration API - Function Reference#GetUserInfo|GetUserInfo]]'' used in the script requires a parameter ''userName''. The function ''Invoke-MSApiCall'' 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|GetUsers]]'' which returns an array of user entries as follows:
+
First, MailStore Server's user list is requested with the API command  ''[[Administration API - Function Reference#GetUserList|GetUsers]]'' which returns an array of user entries as follows:
 
    
 
    
 
   userName          : abby.hernandez
 
   userName          : abby.hernandez
Line 113: Line 105:
 
   distinguishedName : CN=Abby Hernandez,OU=tutorial,DC=example,DC=com
 
   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  ''[[MailStore_Server_Administration_API_Commands#GetUserInfo|GetUserInfo]]''. For the entry listed above the result could be as follows:
+
The script now iterates over this array using the ''userName'' property of each entry as a parameter for the API command  ''[[Administration API - Function Reference#GetUserInfo|GetUserInfo]]''. For the entry listed above the result could be as follows:
  
 
   userName            : abby.hernandez
 
   userName            : abby.hernandez
Line 126: Line 118:
 
As can be seen in the ''privilegesOnFolders'' property, returned objects may be nested and may also contain further objects.
 
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 ===
+
=== Handling Asynchronous API Calls ===
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 Jobs] in the background.
+
The server may decide to execute Administration API commands asynchronously if their execution takes more time. The MailStore PowerShell API Wrapper can either wait for such [[Administration API - Using the API#Long Running Processes|asynchronously executed API commands]] to complete or run them as [http://technet.microsoft.com/en-us/library/hh847783%28v=wps.620%29.aspx PowerShell Jobs] in the background.
  
=== Processing API Wrapper PowerShell Jobs Synchronously ===
+
==== Waiting for Asynchronous API Calls to Complete ====
 
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):
 
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">
   Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
+
   Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
   $mssapiclient = New-MSSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -Code JSON -IgnoreInvalidSSLCerts
+
   $msapiclient = New-MSApiClient -Username "admin" -Password "admin" -Server "localhost" -Port 8463 -IgnoreInvalidSSLCerts
   $return = invoke-MSSApiCall $mssapiclient "VerifyStore" @{id = "1"}
+
   $return = Invoke-MSApiCall $msapiclient "VerifyStore" @{id = "1"}
   if ($return.Type -eq "JOB") {
+
   $return | fl
      Wait-Job $return.Data
 
      Receive-Job $return.Data
 
  } else {
 
      $return.Data
 
  }
 
 
</source>
 
</source>
  
The  API command ''[[MailStore_Server_Administration_API_Commands#VerifyStore|VerifyStore]]'' called in the script returns an object with the ''Type'' property "JOB".
+
By using ''Invoke-MSApiCall'' the API wrapper waits for an API command that is executed asynchronously by MailStore Server to complete and simply returns its final result.
  
  Type  : JOB
+
==== Subscribing to Events Triggered by Asynchronous API Calls ====
  Token : sa9e8d780329f1e0c59503a2e041f7c72b
+
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 in order 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):
  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.
+
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 +
  Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
 +
  $msapiclient = New-MSApiClient -Username "admin" -Password "admin" -Server "localhost" -Port 8463 -IgnoreInvalidSSLCerts
 +
  $return = Start-MSApiCall $msapiclient "VerifyStore" @{id = "1"}
 +
  if ($return.statusCode -eq "running") {
 +
      $mssevent = Register-EngineEvent -SourceIdentifier $return.Token -Action {write-host $event.MessageData}
 +
  } else {
 +
      $return | fl
 +
  }
 +
</source>
  
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]:
+
By using ''Start-MSApiCall'' the API wrapper runs an API command that is executed asynchronously by MailStore Server in the background and returns its first result. The script subscribes to the event that is triggered by the background job via [http://technet.microsoft.com/en-us/library/hh849967.aspx 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'' [http://technet.microsoft.com/en-us/library/hh847768.aspx automatic variable] the script block can access the return object provided by the background job. That object contains the status of the server process:
  
   Type      : JSON
+
   @{error=; token=e2b7c58ff37df64e2b62bb02bde9bbfd; statusVersion=77; statusCode=running; percentProgress=95; statusText=; result=; logOutput=  1400 messages verified...}
  Token      :
 
  Data      : @{status=succeeded; progressPercentage=100; messages=System.Collections.ArrayList}
 
  RunspaceId : 2eca1237-4504-4b63-a153-d326adf8c744
 
  
<p class=msnote>'''Please note:''' The ''RunspaceId'' is generated by the PowerShell automatically and can be ignored here.</p>
+
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.
  
=== Processing API Wrapper PowerShell Jobs Asynchronously ===
+
==== Cancelling Asynchronous API Calls ====
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):
+
To cancel the execution of an asynchronous API command, use ''Stop-MSApiCall'' with either the token or the return object. For the example above the call would be:
  
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
   Import-Module '..\API-Wrapper\MSS.PS.Lib.psd1'
+
   Stop-MSApiCall $MSApiclient -AsyncReturnObject $return
 
 
  $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
 
  }
 
 
</source>
 
</source>
 +
=== Pinning the TLS version ===
  
Here the script subscribes to the event that is triggered by the background job via [http://technet.microsoft.com/en-us/library/hh849967.aspx 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'' [http://technet.microsoft.com/en-us/library/hh847768.aspx 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:
+
The API Wrapper supports TLS1.2, TLS1.1 and TLS1.0 connections and uses the highest version available. In case only a specific TLS version should be used, the ''SecurityProtocol'' parameter can be used. The supported values are ''Tls12'', ''Tls11'' and ''Tls''.
  
  @{status=running; progressPercentage=0; messages=System.Collections.ArrayList}
+
<source lang="powershell" smart-tabs="true" toolbar="false" gutter="false">
 
+
  Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
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.
+
  $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts -SecurityProtocol Tls12
 
+
</source>
[[de:PowerShell API-Wrapper Tutorial]]
 
[[en:PowerShell API Wrapper Tutorial]]
 

Latest revision as of 09:31, 15 June 2022


Important notice: The PowerShell API wrapper for the MailStore Server Administration API provided on this website is to be regarded as an example implementation of an API client. This wrapper should help system administrators and developers to quickly understand how MailStore Server Administration API calls work and how to use them in their own scripts.
Please understand that beyond this documentation no further support for the Powershell API wrapper is provided. Unless stated otherwise, the PowerShell API wrapper as well as all related example scripts are released under the terms and conditions of the MIT License.


This tutorial aims to explain the usage of the Administration API through simple Windows PowerShell example scripts. Basic knowledge of MailStore Server, Windows and PowerShell is a necessary precondition. In order to prevent loss of data, service interruption or other problems, it is highly recommended to use a non-productive test environment for this tutorial as well as for script development in general. 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 (MS.PS.Lib.psm1) and can thus be imported in a PowerShell session via its manifest (MS.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\MS.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 MS.PS.Lib | fl

More detailed information is available through the module's properties. For example,

  (Get-Module MS.PS.Lib).ExportedFunctions

returns the functions provided by the module. Via

  Get-Help *MSApi*

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\MS.PS.Lib.psd1'
  $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
  $return = Invoke-MSApiCall $msapiclient "GetServerInfo"
  $return | fl

The function New-MSApiClient creates a new API client object, which is used by the Invoke-MSApiCall function for API calls. The values for -Username, -Password, -MailStoreServer and -Port 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-MSApiCall needs an API command and its parameters if applicable. The command GetServerInfo in the script does not have any parameters and returns a JSON object as follows:

 PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return | fl
 error           : 
 token           : 
 statusVersion   : 2
 statusCode      : succeeded
 percentProgress : 
 statusText      : 
 result          : @{version=9.1.0.10258; machineName=PC001}
 logOutput       : 

If the call has succeeded, the status object's result property contains another JSON object with the data returned by the function:

 PS C:\MailStore Server Scripting Tutorial\PowerShell\Scripts>$return.result | fl
 version     : 9.1.0.10258
 machineName : PC001

Providing Parameters

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

  Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
  $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts
  $users = (Invoke-MSApiCall $msapiclient "GetUsers").result
  foreach ($user in $users) {(Invoke-MSApiCall $msapiclient "GetUserInfo" @{userName = $user.userName}).result | 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-MSApiCall 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 GetUsers 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.

Handling Asynchronous API Calls

The server may decide to execute Administration API commands asynchronously if their execution takes more time. The MailStore PowerShell API Wrapper can either wait for such asynchronously executed API commands to complete or run them as PowerShell Jobs in the background.

Waiting for Asynchronous API Calls to Complete

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\MS.PS.Lib.psd1'
  $msapiclient = New-MSApiClient -Username "admin" -Password "admin" -Server "localhost" -Port 8463 -IgnoreInvalidSSLCerts
  $return = Invoke-MSApiCall $msapiclient "VerifyStore" @{id = "1"}
  $return | fl

By using Invoke-MSApiCall the API wrapper waits for an API command that is executed asynchronously by MailStore Server to complete and simply returns its final result.

Subscribing to Events Triggered by Asynchronous API Calls

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 in order 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\MS.PS.Lib.psd1'
  $msapiclient = New-MSApiClient -Username "admin" -Password "admin" -Server "localhost" -Port 8463 -IgnoreInvalidSSLCerts
  $return = Start-MSApiCall $msapiclient "VerifyStore" @{id = "1"}
  if ($return.statusCode -eq "running") {
      $mssevent = Register-EngineEvent -SourceIdentifier $return.Token -Action {write-host $event.MessageData}
  } else {
      $return | fl
  }

By using Start-MSApiCall the API wrapper runs an API command that is executed asynchronously by MailStore Server in the background and returns its first result. 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 contains the status of the server process:

 @{error=; token=e2b7c58ff37df64e2b62bb02bde9bbfd; statusVersion=77; statusCode=running; percentProgress=95; statusText=; result=; logOutput=  1400 messages verified...}

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.

Cancelling Asynchronous API Calls

To cancel the execution of an asynchronous API command, use Stop-MSApiCall with either the token or the return object. For the example above the call would be:

  Stop-MSApiCall $MSApiclient -AsyncReturnObject $return

Pinning the TLS version

The API Wrapper supports TLS1.2, TLS1.1 and TLS1.0 connections and uses the highest version available. In case only a specific TLS version should be used, the SecurityProtocol parameter can be used. The supported values are Tls12, Tls11 and Tls.

  Import-Module '..\API-Wrapper\MS.PS.Lib.psd1'
  $msapiclient = New-MSApiClient -Username admin -Password admin -MailStoreServer localhost -Port 8463 -IgnoreInvalidSSLCerts -SecurityProtocol Tls12