Skip to content

Commit 51589eb

Browse files
authored
Merge pull request #11034 from MicrosoftDocs/Invoke-chrisda
New article about Invoke-Command workarounds
2 parents 875f1d3 + f8cfe3a commit 51589eb

File tree

3 files changed

+133
-2
lines changed

3 files changed

+133
-2
lines changed

exchange/docs-conceptual/exchange-online-powershell-v2.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: About the Exchange Online PowerShell V2 module and V3 module
33
ms.author: chrisda
44
author: chrisda
55
manager: dansimp
6-
ms.date: 6/21/2023
6+
ms.date: 7/5/2023
77
ms.audience: Admin
88
audience: Admin
99
ms.topic: article
@@ -62,13 +62,15 @@ Version 3.0.0 or later is known as the EXO V3 module. The EXO V3 module improves
6262

6363
- REST API cmdlets have the same cmdlet names and work just like their remote PowerShell equivalents, so you don't need to update any of your scripts.
6464

65+
The [Invoke-Command](/powershell/module/microsoft.powershell.core/invoke-command) cmdlet doesn't work in REST API connections. For alternatives, see [Workarounds for Invoke-Command scenarios in REST API connections](invoke-command-workarounds-rest-api.md).
66+
6567
- In Exchange Online PowerShell and in Security & Compliance PowerShell, all of the available remote PowerShell cmdlets are backed by the REST API.
6668

6769
- In Exchange Online PowerShell and in Security & Compliance PowerShell, REST API connections are used by default. You need to use the _UseRPSSession_ switch in the **Connect-ExchangeOnline** or **Connect-IPPSSession** command to access cmdlets in remote PowerShell mode.
6870

6971
- Consider the following items if you connect to Exchange Online PowerShell or Security & Compliance PowerShell in remote PowerShell mode:
7072
- [Basic authentication in WinRM](#turn-on-basic-authentication-in-winrm) is required on your client computer.
71-
- If you don't connect i remote PowerShell mode, you have access to REST API cmdlets _only_.
73+
- If you don't connect in remote PowerShell mode, you have access to REST API cmdlets _only_.
7274
- The end of remote PowerShell support in Exchange Online PowerShell has been announced. For more information, see [Announcing Deprecation of Remote PowerShell (RPS) Protocol in Exchange Online PowerShell](https://aka.ms/RPSDeprecation).
7375

7476
- A few REST API cmdlets in Exchange Online PowerShell have been updated with the experimental _UseCustomRouting_ switch. This switch routes the command directly to the required Mailbox server, and might improve overall performance.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
title: Workarounds for Invoke-Command scenarios in REST API connections
3+
ms.author: chrisda
4+
author: chrisda
5+
manager: dansimp
6+
ms.date: 7/5/2023
7+
ms.audience: Admin
8+
audience: Admin
9+
ms.topic: article
10+
ms.service: exchange-powershell
11+
ms.reviewer:
12+
ms.localizationpriority: normal
13+
ms.collection: Strat_EX_Admin
14+
ms.custom:
15+
ms.assetid:
16+
search.appverid: MET150
17+
description: "Learn about the alternatives to Invoke-Command commands in REST API connections using the EXO V3 module."
18+
---
19+
20+
# Workarounds for Invoke-Command scenarios in REST API connections
21+
22+
In multiple connections to Exchange Online or Security & Compliance PowerShell in the same window, you use the [Invoke-Command](/powershell/module/microsoft.powershell.core/invoke-command) cmdlet to run scripts or commands in a specific remote PowerShell session. But, the **Invoke-Command** cmdlet doesn't work in [REST API connections](exchange-online-powershell-v2.md#updates-for-the-exo-v3-module) to Exchange Online or Security & Compliance PowerShell.
23+
24+
This article offers REST API alternatives for scenarios that that use **Invoke-Command** commands.
25+
26+
## Scenario 1: Run Exchange Online cmdlets
27+
28+
This example finds the identity of any other user (`$Us = $User.Identity`).
29+
30+
> [!TIP]
31+
> Other commands were required to get the values of `$User` and therefore `$Us`. Those commands aren't important. The overall approach that's being used is what's important.
32+
33+
- **In a remote PowerShell session**: Use the **Get-PSSession** cmdlet to store the remote PowerShell session details in the variable named `$Session`, and then run the following command:
34+
35+
```powershell
36+
Invoke-Command -Session $Session -ScriptBlock {Get-User $Using:Us | Select-Object DistinguishedName, ExternalDirectoryObjectId} -ErrorAction SilentlyContinue
37+
```
38+
39+
- **In a REST API session**: Run the following command:
40+
41+
```powershell
42+
Get-User $Us | Format-List DistinguishedName, ExternalDirectoryObjectId
43+
```
44+
45+
This example finds the identity of a group member:
46+
47+
- **In a remote PowerShell session**: Use the **Get-PSSession** cmdlet to store the remote PowerShell session details in the variable named `$Session`, and then run the following command:
48+
49+
```powershell
50+
Invoke-Command -Session $Session -ScriptBlock {Get-Recipient -Filter "Members -eq '$($User.DistinguishedName)'" -RecipientTypeDetails MailUniversalDistributionGroup | Select-Object DisplayName, ExternalDirectoryObjectId, RecipientTypeDetails} -ErrorAction SilentlyContinue -HideComputerName
51+
```
52+
53+
- **In a REST API session**: Run the following command:
54+
55+
```powershell
56+
Get-Recipient -Filter "Members -eq '$($User.DistinguishedName)'" -RecipientTypeDetails MailUniversalDistributionGroup | Format-List DisplayName, ExternalDirectoryObjectId, RecipientTypeDetails
57+
```
58+
59+
## Scenario 2: Run Exchange Online cmdlets and expand specific properties
60+
61+
This example finds all mailboxes where the GrantSendOnBehalfTo permission is set, and then returns the users who have the permission on the mailbox.
62+
63+
- **In a remote PowerShell session**: Use the **Get-PSSession** cmdlet to store the remote PowerShell session details in the variable named `$Session`, and then run the following command:
64+
65+
```powershell
66+
Invoke-Command -Session $Session -ScriptBlock {Get-Mailbox -Filter "GrantSendOnBehalfTo -ne `$null" -ErrorAction SilentlyContinue | Select-Object ExternalDirectoryObjectId, GrantSendOnBehalfTo -ExpandProperty GrantSendOnBehalfTo}
67+
```
68+
69+
- **In a REST API session**: Run the following command:
70+
71+
```powershell
72+
$mailboxes = Get-Mailbox -Filter "GrantSendOnBehalfTo -ne `$null"
73+
74+
foreach ($mailbox in $mailboxes)
75+
76+
{
77+
$users = $mailbox | Select-Object GrantSendOnBehalfTo -ExpandProperty GrantSendOnBehalfTo | Get-User
78+
79+
$users | Select-Object Name, Guid
80+
}
81+
```
82+
83+
## Scenario 3: Run Exchange Online cmdlets in a specific PowerShell session when multiple sessions are present
84+
85+
This example shows how to create two PowerShell sessions in the same window and run the **Get-Mailbox** cmdlet in each session.
86+
87+
- **In a remote PowerShell session**:
88+
1. Use the **Get-PSSession** cmdlet to store the first remote PowerShell session details in the variable named `$Session1`.
89+
2. Use the **Get-PSSession** cmdlet to store the second remote PowerShell session details in the variable named `$Session2`.
90+
3. Run the following commands:
91+
92+
```powershell
93+
Invoke-Command -Session $Session1 -ScriptBlock {Get-Mailbox -ResultSize 1}
94+
95+
Invoke-Command -Session $Session2 -ScriptBlock {Get-Mailbox -ResultSize 1}
96+
```
97+
98+
- **In a REST API session**:
99+
1. In the first **Connect-ExchangeOnline** command, use the parameter _Prefix_ with the value C1.
100+
2. Store the first REST API connection details in the variable named `$ConnectionInfo1` by running the following command:
101+
102+
```powershell
103+
$ConnectionInfo1 = Get-ConnectionInformation | Where-Object { $_.ModulePrefix -eq "C1"}
104+
```
105+
106+
3. In the second **Connect-ExchangeOnline** command, use the parameter _Prefix_ with the value C2.
107+
4. Store the second REST API connection details in the variable named `$ConnectionInfo2` by running the following command:
108+
109+
```powershell
110+
$ConnectionInfo1 = Get-ConnectionInformation | Where-Object { $_.ModulePrefix -eq "C2"}
111+
```
112+
113+
5. Now you can run commands in either session. For example:
114+
115+
```powershell
116+
$CommandStr1 = "Get-$($ConnectionInfo1.ModulePrefix)Mailbox -ResultSize 10"
117+
118+
Invoke-Expression $CommandStr1
119+
```
120+
121+
Or
122+
123+
```powershell
124+
$CommandStr2 = "Get-$($ConnectionInfo2.ModulePrefix)Mailbox -ResultSize 10"
125+
126+
Invoke-Expression $CommandStr2
127+
```

exchange/docs-conceptual/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
href: connect-exo-powershell-managed-identity.md
3939
- name: Connect using C#
4040
href: connect-to-exo-powershell-c-sharp.md
41+
- name: Workarounds for Invoke-Command in REST API connections
42+
href: invoke-command-workarounds-rest-api.md
4143
- name: Enable or disable access to Exchange Online PowerShell
4244
href: disable-access-to-exchange-online-powershell.md
4345
- name: Exchange cmdlet syntax

0 commit comments

Comments
 (0)