question

Chabango avatar image
0 Votes"
Chabango asked RichMatheisen-8856 commented

Invoke-command in foreach loop : The syntax is not supported by this runspace. This can occur if the runspace is in no-language mode.

I am running an invoke-command against Exchange Online in a foreach loop and IO keep receiving the following error: The syntax is not supported by this runspace. This can occur if the runspace is in no-language mode. Here is the code: the first invoke-command ($MBX) outside the foreach completes fine, but the second ($name) throws the error:

 $mbx= Invoke-Command -Session (Get-PSSession) -scriptblock {Get-Mailbox -ResultSize unlimited | select-object primarysmtpaddress}
    
 $count=1
 $fullcount = ($mbx | measure-object).count
    
    
 $Meetings = @()
     foreach ($M in $MBX) {
    
 $count++
 $search = $m.primarysmtpaddress
    
 Write-progress -activity "Getting Calendar $count out of $fullcount --- $search " -percentcomplete (($count / $fullcount)*100) -status "Processing"
    
    
 #### THis is where the error happens ######
 $name = Invoke-Command -Session (Get-PSSession) -scriptblock {Get-CalendarDiagnosticObjects -Identity $search -StartDate 3/10/2021  | where {$_.location -eq "WebEx"} | group-object AppointmentSequenceNumber}
    
 $User = New-Object psobject
 $user | Add-Member -MemberType NoteProperty -Name Mailbox -Value $null
 $user | Add-Member -MemberType NoteProperty -Name WebExCount -Value $null
    
 $user.mailbox = $M.primarysmtpaddress
 $user.WebExCount = $name.count
    
    
 $meetings += $user
 }
    
    
 $meetings
windows-server-powershell
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

How are you creating that session? Each session has a language mode. It looks like you haven't added one. Exchange (if I remember correctly) operates in a constrained endpoint and only allows certain commands.

Also, you're trying to use a local variable ($search) in a remote session. You can either parameterize that, or you can use this: $Using:search

about_language_modes
powershell-constrained-language-mode



0 Votes 0 ·
Chabango avatar image
0 Votes"
Chabango answered RichMatheisen-8856 commented

Using your portion of the code, I still receive the same error:
The syntax is not supported by this runspace. This can occur if the runspace is in no-language mode.
+ CategoryInfo : ParserError: (Get-CalendarDia...tSequenceNumber:String) [], ParseException
+ FullyQualifiedErrorId : ScriptsNotAllowed
+ PSComputerName : outlook.office365.com

With this code:

 $mbx = Invoke-Command -Session (Get-PSSession) -ScriptBlock {get-mailbox -ResultSize unlimited | select-object primarysmtpaddress} 
    
 $count=1
 $fullcount = ($mbx | measure-object).count
    
 #$mbx = get-exomailbox charles.bost
    
 $Meetings = @()
     foreach ($M in $MBX) {
    
 $count++
 $search = $m.primarysmtpaddress
    
 Write-progress -activity "Getting Calendar $count out of $fullcount --- $search " -percentcomplete (($count / $fullcount)*100) -status "Processing"
    
 ### your portion of the code###
  $sb = [ScriptBlock]::Create( "Get-CalendarDiagnosticObjects -Identity $search -StartDate 3/10/2021  | 
                                  Where-Object {$_.location -eq 'WebEx'} | 
                                      group-object AppointmentSequenceNumber"
                              )
  $name = Invoke-Command -Session (Get-PSSession) -ScriptBlock $sb
    
  ### end of your portion of code ###
    
 $User = New-Object psobject
 $user | Add-Member -MemberType NoteProperty -Name Mailbox -Value $null
 $user | Add-Member -MemberType NoteProperty -Name WebExCount -Value $null
    
 $user.mailbox = $M.primarysmtpaddress
 $user.WebExCount = $name.count
    
    
 $meetings += $user
 }
    
 $meetings
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

That's true . . . I pointed out the need to set an appropriate language mode in my comment to your original post. I left a couple of links in that comment that should get started on selecting, and setting, a language mode. The reason this is necessary is that not all language features are accessible in every language mode. In your case, you're working in the "no language" mode. Which of the language modes is appropriate for Exchange I don't know.

0 Votes 0 ·
Chabango avatar image
0 Votes"
Chabango answered RichMatheisen-8856 edited

Thanks for the great info!
What if the info in the $search variable is not local?
In my example, $search = $m.primarysmtpaddress, which is pulling from the
$mbx= Invoke-Command -Session (Get-PSSession) -scriptblock {Get-Mailbox -ResultSize unlimited | select-object primarysmtpaddress}
in for the foreach loop, $m.primarysmtpaddress would be the primarysmtpaddress for each object in $mbx.
I'm not sure how to tie in the $search using your example.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

The variable "$search" is set once for each element in the array named $mbx. The "$search" variable in your script is local. There should be nothing to do except to use the examples I gave, each one used the $search defined in your script.

0 Votes 0 ·
RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

Three ways to get local values into a scriptblock to be run on a remote machine:

 $search = "A Name Goes Here"
    
 # Make use of the "Using" scope (Probably the best/easiest)
 $name = Invoke-Command -Session (Get-PSSession) -scriptblock {
             Get-CalendarDiagnosticObjects -Identity $Using:search -StartDate 3/10/2021  | 
                 Where-Object {$_.location -eq "WebEx"} | 
                     group-object AppointmentSequenceNumber
     }
    
 # Pass parameter(s) from local machine into the scriptblock
 $name = Invoke-Command -Session (Get-PSSession) -scriptblock {}
             param ([string]$SearchParam)
             Get-CalendarDiagnosticObjects -Identity $SearchParam -StartDate 3/10/2021  | 
                 Where-Object {$_.location -eq "WebEx"} | 
                     group-object AppointmentSequenceNumber
         } -ArgumentList $search
    
 # Build your scriptblock (if the script block is complex this might be the most flexible way)
 # watch out for using double quotes in the scriptblock and the need to use "$($object.property)" to
 # ensure that variable interpolation works the way you want
 $sb = [ScriptBlock]::Create( "Get-CalendarDiagnosticObjects -Identity $search -StartDate 3/10/2021  | 
                                 Where-Object {$_.location -eq 'WebEx'} | 
                                     group-object AppointmentSequenceNumber"
                             )
 $name = Invoke-Command -Session (Get-Session) -ScriptBlock $sb


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Chabango avatar image
0 Votes"
Chabango answered

The $search is a variable for each run through the foreach loop. I am not sure how you are saying to parameterize that?

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.