Skip to content

Commit 2460b12

Browse files
authored
Merge pull request #279257 from ecfan/ps
[Standard] Run PowerShell Code action
2 parents afd1baa + ce7ca18 commit 2460b12

File tree

3 files changed

+392
-8
lines changed

3 files changed

+392
-8
lines changed
Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,382 @@
1+
---
2+
title: Add and run PowerShell in Standard workflows
3+
description: Write and run PowerShell script code in Standard workflows to perform custom integration tasks using Inline Code operations in Azure Logic Apps.
4+
ms.service: azure-logic-apps
5+
ms.suite: integration
6+
ms.reviewer: estfan, swghimire, shahparth, azla
7+
ms.topic: how-to
8+
ms.date: 08/13/2024
9+
# Customer intent: As a logic app workflow developer, I want to write and run PowerShell code so that I can perform custom integration tasks in Standard workflows for Azure Logic Apps.
10+
---
11+
12+
# Add and run PowerShell script code in Standard workflows for Azure Logic Apps (Preview)
13+
14+
[!INCLUDE [logic-apps-sku-standard](../../includes/logic-apps-sku-standard.md)]
15+
16+
> [!NOTE]
17+
> This capability is in preview and is subject to the
18+
> [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/).
19+
20+
To perform custom integration tasks inline with your Standard workflow in Azure Logic Apps, you can directly add and run PowerShell code from within your workflow. For this task, use the **Inline Code** action named **Execute PowerShell Code**. This action returns the results from your PowerShell code so that you can use this output in your workflow's subsequent actions.
21+
22+
This capability provides the following benefits:
23+
24+
- Write your own scripts within the workflow designer so you can solve complex integration challenges. No other service plans are necessary.
25+
26+
This benefit streamlines workflow development plus reduces the complexity and cost with managing more services.
27+
28+
- Generate a dedicated code file, which provides a personalized scripting space within your workflow.
29+
30+
- Integrate with [Azure Functions PowerShell Functions](../azure-functions/functions-reference-powershell.md), which provides powerful functionality and inheritance for advanced task execution.
31+
32+
- Deploy scripts alongside your workflows.
33+
34+
This guide shows how to add the action in your workflow and add the PowerShell code that you want to run.
35+
36+
## Prerequisites
37+
38+
* An Azure account and subscription. If you don't have a subscription, [sign up for a free Azure account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
39+
40+
* The Standard logic app workflow where you want to add your PowerShell script. The workflow must already start with a trigger. For more information, see [Create example Standard logic app workflows](create-single-tenant-workflows-azure-portal.md).
41+
42+
You can use any trigger for your scenario, but as an example, this guide uses the **Request** trigger named **When a HTTP request is received** and also the **Response** action. The workflow runs when another application or workflow sends a request to the trigger's endpoint URL. The sample script returns the results from code execution as output that you can use in subsequent actions.
43+
44+
## Considerations
45+
46+
- The Azure portal saves your script as a PowerShell script file (.ps1) in the same folder as your **workflow.json** file, which stores the JSON definition for your workflow, and deploys the file to your logic app resource along with the workflow definition.
47+
48+
The **.ps1** file format lets you write less "boilerplate" and focus just on writing PowerShell code. If you rename the action, the file is also renamed, but not vice versa. If you directly rename the file, the renamed version overwrites the previous version. If the action name and file names don't match, the action can't find the file and tries to create a new empty file.
49+
50+
- The script is local to the workflow. To use the same script in other workflows, [view the script file in the **KuduPlus** console](#view-script-file), and then copy the script to reuse in other workflows.
51+
52+
## Limitations
53+
54+
| Name | Limit | Notes |
55+
|------|-------|-------|
56+
| Script run duration | 10 minutes | If you have scenarios that need longer durations, use the product feedback option to provide more information about your needs. |
57+
| Output size | 100 MB | Output size depends on the output size limit for actions, which is generally 100 MB. |
58+
59+
## Add the Execute PowerShell Code action
60+
61+
1. In the [Azure portal](https://portal.azure.com), open your Standard logic app resource and workflow in the designer.
62+
63+
1. In the designer, [follow these general steps to add the **Inline Code Operations** action named **Execute PowerShell Code** to your workflow](create-workflow-with-trigger-or-action.md?tabs=standard#add-action).
64+
65+
1. After the action information pane opens, on the **Parameters** tab, in the **Code File** box, update the prepopulated sample code with your own code.
66+
67+
- To access data coming from your workflow, see [Access workflow trigger and action outputs in your script](#access-trigger-action-outputs) later in this guide.
68+
69+
- To return the script's results or other data to your workflow, see [Return data to your workflow](#return-data-to-workflow).
70+
71+
The following example shows the action's **Parameters** tab with the sample script code:
72+
73+
:::image type="content" source="media/add-run-powershell-scripts/action-sample-script.png" alt-text="Screenshot shows Azure portal, Standard workflow designer, Request trigger, Execute PowerShell Code action with information pane open, and Response action. Information pane shows sample PowerShell script." lightbox="media/add-run-powershell-scripts/action-sample-script.png":::
74+
75+
The following example shows the sample script code:
76+
77+
```powershell
78+
# Use the following cmdlets to retrieve outputs from prior steps.
79+
# $triggerOutput = Get-TriggerOutput
80+
# $ActionOutput = Get-ActionOutput -ActionName <action-name>
81+
82+
$customResponse = [PSCustomObject]@{
83+
Message = "Hello world!"
84+
}
85+
86+
# Use Write-Debug/Write-Host/Write-Output/ to log messages to Application Insights.
87+
# Write-Host/Write-Output/Write-Debug and 'return' won't return an output to the workflow.
88+
# Write-Host "Sending to Application Insight logs"
89+
90+
# Use Push-WorkflowOutput to push outputs into subsequent actions.
91+
Push-WorkflowOutput -Output $customResponse
92+
```
93+
94+
The following example shows a custom sample script:
95+
96+
```powershell
97+
$action = Get-TriggerOutput
98+
$results = "Hello from PowerShell!"
99+
Push-WorkflowOutput -Output $results
100+
```
101+
102+
1. When you finish, save your workflow.
103+
104+
After you run your workflow, you can review the workflow output in Application Insights, if enabled. For more information, see [View output in Application Insights](#log-output-application-insights).
105+
106+
<a name="access-trigger-action-outputs"></a>
107+
108+
## Access workflow trigger and action outputs in your script
109+
110+
The output values from the trigger and preceding actions are returned using a custom object, which has multiple parameters. To access these outputs and make sure that you return the value that you want, use the [**Get-TriggerOutput**](#get-triggeroutput), [**Get-ActionOutput**](#get-actionoutput), and [**Push-WorkflowOutput**](#push-workflowoutput) cmdlets plus any appropriate parameters described in the following table, for example:
111+
112+
```powershell
113+
$trigger = Get-TriggerOutput
114+
$statusCode = $trigger.status.ToString();
115+
$action = Get-ActionOutput -ActionName Compose
116+
$actionOutput = $action.outputs['actionOutput'].ToString();
117+
$populatedString = "Send the $statusCode for the trigger status and $actionOutputName."
118+
119+
Push-WorkflowOutput -Output $populatedString
120+
```
121+
122+
> [!NOTE]
123+
>
124+
> In PowerShell, if you reference an object that has **JValue** type inside a complex object, and you
125+
> add that object to a string, you get a format exception. To avoid this error, use **ToString()**.
126+
127+
### Trigger and action response outputs
128+
129+
The following table lists the outputs that are generated when you call **Get-ActionOutput** or **Get-TriggerOutput**. The return value is a complex object called **PowershellWorkflowOperationResult**, which contains thee following outputs.
130+
131+
| Name | Type | Description |
132+
|------|------|-------------|
133+
| **Name** | String | The name for the trigger or action. |
134+
| **Inputs** | JToken | The input values passed into the trigger or action. |
135+
| **Outputs** | JToken | The outputs from the executed trigger or action. |
136+
| **StartTime** | DateTime | The start time for the trigger or action. |
137+
| **EndTime** | DateTime | The end time for the trigger or action. |
138+
| **ScheduledTime** | DateTime | The scheduled time to run the trigger or action or trigger. |
139+
| **OriginHistoryName** | String | The origin history name for triggers with the **Split-On** option enabled. |
140+
| **SourceHistoryName** | String | The source history name for a resubmitted trigger. |
141+
| **TrackingId** | String | The operation tracking ID. |
142+
| **Code** | String | The status code for the result. |
143+
| **Status** | String | The run status for the trigger or action, for example, **Succeeded** or **Failed**. |
144+
| **Error** | JToken | The HTTP error code. |
145+
| **TrackedProperties** | JToken | Any tracked properties that you set up. |
146+
147+
<a name="return-data-to-workflow"></a>
148+
149+
## Return outputs to your workflow
150+
151+
To return any outputs to your workflow, you must use the [**Push-WorkflowOutput** cmdlet](#push-workflowoutput).
152+
153+
## Custom PowerShell commands
154+
155+
The **Execute PowerShell Code** action includes following custom [PowerShell commands (cmdlets)](/powershell/scripting/powershell-commands) for interacting with your workflow and other operations in your workflow:
156+
157+
### Get-TriggerOutput
158+
159+
Gets the output from the workflow's trigger.
160+
161+
#### Syntax
162+
163+
```powershell
164+
Get-TriggerOutput
165+
```
166+
167+
#### Parameters
168+
169+
None.
170+
171+
### Get-ActionOutput
172+
173+
Gets the output from another action in the workflow and returns an object named **PowershellWorkflowOperationResult**.
174+
175+
#### Syntax
176+
177+
```powershell
178+
Get-ActionOutput [ -ActionName <String> ]
179+
```
180+
181+
#### Parameters
182+
183+
| Parameter | Type | Description |
184+
|-----------|------|-------------|
185+
| **ActionName** | String | The name of the action in the workflow with the output that you want to reference. |
186+
187+
### Push-WorkflowOutput
188+
189+
Pushes output from the **Execute PowerShell Code** action to your workflow, which can pass back any object type. If the return value is null, you get a null object error from the cmdlet.
190+
191+
> [!NOTE]
192+
>
193+
> The **Write-Debug**, **Write-Host**, and **Write-Output** cmdlets don't return values
194+
> to your workflow. The **return** statement also doesn't return values to your workflow.
195+
> However, you can use these cmdlets to write trace messages that appear in Application Insights.
196+
> For more information, see [Microsoft.PowerShell.Utility](/powershell/module/microsoft.powershell.utility).
197+
198+
#### Syntax
199+
200+
```powershell
201+
Push-WorkflowOutput [-Output <Object>] [-Clobber]
202+
```
203+
204+
#### Parameters
205+
206+
| Parameter | Type | Description |
207+
|-----------|------|-------------|
208+
| **Output** | Varies. | The output that you want to return to the workflow. This output can have any type. |
209+
| **Clobber** | Varies. | An optional switch parameter that you can use to override the previously pushed output. |
210+
211+
## Authenticate and authorize access with a managed identity using PowerShell
212+
213+
With a [managed identity](/entra/identity/managed-identities-azure-resources/overview), your logic app resource and workflow can authenticate and authorize access to any Azure service and resource that supports Microsoft Entra authentication without including credentials in your code.
214+
215+
From inside the **Execute PowerShell Code** action, you can authenticate and authorize access with a managed identity so that you can perform actions on other Azure resources where you enabled access. For example, you can restart a virtual machine or get the run details of another logic app workflow.
216+
217+
To use the managed identity from inside the **Execute PowerShell Code** action, you must follow these steps:
218+
219+
1. [Follow these steps to set up the managed identity on your logic app and grant the managed identity access on the target Azure resource](authenticate-with-managed-identity.md?tabs=standard).
220+
221+
On the target Azure resource, review the following considerations:
222+
223+
- On the **Role** tab, a **Contributor** role is usually sufficient.
224+
225+
- On the **Add role assignment** page, on the **Members** tab, for the **Assign access to** property, make sure that you select **Managed identity**.
226+
227+
- After you select **Select members**, on the **Select managed identities** pane, select the managed identity that you want to use.
228+
229+
1. In your **Execute PowerShell Code** action, include the following code as the first statement:
230+
231+
```powershell
232+
Connect-AzAccount -Identity
233+
```
234+
235+
1. Now, you can work with the Azure resource using cmdlets and modules.
236+
237+
<a name="view-script-file"></a>
238+
239+
## View the script file
240+
241+
1. In the [Azure portal](https://portal.azure.com), open your Standard logic app resource that has the workflow you want.
242+
243+
1. On the logic app resource menu, under **Development Tools**, select **Advanced Tools**.
244+
245+
1. On the **Advanced Tools** page, select **Go**, which opens the **KuduPlus** console.
246+
247+
1. Open the **Debug console** menu, and select **CMD**.
248+
249+
1. Go to your logic app's root location: **site/wwwroot**
250+
251+
1. Go to your workflow's folder, which contains the .ps1 file, along this path: **site/wwwroot/{workflow-name}**
252+
253+
1. Next to the file name, select **Edit** to open and view the file.
254+
255+
<a name="log-output-application-insights"></a>
256+
257+
## View logs in Application Insights
258+
259+
1. In the [Azure portal](https://portal.azure.com), on the logic app resource menu, under **Settings**, select **Application Insights**, and then select your logic app.
260+
261+
1. On the **Application Insights** menu, under **Monitoring**, select **Logs**.
262+
263+
1. Create a query to find any traces or errors from your workflow execution, for example:
264+
265+
```text
266+
union traces, errors
267+
| project TIMESTAMP, message
268+
```
269+
270+
## Modules
271+
272+
PowerShell modules are self-contained, reusable units that include various components, for example:
273+
274+
- Cmdlets: Individual commands that perform specific tasks.
275+
- Providers: Allow access to data stores, such as the registry or file system, as if they were drives.
276+
- Functions: Reusable code blocks that perform specific actions.
277+
- Variables: Store data for use within the module.
278+
- Other types of resources.
279+
280+
A module organizes PowerShell code, making it easier to distribute. For example, you can create your own modules to package and make related functionality more manageable and shareable. The **Execute PowerShell Code** action lets you import both public and private PowerShell modules.
281+
282+
### Public modules
283+
284+
To find publicly available modules, visit the [PowerShell gallery](https://www.powershellgallery.com). A Standard logic app resource can support up to 10 public modules. To use any public module, you must enable this capability by following these steps:
285+
286+
1. In the [Azure portal](https://portal.azure.com), on your logic app resource menus, under Development Tools, select **Advanced Tools**.
287+
288+
1. On the **Advanced Tools** page, select **Go**.
289+
290+
1. On the **Kudu Plus** toolbar, from the **Debug console** menu, select **CMD**.
291+
292+
1. Browse to your logic app's root level at **C:\home\site\wwwroot** by using the directory structure or the command line.
293+
294+
1. Open the workflow's **host.json** file, and set the **managed dependency** property to **true**, which is already set by default.
295+
296+
```json
297+
"managedDependency": {
298+
"enabled": true
299+
}
300+
```
301+
302+
1. Open the file named **requirements.psd1**. Include the name and version for the module that you want by using the following syntax: **MajorNumber.\*** or the exact module version, for example:
303+
304+
```powershell
305+
@{
306+
Az = '1.*'
307+
SqlServer = '21.1.18147'
308+
}
309+
```
310+
311+
#### Considerations for public modules
312+
313+
If you use dependency management, the following considerations apply:
314+
315+
- To download modules, public modules require access to the [PowerShell Gallery](https://www.powershellgallery.com).
316+
317+
- Managed dependencies currently don't support modules that require you to accept a license, either by accepting the license interactively or by providing the **-AcceptLicense** option when you run **Install-Module**.
318+
319+
### Private modules
320+
321+
You can generate your own private PowerShell modules. To create your first PowerShell module, see [Write a PowerShell Script Module](/powershell/scripting/developer/module/how-to-write-a-powershell-script-module).
322+
323+
1. In the [Azure portal](https://portal.azure.com), on your logic app resource menu, under Development Tools, selects **Advanced Tools**.
324+
325+
1. On the **Advanced Tools** page, select **Go**.
326+
327+
1. On the **Kudu Plus** toolbar, from the **Debug console** menu, select **CMD**.
328+
329+
1. Browse to your logic app's root level at **C:\home\site\wwwroot** by using the directory structure or the command line.
330+
331+
1. Create a folder named **Modules**.
332+
333+
1. In the **Modules** folder, create a subfolder with the same name as your private module.
334+
335+
1. In your private module folder, add your private PowerShell module file with the **psm1** file name extension. You can also include an optional PowerShell manifest file with the **psd1** file name extension.
336+
337+
When you're done, your complete logic app file structure appears similar to the following example:
338+
339+
```text
340+
MyLogicApp
341+
-- execute_powershell_script.ps1
342+
-- mytestworkflow.json
343+
Modules
344+
-- MyPrivateModule
345+
--- MyPrivateModule.psd1
346+
--- MyPrivateModule.psm1
347+
-- MyPrivateModule2
348+
--- MyPrivateModule2.psd1
349+
--- MyPrivateModule2.psm1
350+
requirements.psd1
351+
host.json
352+
```
353+
354+
## Compilation errors
355+
356+
In this release, the web-based editor includes limited IntelliSense support, which is still under improvement. Any compilation errors are detected when you save your workflow, and the Azure Logic Apps runtime compiles your script. These errors appear in your logic app's error logs.
357+
358+
## Runtime errors
359+
360+
### A workflow action doesn't return any output.
361+
362+
Make sure that you use the **Push-WorkflowOutput** cmdlet.
363+
364+
### Execute PowerShell Code action fails: "The term '{some-text}' is not recognized..."
365+
366+
If you incorrectly reference a public module in the **requirements.psd1** file or when your private module doesn't exist in the following path: **C:\home\site\wwwroot\Modules\{module-name}**, you get the following error:
367+
368+
**The term '{some-text}' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name or if a path was included, verify the path is correct and try again.**
369+
370+
> [!NOTE]
371+
>
372+
> By default, the Az* modules appear in the **requirements.psd1** file, but they're commented out at file creation.
373+
> When you reference a cmdlet from the module, make sure to uncomment the module.
374+
375+
### Execute PowerShell Code action fails: "Cannot bind argument to parameter 'Output' because it is null."
376+
377+
This error happens when you try to push a null object to the workflow. Confirm whether the object that you're sending with **Push-WorkflowOutput** is null.
378+
379+
## Related content
380+
381+
- [Add and run JavaScript code snippets](add-run-javascript.md)
382+
- [Add and run C# scripts](add-run-csharp-scripts.md)
90.2 KB
Loading

0 commit comments

Comments
 (0)