4

I'm attempting to pull data from Office 365 Exchange Online in parallel to save time. I'm not able to accomplish what I'm looking to do, the following code is the "closest" I've come so far.

Workflow Get-MailboxStatisticsParallel{
    param ($o365cred)

    $session = InlineScript {
        New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/" -Credential $using:o365cred -Authentication Basic -AllowRedirection
    }

    InlineScript {
        Invoke-Command -Session $session -ScriptBlock {Get-Mailbox "Firstname Middleinitial. Lastname"}
    }
}

I defined two inline scripts because I want to setup the remote session once but then call the Get-Mailbox command in parallel to speed up the process. Here is an example of what I would want the workflow to look like.

Workflow Get-MailboxStatisticsParallel{
    param ($o365cred, $mailboxes)

    $session = InlineScript {
        New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/" -Credential $using:o365cred -Authentication Basic -AllowRedirection
    }

    ForEach -Parallel ($mailbox in $mailboxes){
        InlineScript {
            Invoke-Command -Session $using:session -ScriptBlock {param ($mailbox); Get-MailboxStatistics $mailbox.UserPrincipalName} -ArgumentList $mailbox
        }
    }

}

An example run would look like this.

$cred = Get-Credential

$mailboxes = Get-Mailbox -ResultSize Unlimited

Get-MailboxStatisticsParallel -o365cred $cred -mailboxes $mailboxes

Here are the typical results.

Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Supply an argument that is not null or empty and then try 
the command again.
At Get-MailboxStatisticsParallel:7 char:7
+ 
    + CategoryInfo          : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
    + PSComputerName        : [localhost]

I can see the $session object is being deserialized, I'm guessing that's my issue. The question is how can I establish a remote PowerShell session with a specific Uri and ConfigurationName and take advantage of the features workflows provide?

Douglas Plumley
  • 565
  • 5
  • 21

2 Answers2

5

I've tried to make this work, but haven't found a way.

Taking a look at Running Windows PowerShell Commands in a Workflow, it says, "To run the commands in inlinescript activity on remote computers, you need to establish and manage connections to the remote computer from within the inlinescript block and then run the commands remotely."

Assuming I'm understanding that statement correctly, I don't think you can establish a session outside of the InlineScript block and then use it inside the block. I've tried several ways of trying to pass the $session into the InlineScript, but it is always $null. This limitation makes sense to me because I don't see how a Workflow could use one remote session or connection to simultaneously execute multiple commands on the remote server. I think that you're going to need multiple remote connections to execute multiple remote commands.

My guess is that you're best bet will be to establish a series of connections to Office 365 and then use jobs to execute commands in parallel using each of the sessions.

Elijah W. Gagne
  • 2,801
  • 4
  • 31
  • 29
  • I think you are right on this, I haven't been able to find a workaround. This is what I see when trying to use the $session variable. Invoke-Command : Cannot bind parameter 'Session'. Cannot convert the "[PSSession]Session1" value of type "Deserialized.System.Management.Automation.Runspaces.PSSession" to type "System.Management.Automation.Runspaces.PSSession". – Douglas Plumley Nov 13 '13 at 13:39
  • Just wondering - did you ever come up with an alternative approach for the task at hand (spread a scripted task across multiple sessions)? I'm interested not for EXO, but on-premises instead. Want to pull permissions out from all mailboxes (~65K), so want to get the list of all mailboxes, then split that up evenly across a list of Exchange servers which will then run the same script but for only the corresponding mailboxes. – Jeremy Bradshaw Jul 02 '21 at 17:27
  • No @JeremyBradshaw, but I think what I'd do in that case is start an initial session to get the list of mailboxes and then split that into chunks to process in other sessions. It's been a long time since I've looked at this so I'm a little fuzzy on the details sorry. I wonder if this would help in any way as well - https://stackoverflow.com/questions/43008677/powershell-workflow-inlinescript-remoting/43008678#43008678 – Douglas Plumley Jul 23 '21 at 13:36
2
$using:sesssion has 3 s

change it to

$using:session
kleopatra
  • 51,061
  • 28
  • 99
  • 211