Create custom actions - Power Automate (2023)

  • Article

[This article is pre-release documentation and is subject to change.]

You can extend Power Automate for desktop through the Actions SDK (Preview). Through the SDK,custom modulesit can be created and then used through desktop flows.

Use

  • The termmodulesis equivalent to the termcustom action group(preview) and is used to describe custom action groups (preview) from a pro-developer perspective in this article.
  • HeActions SDK (Preview)yPower Automate Desktop - Visual Studio templates (preview)are available as a preview version.

previous requirements

To create custom actions in Power Automate for desktop, you need:

  • .NET Framework 4.7.2 SDK o posterior.
  • An IDE (Integrated Development Environment like Visual Studio 2022).
  • Power Automate for desktop v2.32 or later.
  • The actions SDK.

This article uses Visual Studio 2022.

Using Power Automate desktop actions - Visual Studio templates (preview)

Use

Power Automate Desktop Actions: Visual Studio (Preview) templates are only supported in Visual Studio 2022 or later when using Visual Studio as the IDE.

You have two options for installing Power Automate Desktop Actions: Visual Studio templates (preview).

Option 1

  • Download the NuGet package that contains the templates, atnuget.org.

  • Run the following command in the Visual Studio Package Manager with the appropriate path.

    dotnet new -i

option 2

Run the following command in the Visual Studio Package Manager.

dotnet nuevo -i Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.Templates

Here is a summary of the steps required to create custom actions in Power Automate for desktop:

  1. Create a new project with Power Automate Desktop Actions - Visual Studio Templates (Preview).
  2. Build your project.
  3. Sign the generated .dll file with a trusted certificate.
  4. Package the generated .dll file along with all its dependencies into a .cab file.
  5. Sign the .cab file.

Use

  • Make sure that the .dll files that describe custom actions (preview), their dependency .dll files, and .cab files are properly signed with a digital certificate that is trusted by your organization. The certificate must also be installed on the device under the trusted root certificate authority where the desktop flow with custom action dependencies is running.
  • Each project (.dll file) that references the SDK is a module (group of custom actions).
  • Module actions are represented by classes within that project.

After installing the Power Automate Desktop Actions templates for Visual Studio (Preview), open Visual Studio and select one of the following options:

Create custom actions - Power Automate (1)

project templateDescription
Empty Power Automate moduleCreate an empty project with the references needed to create a custom Power Automate module.
Power Automate sample moduleCreate a sample project that contains an action with the references needed to create a custom Power Automate module.

Use

The following examples use the Power Automate sample module project (a project that includes a simple action (Action1.cs)).

Here's what Action1.cs looks like after creating a sample Power Automate module:

using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;using System;namespace Modules.CustomModule{ [Action(Id = "Action1", Order = 1)] [Throws("ActionError")] // TODO: rename the error (or remove it if not needed) public class Action1 : ActionBase { #region Properties // NOTE: An example description and friendly name entries can be found at Resources [InputArgument] public string InputArgument1 { get; place; } [Output argument] public string Output argument1 { get; place; } #endregion #region Methods Overrides public override void Execute(ActionContext context) { try { OutputArgument1 = $"Hello World ${InputArgument1}"; } catch (Exception e) { if (e is ActionException) throw; throw new ActionException("ActionError", e.Message, e.InnerException); } } #endregion }}

Actions can have parameters (input or output). Input and output parameters are represented by C# properties.

Each property must have an appropriate C# attribute,[Input Argument]o[output argument]to dictate their type and how they are presented in Power Automate for desktop. Actions can also be organized into categories by setting the Category property of the Action attribute.

You can pre-populate the parameters by setting a default value C# attribute.

For example, the default value of InputArgument is "Developer". In this example, modifying theExecutemethod to return an output, your custom action should look like this:

using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;using System;using System.ComponentModel;namespace Modules.CustomModule{ [Action(Id = "Action1 ", Order = 1, Category = "TestCategory")] [Throws("ActionError")] // TODO: rename the error (or remove it if not necessary) public class Action1 : ActionBase { #region Properties // NOTE : You can find a sample description and friendly name inputs in Resources [InputArgument, DefaultValue("Developer")] public string InputArgument1 { get; place; } [Output argument] public string Output argument1 { get; place; } #endregion #region Methods Overrides public override void Execute(ActionContext context) { try { OutputArgument1 = $"Hello, {InputArgument1}"; } catch (Exception e) { if (e is ActionException) throw; throw new ActionException("ActionError", e.Message, e.InnerException); } } #endregion }}

Custom module naming conventions

For custom modules to be read by Power Automate for desktop, AssemblyName must have a file name that follows the following pattern:

?*.Modules.?*Modules.?*

For example,Modules.ContosoActions.dll

The AssemblyTitle in the project configuration specifies the module ID. It can only have alphanumeric characters and underscores and must start with a letter.

Custom Module IDs

Each module has its own ID.

Create custom actions - Power Automate (2)

When creating custom modules, be sure to establish unique module IDs.

Adding Descriptions to Custom Actions (Preview)

It is recommended that you provide a description and a friendly name for the module and its respective actions so that users of Power Automate for desktop know how to best use them.

Friendly names and descriptions are displayed in the Power Automate for desktop designer.

Modify the "Resources.resx" file in the "Properties" of the project to add a description.

The format of the descriptions of the modules and actions must be the following:

"Module_Description" or "Action_Description" and "Module_FriendlyName" or "Action_FriendlyName" respectively in the name field. The description in the value field.

It is also recommended that you provide descriptions and friendly names for the parameters. Its format should be as follows: "Action_Parameter_Description", "Action_Parameter_FriendlyName".

These can also be set with the FriendlyName and Description properties of the[Input Argument],[output argument]y[Action]attributes

Here is an example of aResources.resxfile for a custom module.

Create custom actions - Power Automate (3)

Advice

Consider adding comments in theComment(like a module or an action).

Another way to quickly add friendly names and descriptions to actions and parameters is with the FriendlyName and Description properties on the[Action],[Input Argument]y[output argument]attributes

Use

To add a friendly name and description to a module, you must modify the respective .resx file.

Resource location

The default language for modules in Power Automate for desktop is assumed to be English.

HeResources.resxThe file must be in English.

Any other language can be added with additional resources.{locale}.resx files for localization. For example,Resources.fr.resx.

Create actions without using Power Automate Desktop Visual Studio templates (preview)

Start by creating a new Class Library (.NET Framework) project. Select .NET framework version 4.7.2.

Add the Actions SDK (Preview) to your project.

To form an action in the created custom module:

  • Delete the automatically generated Class1.cs file.
  • Create a new class within your project to represent the custom action and give it a different name.
  • Include the namespaces Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK and Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes.
  • All classes that represent actions must have an [Action] attribute on their class.
  • The class must have public access and inherit from the ActionBase class.
usando System; usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK; usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;namespace Modules.MyCustomModule{ [Action(Id = "CustomAction")] public class CustomAction : ActionBase { public override void Execute(ActionContext context) { throw new NotImplementedException(); } }}

Most actions have parameters (Input or Output). Input and output parameters are represented by classic C# properties. Each property must have a suitable C# attribute, either[Input Argument]o[output argument]to dictate their type and how they are presented in Power Automate for desktop. Input arguments can also have default values.

usando System.ComponentModel;usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;namespace Modules.MyCustomModule{ [Action(Id = "CustomAction")] clase pública CustomAction: ActionBase { [InputArgument, DefaultValue("Developer")] public string InputName { get; colocar; } [Argumento de salida] public string DisplayedMessage { get; colocar; } public override void Execute(ActionContext context) { DisplayedMessage = $"Hola, {InputName}"; } }}

Adding descriptions to custom actions (preview) created from scratch

Add a friendly name and description for modules and actions so that RPA developers know how to best use them.

Power Automate for desktop designer displays descriptive names and descriptions.

You can create a "Resources.resx" file inside the module project Properties folder. The new ".resx" file should be named "Resources.resx".

The format of the descriptions of Modules and Actions must be the following:

"Module_Description" or "Action_Description" and "Module_FriendlyName" or "Action_FriendlyName" respectively in the name field. The description in the value field.

It is also recommended that you provide descriptions and friendly names for the parameters. Its format should be as follows: "Action_Parameter_Description", "Action_Parameter_FriendlyName".

Create custom actions - Power Automate (4)

Use

It is recommended to indicate what you are describing in the comment field (for example, Module, Action, etc.)

Custom Module Categories

The modules can include categories and subcategories for a better organization of the actions.

To separate custom actions into categories, subcategories, modify the[Action]attribute that precedes the class that represents the custom action as follows:

[Action(Category = "category.subcategory")]

Use

A module can have several categories. Similarly, categories can be made up of subcategories. This structure can be indefinite.

The Order property dictates the order in which actions are previewed in the designer.

Action1 belongs to the category "TestCategory" and is the first action of the module (this way you explain Order and category with an example).

[Action(Id = "Action1", Order = 1, Category = "Test Category")]

conditional actions

Conditional actions are actions that return "True" or "False". The 'If file exists' Power Automate for Desktop action from the standard library is a good example of a conditional action.

Example of conditional action:

using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;using System;using System.ComponentModel;namespace Modules.CustomModule{ [ConditionAction(Id = "ConditionalAction1 ", ResultPropertyName = nameof(Result))] [Throws("ActionError")] // TODO: rename the error (or remove if not needed) public class ConditionalAction1 : ActionBase { #region Properties public bool Result { get; private set; } [InputArgument] public string InputArgument1 { get; place; } #endregion #region Methods Overrides public override void Execute(ActionContext context) { try { //TODO: add action execution code here } catch (Exception e) { if (e is ActionException) throw; throw new ActionException("ActionError", e.Message, e.InnerException); } } #endregion }}

Watch herResultvariable booleana.

Heif the file existsaction does not have an output argument. What it returns is true or false, depending on what the boolean variableResulthe claims

Custom action selectors

There are particular cases where a custom action may be required to have more than one variation.

An example is the "Run Excel" action, from the standard library of actions.

Using the "with a blank document" selector, the flow launches a blank Excel document, while using the "and open the following document" selector requires the file path to open.

Create custom actions - Power Automate (5)

The two actions mentioned above are two selectors of the "Launch Excel" base action.

By creating custom actions, you don't have to rewrite functionality.

You can create a single "base" action, setting its input and output parameters, and then choose what would be visible in each type using action selectors.

Through action selectors, a layer of abstraction can be added on top of a single action, allowing specific functionality to be retrieved from the single "base" action without having to rewrite the code to form a new variation of it. action every time.

Think of selectors like options, filtering for a single action and presenting only the information required according to the respective selectors.

Create custom actions - Power Automate (6)

To form a new action selector, first create a base action for the selectors to use.

The core action requires a boolean or enumeration property as a C# input argument.

The value of this property determines which selector is used.

The most common way is to use an enum. Especially when more than two selectors are needed, enums are the only option.

For two selector instances, boolean values ​​can be used.

This property, also known as the constraint argument, must have a default value.

The central action is declared as a classic action.

Notice that the first property (input argument) is an enumeration. Based on the value of that property, the appropriate selector is activated.

Use

To have the arguments ordered the way you want, set the Order value next to the InputArgument attribute.

usando System.ComponentModel;usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Desktop.Actions.SDK;usando Microsoft.PowerPlatform.PowerAutomate.Desktop.Desktop.Actions.SDK.Attributes;módulos de espacio de nombres.CustomModule{ [Action(Id = "CentralCustomAction" )] public class CentralCustomAction: ActionBase { #region Properties [InputArgument, DefaultValue(SelectorChoice.Selector1)] public SelectorChoice Selector { get; colocar; } [InputArgument(Order = 1)] public string FirstName { get; colocar; } [InputArgument(Order = 2)] public string LastName { get; colocar; } [InputArgument(Order = 3)] public int Age { get; colocar; } [Argumento de salida] public string DisplayedMessage { get; colocar; } #endregion #region Métodos Anulados public override void Execute(ActionContext context) { if (Selector == SelectorChoice.Selector1) { DisplayedMessage = $"Hola, {FirstName}!"; } else if (Selector == SelectorChoice.Selector2) { DisplayedMessage = $"Hola, {FirstName} {LastName}!"; } else // Se eligió el tercer selector { DisplayedMessage = $"¡Hola, {FirstName} {LastName}!\nTu edad es: {Age}"; } } #endregion } // puede ver a continuación cómo implementar un selector de acción}

Custom action selectors using enums

In this example, you create three selectors. A simple enum dictates the appropriate selector each time:

public enum SelectorChoice{ Selector1, Selector2, Selector3}

Selectors are represented by classes.

Those classes should inherit theActionSelectorclass.

Use

TBaseActionClassis the name of the base action class.

In ituse name()method, the name of the action selector is declared. It is used as the name of the action to resolve the resources.

Public class Selector1: ActionSelector{ Public Selector1() { UseName("DisplayOnlyFirstName"); Prop(p => p.Selector).Should be(SelectorChoice.Selector1); Show everything(); Hide(p => p.LastName); Hide(p => p.Age); // or // Show(p => p.Name); // Show(p => p.DisplayedMessage); }}

Use

HeSelectorclasses should not be declared as actions. The only action is the center. Selectors act as filters.

In this specific example, we want to display only one of the arguments, so the others are filtered out. Similarly forSelector2:

public class Selector2: ActionSelector{ public Selector2() { UseName("DisplayFullName"); Prop(p => p.Selector).Should be(SelectorChoice.Selector2); Show everything(); Hide(p => p.Age); }}

YSelector3classes:

public class Selector3: ActionSelector{ public Selector3() { UseName("DisplayFullDetails"); Prop(p => p.Selector).Should be(SelectorChoice.Selector3); Show everything(); }}

The final execution is achieved through theExecute(ActionContext context)method that resides in the core action. Depending on the selector, the respective filtered values ​​are displayed.

public override void Execute(ActionContext context){ if (Selector == SelectorChoice.Selector1) { DisplayedMessage = $"Hola, {FirstName}!"; } else if (Selector == SelectorChoice.Selector2) { DisplayedMessage = $"Hola, {FirstName} {LastName}!"; } else // Se eligió el tercer selector { DisplayedMessage = $"¡Hola, {FirstName} {LastName}!\nTu edad es: {Age}"; }}

Custom action selectors using booleans

The following is an example that uses Boolean instead of enums.

con System.ComponentModel;con Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;con Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.ActionSelectors;con Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;módulos de espacio de nombres .CustomModule{ [Acción] public class CentralCustomActionWithBoolean: ActionBase { #region Properties [InputArgument, DefaultValue(true)] public bool TimeExpired { get; colocar; } [InputArgument] public string ElapsedTime { get; colocar; } [InputArgument] public string RemainingTime { get; colocar; } [Argumento de salida] public string DisplayedMessage { get; colocar; } #endregion #region Métodos Invalidaciones public override void Execute(ActionContext context) { DisplayedMessage = TimeExpired ? $"El temporizador ha expirado. Tiempo transcurrido: {ElapsedTime}" : $"Tiempo restante: {RemainingTime}"; } #endregion } public class NoTime : ActionSelector{ public NoTime() { UseName("TimeHasExpired"); Prop(p => p.TimeExpired).ShouldBe(true); Show everything(); Hide(p => p.RemainingTime); } } public class ThereIsTime: ActionSelector{ public ThereIsTime() { UseName("TimeHasNotExpired"); Prop(p => p.TimeExpired).ShouldBe(false); Show everything(); Hide(p => p.RemainingTime); } }}

Configuring descriptions for custom action selectors

To create a description and summary for the selectors, use the following format in the .resx file of your custom module.

SelectorName_DescriptionSelectorName_Summary

This can also be done in the selector with the WithDescription and WithSummary methods.

Important

The .dll files that describe the custom actions, their .dll dependencies, and the .cab file that contains everything must be properly signed with a digital certificate that is trusted by your organization. The certificate must also be installed on each machine running a desktop flow with custom action dependencies, present under the Trusted Root Certification Authorities.

Creation and import of a self-signed certificate

To create a self-signed certificate with exportable private key and code signing capabilities:

  1. Abra Windows PowerShell.

  2. Copy and paste the following commands, replacing the names as appropriate.

    $certname = "{Your certificate name}"$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Type CodeSigningCert -Subject "CN=$certname" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorith m SHA256 $mypwd = ConvertTo-SecureString -String "{your password}" -Force -AsPlainTextExport-PfxCertificate -Cert $cert -FilePath "{enter the full path of the preferred exported location}\{preferred certificate name}.pfx" - Password $mypwd
  3. Once the certificate has been created and exported, import it into your trusted root.

  4. Double-click the exported certificate.

  5. Select Current user.

    Create custom actions - Power Automate (7)

  6. In itprivate key protectionscreen, use the password provided during certificate creation and also mark the key as exportable and include all extended properties

    Create custom actions - Power Automate (8)

  7. Add the certificate to the Trusted Root Certification Authorities

    Create custom actions - Power Automate (9)

Sign a custom module

To finish creating the custom module, the generated .dll file ([Assembly Name].dll) is required. The file can be found in the project's bin/release or bin/Debug folder.

Sign the .dll file with a trusted certificate by running the following command at a Visual Studio developer command prompt:

Signtool sign /f {name of your certificate}.pfx /p {your password to export the certificate} /fd SHA256 {path to the .dll you want to sign}.dll

Use

The digital certificate must have an exportable private key and code signing capabilities.

Packaged everything in a file cabinet

The .dll that contains the custom actions (preview) and all their dependencies (.dll files) must be packaged in a cabinet (.cab) file.

Use

When naming the .cab file, follow the file and folder naming convention for the Windows operating system. Do not use blank spaces or special characters such as< > : " / \ | ? *.

Create a Windows PowerShell script (.ps1) that contains the following lines:

param( [ValidateScript({Test-Path $_ -PathType Container})][string]$sourceDir,[ValidateScript({Test-Path $_ -PathType Container})] [string] $cabOutputDir, [string] $cabFilename) $ddf = ".OPTION EXPLICIT.Set CabinetName1=$cabFilename.Set DiskDirectory1=$cabOutputDir.Set CompressionType=LZX.Set Cabinet=on.Set Compress=on.Set CabinetFileCountThreshold=0.Set FolderFileCountThreshold=0.Set FolderSizeThreshold=0. Establezca MaxCabinetSize=0.Establezca MaxDiskFileCount=0.Establezca MaxDiskSize=0"$ddfpath = ($env:TEMP + "\customModule.ddf")$sourceDirLength = $sourceDir.Length;$ddf += (Get-ChildItem $sourceDir - Filtrar "*.dll" | Where-Object { (!$_.PSIsContainer) -and ($_.Name -ne "Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.dll") } | Select-Object -ExpandProperty FullName | ForEach-Object { '"' + $_ + '" "' + ($_.Substring($sourceDirLength)) + '"' }) -join "`r`n"$ddf | Archivo de salida -Codificación UTF8 $ddfpathmakecab.exe /F $ddfpathRemove-Item $ddfpath

This Windows PowerShell script can be used to create the .cab file by calling it in Windows PowerShell and providing:

  • The directory of the .dll files to compress.
  • The destination directory to place the generated .cab file.

Example:

.\makeCabFromDirectory.ps1 "{source directory to zip dlls}" "{destination directory to save cab}" {cabName}.cab

Use

The .cab file must also be signed. Unsigned .cab files and/or unsigned .dlls contained within them will not be usable in desktop flows and will result in an error during inclusion.

Next steps

Upload custom actions

See also

  • Asset Library (Preview)
  • Use custom actions
  • custom actions

References

Top Articles
Latest Posts
Article information

Author: Neely Ledner

Last Updated: 07/21/2023

Views: 6145

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Neely Ledner

Birthday: 1998-06-09

Address: 443 Barrows Terrace, New Jodyberg, CO 57462-5329

Phone: +2433516856029

Job: Central Legal Facilitator

Hobby: Backpacking, Jogging, Magic, Driving, Macrame, Embroidery, Foraging

Introduction: My name is Neely Ledner, I am a bright, determined, beautiful, adventurous, adventurous, spotless, calm person who loves writing and wants to share my knowledge and understanding with you.