Starting with Server 5.5, PowerShell is supported for developing Automations and Integrations. PowerShell Integrations and Automations are executed using PowerShell Core. Version 6.2 and higher of PowerShell Core is supported.
Note for Partners/Contributors: As support for PowerShell is available from Server version 5.5+ (released April 2020), for the widest audience we recommend to develop your Integrations in Python until adoption by customers of Server 5.5 increases. Additionally, most of our customers have a better understanding of Python compared to PowerShell, thus developing in Python will allow them to easily contribute back fixes and improvements. You should choose to develop your integration in PowerShell only if you've invested extensively already in PowerShell (for example you have a product SDK written in PowerShell), your Integration requires technologies available only in PowerShell (for example Microsoft based SDKs available only in PowerShell), or your development capabilities are significantly greater in PowerShell versus Python.
Similar to Python, PowerShell Integrations and Automations run in a Docker container. All of the Demisto Docker images that support PowerShell are named with a prefix of either
demisto/pwsh. If you need to create a new image follow the instructions at the
demisto/dockerfiles project: https://github.com/demisto/dockerfiles.
Similar to Python, PowerShell Integrations/Automations should follow the Directory Structure. With a slight difference that unit test files should be named:
<IntegrationFileName>.Tests.ps1 (Pester Unit Testing naming convention). You can use
demisto-sdk split-yml to convert an exported PowerShell Integration/Automation to the Directory Structure (more info here).
We use PSScriptAnalyzer for linting and static code analysis of PowerShell Integrations/Automations. If you receive a false positive from the Analyzer, you can suppress the rule by decorating the function/script with
SuppressMessageAttribute. Make sure to specify a
Justification in the attribute why the suppression was necessary. An example usage of suppression can be seen here. PSScriptAnalyzer suppression documentation is available here.
Follow the same guidelines for writing unit tests as recommended for Python. Unit tests should avoid performing communication with external APIs and should prefer to use mocking. Testing actual interaction with external APIs should be performed via Test Playbooks.
For running the unit tests we use Pester.
Make sure your code imports
CommonServerPowerShell.ps1. The import should be done by adding the following line to the start of the file:
When the Integration/Automation code is unified by
demisto-sdk for deployment to the Server the import line is automatically removed.
Main in Integration/Automation Code#
When writing unit tests you will import the Integration/Automation file from the
*.Tests.ps1 file. Thus, there is need to make sure that the file is written in such a way that when importing, it will not execute. This can be done with a simple
Main function which is called depending on how the file was executed. When the Integration/Automation script is imported by the unit test file we will not execute the
Main function. Adding the following code will ensure the script is not run when imported by the unit tests:
All unit tests should be written in a separate PowerShell file named:
<IntegrationFileName>.Tests.ps1 (Pester Unit Testing naming convention). The unit test file should import the Integration/Automation code file by adding the following line at the start of the file:
Group related unit tests using the
Describe block. Use
Context for grouping tests that use the same mock logic. Write your tests using the
It command. For more details see the Pester Docs. Example unit tests can be seen at: VerifyJSON.
Pester supports mocking PowerShell functions. You can mock any function defined in CommonServerPowerShell.ps1 and functions included in standard PowerShell and imported modules. Pester doesn't support mocking object methods. This includes methods of the
$demisto object. You can however modify the
$demisto object properties in a test. For example you can set the
ContextArgs property to control the return of
$demisto.Args() method. Example code:
Additionally, you can mock functions called by the
$demisto object. For example you can mock
DemistoServerLog which is called by the
$demisto object methods:
Info, Debug, Error. Example of using mocking can be seen at: VerifyJSON. More info about Pester Mocking is available here.
CircleCI build will run the unit tests within the docker image the Integration/Automation will run with. It is recommended to use this method to run linting and tests as it uses exactly the same environment (docker container) with all modules and OS dependencies that are used by the Integration/Automation. To run both linting and testing run:
Tip: Use the command line params
--no-pwsh-test to skip either the PSScriptAnalyzer or unit testing.
Make sure to install Pester, PSScriptAnalyzer and all dependent modules. Run
demisto-sdk lint -i ... to copy
demistomock.ps1 to the Integration/Automation directory. Enter the pwsh console and change into the Integration/Automation directory.
To run unit tests use Pester:
To run PSScriptAnalyzer:
Check the command help on how to specify specific tests to run.
We recommend using VSCode as a PowerShell editor. The PowerShell Extension developed by Microsoft comes with built-in support for PSScriptAnalyzer and Pester unit testing (including Debugging).
Sample output of PSScriptAnalyzer in VS Code alerting about an unused variable:
Sample debug session using VS Code: