PowerShell Connector Toolkit

The PowerShell Connector Toolkit is not a complete connector in the traditional sense. Rather, it is a framework within which you must write your own PowerShell scripts to address the requirements of your Microsoft Windows ecosystem. You can use the PowerShell Connector Toolkit to create connectors that can provision any Microsoft system, including, but not limited to, Active Directory, Microsoft SQL, MS Exchange, SharePoint, Azure, and Office365. Essentially, any task that can be performed with PowerShell can be executed through connectors based on this toolkit.

The PowerShell Connector Toolkit is available from the ForgeRock BackStage download site.

IDM includes sample scripts for synchronization of users between Windows Active Directory and IDM. These sample scripts can help you get started with the PowerShell Connector toolkit. For more information, see Connect to Active Directory With the PowerShell Connector.

Before You Start

To implement a scripted PowerShell connector, you must install the following:

  • Microsoft .NET Framework 4.5 or later. Connectors created with the PowerShell Connector Toolkit run on the .NET platform and require the installation of a .NET connector server on the Windows system. To install the .NET connector server, follow the instructions in "Set Up a .NET Connector Server".

  • PowerShell version 4.0 or above.

  • The PowerShell Connector Toolkit.

Setting Up the PowerShell Connector

To run the commands in this procedure, start with the PowerShell command line. Some of the commands in this procedure require administrative privileges.

  1. Install, configure, and start the .NET connector server on a Windows host. If you are running an Active Directory Domain Controller, install the .NET connector server on the same host on which the Windows PowerShell module is installed.

  2. Configure IDM to connect to the .NET connector server.

  3. Download the PowerShell Connector Toolkit archive (mspowershell-connector-1.4.7.0.zip) from the ForgeRock BackStage download site.

    Extract the archive and move the MsPowerShell.Connector.dll to the folder in which the connector server application executable file (ConnectorServerService.exe) is located.

  4. The openidm\samples\scripted-powershell-with-ad directory contains sample scripts for a connection to Active Directory. Copy these scripts to the host on which the .NET connector server is installed.

    The full path to the scripts must be referenced in your connector configuration file (provisioner.openicf-*.json), for example:

    "CreateScriptFileName" : "C:/openidm/samples/scripted-powershell-with-ad/tools/ADCreate.ps1",
    ...
  5. Copy the sample connector configuration file (provisioner.openicf-adpowershell.json) from the samples\example-configurations\provisioners directory to your project's conf directory.

    Verify that at least the path to the scripts and the connection and authentication details are correct for your deployment. The following section describes the configurable properties in the sample connector configuration files.

    Note

    Paths in these files must use forward slash characters and not the backslash characters that you would expect in a Windows path.

Configuring the PowerShell Connector

Your PowerShell connector configuration file should include the following properties:

PropertyTypeExampleEncrypted [a] Required [b]
operationScriptFileName String C:/openidm/AD/ADCreate.ps1,

The full path to the script that implements the corresponding OpenICF operation.

VariablesPrefix String Connector

To avoid variable namespace conflicts, you can define a prefix for the connector variables. All variables are injected into the script under that prefix and can be used with the dotted notation.

QueryFilterType String AdPsModule (for Active Directory)

A configurable query filter visitor property that defines the format in which the query will be injected into the connector. Possible values are:

  • Map - the query filter is a map

  • Ldap - the query filter is in LDAP search format, for example, "(cn=Joe)"

  • Native - the query filter is a native OpenICF query filter

  • AdPsModule - the query filter is compatible with the Active Directory PowerShell module, Get-ADUser Filter

ReloadScriptOnExecution Boolean true

When true, the connector reloads the script from disk every time it is executed. This can be useful for debugging purposes. Set to false in production.

UseInterpretersPool Boolean true

If true, the connector leverages the PowerShell RunSpace Pool.

MaxInterpretersPoolSize Integer 5

The maximum size of the interpreter pool.

MinInterpretersPoolSize Integer 1

The minimum size of the interpreter pool.

PoolCleanupInterval Double 60

Specifies the interval (in minutes) at which unused interpreter instances are discarded. To avoid cleaning up unused interpreter instances, set this property to 0.

SubstituteUidAndNameInQueryFilter Boolean true

Specifies whether the __UID__ and __NAME__ should be replaced by the value defined in the NameAttributeName and UidAttributeName in the query filter.

UidAttributeName String ObjectGUID

The attribute on the resource that contains the object __UID__

NameAttributeName String DistinguishedName

The attribute on the resource that contains the object __NAME__

PsModulesToImport Array [ "ActiveDirectory", "C:/openidm/samples/scripted-powershell-with-ad/tools/ADSISearch.psm1"]

An array of additional PowerShell modules that the connector must import

Host String ad.example.com

The host name or IP address of the Active Directory server

Port Integer null

The port number on which the remote resource listens for connections

Login String ""

The user account in the remote resource that is used for the connection

Password String null

The password of the user account that is used for the connection

CustomProperties Array [ ]

An array of Strings to define custom configuration properties. Each property takes the format "name=value". For example:

"configurationProperties" : {
    ...
    "CustomProperties" : ["baseContext = CN=Users,DC=example,DC=com" ],
    ...
}

The custom property can then be read from the PowerShell scripts as follows: $base = $Connector.Configuration.PropertyBag.baseContext

[a] Indicates whether the property value is considered confidential, and therefore encrypted in IDM.

[b] A list of operations in this column indicates that the property is required for those operations.

Testing the PowerShell Connector

Start IDM with the configuration for your PowerShell connector project.

The following tests assume that the configuration is in the default path/to/openidm directory. If your PowerShell project is in a different directory, use the startup command with the -p option to point to that directory.

/path/to/openidm/startup.sh

Confirming the Connector Configuration

To test that the PowerShell connector has been configured correctly, run the following REST call:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
"http://localhost:8080/openidm/system?_action=test"
{
  "name" : "adpowershell",
  "enabled" : true,
  "config" : "config/provisioner.openicf/adpowershell",
  "objectTypes" : [ "__ALL__", "group", "account" ],
  "connectorRef" : {
    "connectorName" : "Org.Forgerock.OpenICF.Connectors.MsPowerShell.MsPowerShellConnector",
    "bundleName" : "MsPowerShell.Connector",
    "bundleVersion" : "[1.4.3.0,1.5.0.0)"
  },
  "displayName" : "PowerShell Connector",
  "ok" : true
}

When you run this test, you should also see a log entry associated with the .NET connector server, in the logs/ directory of that server.

Creating With the Connector

You can use the connector to create new users or groups on the target system, based on options listed in the relevant provisioner.openicf-* configuration file.

For example, the following command creates a new user in Active Directory:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
--header "content-type: application/json" \
--data '{
  "PasswordNeverExpires": false,
  "AlternateEmailAddresses": ["Robert.Smith@example.com"],
  "LastName": "Smith",
  "PreferredLanguage": "en-US",
  "FirstName": "Robert",
  "UserPrincipalName": "Robert.Smith@example.onmicrosoft.com",
  "DisplayName": "Robert Smith"
}' \
"http://localhost:8080/openidm/system/adpowershell/account?_action=create"

Updating With the Connector

The PowerShell scripts associated with update functionality support changes to the following properties:

  • Password

  • Principal Name

  • License

  • Common user attributes

As an example, you could use the following command to change the password for the user with the noted _id:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request PATCH \
--header "content-type: application/json" \
--data '{
  "operation": "replace",
  "Field": "password",
  "value": "Passw1rd"
}' \
"http://localhost:8080/openidm/system/adpowershell/account/1d4c9276-6937-4d9e-9c60-67e8b4207f4e"

Deleting With the Connector

You can use the PowerShell connector to delete user and group objects. The following command deletes a user in Active Directory, based on their _id:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request DELETE \
"http://localhost:8080/openidm/system/adpowershell/account/1d4c9276-6937-4d9e-9c60-67e8b4207f4e"

Running a Script on the Connector

The runScriptOnConnector script enables you to run an arbitrary script action through the connector. This script takes the following variables as input:

Configuration

A handler to the connector's configuration object.

Options

A handler to the Operation Options.

Operation

The operation type that corresponds to the action (RUNSCRIPTONCONNECTOR in this case).

Arguments

A map of script arguments (this can be null).

The script can return any object that can be serialized by OpenICF, such as Boolean, String, Array, or Dictionary. If the object type cannot be serialized, such as Hashtable, the script fails with the error:

"error": "No serializer for class: System.Collections.Hashtable"

To run an arbitrary script on the PowerShell connector, define the script in the systemActions property of your provisioner file:

"systemActions" : [
    {
        "scriptId" : "MyScript",
        "actions" : [
            {
                "systemType" : ".*PowerShellConnector",
                "actionType" : "PowerShell",
                "actionFile" : "scripts/Myactionscript.ps1"
            }
        ]
    }
]

When you have defined the script, you can call it over REST on the system endpoint, as follows:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
"http://localhost:8080/openidm/system/adpowershell?_action=script&scriptId=MyScript&param1=value1&param2=value2"

You can also call it through the IDM script engine, as follows:

openidm.action("/system/adpowershell", "script", {}, {"scriptId": "MyScript", "param1": "value1", "param2": "value2"})

Important

Because the action script is stored locally with IDM, it must be transmitted across the network every time it is called. An alternative approach is to write a PowerShell module and to load it using the PsModulesToImport option of the PowerShell connector. In this case, the action script is limited to a function call and you do not need a script file on the IDM side.

The following example uses the actionSource property in the provisioner, instead of the actionFile property, to call the action. The example calls a custom Set-Exchange function from a module loaded on the .Net connector server by the PowerShell connector:

"systemActions" : [
    {
        "scriptId" : "SetExchange",
        "actions" : [
            {
                "systemType" : ".*PowerShellConnector",
                "actionType" : "PowerShell",
                "actionSource" : "Set-Exchange $Connector.Arguments.dn"
            }
        ]
    }
]

Manage Azure AD Objects With the PowerShell Connector

ForgeRock provides two sets of sample scripts to let you manage objects in Azure AD with the PowerShell connector:

  • Version 1: These scripts are based on the older Microsoft Online (MSOL) V1 PowerShell module. For information on connecting to your Azure AD with this module, see the corresponding Microsoft documentation. Microsoft has expressed its intention to deprecate this module when its functionality has been completely migrated to the newer Azure Active Directory PowerShell for Graph Module. These scripts are supported only up to Windows 2012 R2.

    The Version 1 scripts can manage security groups but not dynamic groups.

  • Version 2: These scripts are based on the Azure Active Directory PowerShell for Graph Module. For information on connecting to your Azure AD with this module, see the corresponding Microsoft documentation. The cmdlets in this module let you perform CRUD operations on an Azure AD instance, and configure the directory and its features.

    The Version 2 scripts can manage user password policies, security and mail groups, dynamic groups, and devices.

Follow these procedures to use the sample Azure AD scripts with the PowerShell connector:

Set Up Your Systems
  1. Set up IDM.

    These steps assume that IDM 7 is running locally on a UNIX/Linux system.

  2. Install a .NET connector server on your windows host. These steps assume a Windows hostname of windows-host.example.com.

  3. On windows-host.example.com, install the PowerShell connector.

    When you have installed the PowerShell connector, make sure that the ICF .NET connector server is still running. If it is not running, restart the connector server and check the logs. In some cases, Windows blocks the PowerShell connector .dll files. If the connector server fails to start, right-click on MsPowerShell.Connector.dll and select Properties > Security. If you see the following text on that tab:

    This file came from another computer and might be blocked to help protect this computer.

    Click the Unblock button to unblock the connector .dll file. Then restart the connector server.

  4. On windows-host.example.com, install the Windows Azure AD Module that corresponds to the version of the scripts you are using.

  5. These instructions assume that you have an existing Azure AD instance.

    Create a specific administrative account in Azure AD, to run the PowerShell connector scripts.

  6. In a PowerShell window on windows-host.example.com, verify that your Windows host can connect to your Azure AD tenant:

    • For Version 1 scripts, run Connect-MsolService.

    • For Version 2 scripts, run Connect-AzureAD.

Set Up the PowerShell Azure AD Scripts

When all your systems are installed and running, and you have verified that your Windows host can connect to your Azure AD, set up the sample scripts as follows:

  1. On windows-host.example.com, create a directory for the PowerShell scripts, for example:

    PS C:\> mkdir -Path openidm\scripted-powershell-with-azure-ad\scripts

    Whatever location you choose for the scripts will be referenced in your connector configuration (provisioner file).

  2. Download the Azure AD scripts from the ForgeRock stash repository.

    Download either the V1 or V2 scripts, depending on your Azure AD module, and place them in the scripts directory you created in the previous step:

    ls C:\openidm\scripted-powershell-with-azure-ad\scripts
    Directory: C:\openidm\scripted-powershell-with-azure-ad\scripts
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---          7/21/2020  4:00 AM      10965 AzureADCreate.ps1
    -a---          7/21/2020  4:00 AM       3547 AzureADDelete.ps1
    -a---          7/21/2020  4:00 AM       6952 AzureADSchema.ps1
    -a---          7/21/2020  4:00 AM       8149 AzureADSearch.ps1
    -a---          7/21/2020  4:00 AM       2465 AzureADTest.ps1
    -a---          7/21/2020  4:00 AM      10840 AzureADUpdate.ps1

    Note

    By default, Windows does not trust downloaded scripts. To be able to run the scripts, you might need to do the following:

    • Run the Unblock-File cmdlet. This cmdlet unblocks PowerShell script files that were downloaded from the Internet so that you can run them, regardless of the PowerShell execution policy.

    • Change the PowerShell execution policy to let you run the scripts.

  3. On the IDM host, configure IDM to connect to the .NET connector server.

  4. On the IDM host, create a connector configuration file for the PowerShell connector in your project's conf directory.

    The ForgeRock stash repository includes a sample provisioner file for both versions of the scripts. Use those files as a starting point.

    Save the file as conf/provisioner.openicf-azureadpowershell.json and edit it to match your deployment. Set at least the following properties:

    • connectorHostRef: The name of the connector server referenced in the previous step.

    • *ScriptFileName: Set the path to the script directory that you created on windows-host.example.com.

Test the PowerShell Connector With Azure AD
  1. Start IDM.

  2. Test that the connector has been configured correctly and can reach the Azure AD:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request POST \
    "http://localhost:8080/openidm/system/azureadpowershell?_action=test"
    {
      "name": "azureadpowershell",
      "enabled": true,
      "config": "config/provisioner.openicf/azureadpowershell",
      "objectTypes": [
        "__ALL__",
        "account",
        "group"
      ],
      "connectorRef": {
        "bundleName": "MsPowerShell.Connector",
        "connectorName": "Org.ForgeRock.OpenICF.Connectors.MsPowerShell.MsPowerShellConnector",
        "bundleVersion": "[1.4.2.0,1.5.0.0)"
      },
      "displayName": "PowerShell Connector ",
      "ok": true
    }

    If you see no response from this connector test, check your connector configuration and the connection to the .NET connector server.

Read a different version of :