Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax not supported by this runspace in Powershell and C#

I am trying to get information about my users' mailboxes using power shell integrated into C#, but i am getting below error:

This syntax is not supported by this run space. This might be because it is no-language mode.

Here is the code that I am using:

using System;
using System.Collections.ObjectModel;
using System.Collections;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;
using System.Globalization;

namespace Office365
{
    class Program
    {
        static void Main(string[] args)
        {
            CultureInfo oldCI = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

            System.Security.SecureString secureString = new System.Security.SecureString();
            string myPassword = "mySecretPassword";
            foreach (char c in myPassword)
                secureString.AppendChar(c);
            PSCredential credential = new PSCredential("[email protected]", secureString);
            Console.WriteLine("Forbinder....");
            WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("https://ps.outlook.com/PowerShell-LiveID?PSVersion=2.0"), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);
            connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
            connectionInfo.SkipCACheck = true;
            connectionInfo.SkipCNCheck = true;

            string cmd2 = @"Get-Mailbox | Select-object Identity, displayname, ProhibitSendReceiveQuota, @{n='size';e={$MBXSTAT=Get-MailboxStatistics $_.Identity; $MBXSTAT.TotalItemSize}}";

            using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
            {

                    runspace.Open();

                using (Pipeline pipeline = runspace.CreatePipeline(cmd2))
                {
                    pipeline.Commands.AddScript(cmd2);
                    Collection<PSObject> results = pipeline.Invoke();
                    foreach (PSObject obj in results)
                    {

                        // Do something with each result object
                    }
                }
            }
        }
}

Any Suggestions on this? How can I overcome to this issue?

like image 739
Knaks Avatar asked Sep 07 '12 11:09

Knaks


1 Answers

Normally i like to leave the dead alone but in this case i feel the need to resurrect this old post because i encountered the exact problem, need a place to keep this code and hope this prevents anybody else from wasting too much time.

I have found connecting to O365 with WSManConnectionInfo problematic and after wasting far too much time trying to get it to work i won't be using it unless i have no other choice.

That said the following code works for me and behaves the same as if i had opened a PowerShell prompt entered the commands i want to run :) it makes testing a lot simpler.

using (var _power_shell = PowerShell.Create()) {
  _power_shell.AddScript("Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process");
  _power_shell.Invoke();
var credential = new PSCredential(username, password.ToSecureString()); _power_shell.Runspace.SessionStateProxy.SetVariable("Credential", credential);
_power_shell.AddScript("$Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Credential -Authentication Basic -AllowRedirection"); _power_shell.AddScript("Import-PSSession $Session"); _power_shell.Invoke();
_power_shell.AddScript("Get-Mailbox -RecipientTypeDetails RoomMailbox | Select-Object DisplayName, PrimarySmtpAddress"); var results = _power_shell.Invoke();
foreach (var obj in results) { /* Do something with the results */ }
_power_shell.AddScript("Remove-PSSession $Session"); _power_shell.Invoke(); }

The above code assumes username & password as string variables already in scope. Also an Extention method ToSecureString exists and is in scope.

As far as i understand PowerShell.Creste() provides an execution environment set to Restricted so you first need to change that. In this case becasue we scoped the Set-ExecutionPolicy to the process Admin rights are not required.

From what little i found on the subject it appears you need to remove the session when you are done or you may get throttled and lock yourself out of O365 for some time.

like image 65
Robert Avatar answered Oct 03 '22 08:10

Robert