title: C# PowerShell with RunspacePool - How to import Exchange Cmdlets like Get-Mailbox?
body: <p>I am currently building a Windows-Service that will execute PowerShell Commands wenn some request comes in. There will be lots of requests comming in so I adopted the code from: <a href="https://stackoverflow.com/questions/18382401/using-powershell-runspacepool-multithreaded-to-remote-server-from-c-sharp">Using Powershell RunspacePool multithreaded to remote server from C#</a></p>
  
  <p>I am not using the WSManConnectionInfo but just do New-PSSession. See my Code at the end of this question.</p>
  
  <p>This appears to work great for all regular Commands but one which uses Exhange Cmdlets and does an Import-PSSession before. I don't want to import the Cmdlets every time the script runs, but I am not getting the import right from C#. After invocation the PowerShell ErrorStream also notes that the term "Get-Mailbox" is unknown. I do not understand why the import does not work and what I need to do for it.</p>
  
  <p>I had working for once but only with a single runspace. After moving to the RunspacePool I could not get it to work again.</p>
  
  <p>Any help would be highly appreciated.</p>
  
  <p>THE CODE:</p>
  
  <pre><code>static void Main(string[] args)
  { 
      string connectionUri = "https://.../Powershell";
      string userName = @"...\...";
      string password = "...";
  
      System.Uri uri = new Uri(connectionUri);
      System.Security.SecureString securePassword = String2SecureString(password);
  
      System.Management.Automation.PSCredential creds = new System.Management.Automation.PSCredential(userName, securePassword);
  
      //InitialSessionState iss = InitialSessionState.CreateDefault();
      //iss.ImportPSModule(new[] { "Get-Mailbox", "Get-MailboxStatistics" });
  
      RunspacePool runspacePool = RunspaceFactory.CreateRunspacePool();
      runspacePool.ThreadOptions = PSThreadOptions.UseNewThread;
  
      PowerShell powershell = PowerShell.Create();
      PSCommand command = new PSCommand();
      command.AddCommand(string.Format("New-PSSession"));
      command.AddParameter("ConfigurationName", "Microsoft.Exchange");
      command.AddParameter("ConnectionUri", uri);
      command.AddParameter("Credential", creds);
      command.AddParameter("Authentication", "Basic");
      command.AddParameter("AllowRedirection");
  
      // IS THIS NEEDED?
      PSSessionOption sessionOption = new PSSessionOption();
      sessionOption.SkipCACheck = true;
      sessionOption.SkipCNCheck = true;
      sessionOption.SkipRevocationCheck = true;
      command.AddParameter("SessionOption", sessionOption);
  
      powershell.Commands = command;
  
      runspacePool.Open();
      powershell.RunspacePool = runspacePool;
      Collection&lt;PSSession&gt; result = powershell.Invoke&lt;PSSession&gt;();
  
      foreach (ErrorRecord current in powershell.Streams.Error)
      {
          Console.WriteLine("Exception: " + current.Exception.ToString());
          Console.WriteLine("Inner Exception: " + current.Exception.InnerException);
      }
  
      // Returns the session
      if (result.Count != 1)
          throw new Exception("Unexpected number of Remote Runspace connections returned.");
  
      // THATS THE PART NOT WORKING
      // First import the cmdlets in the current runspace (using Import-PSSession)
      powershell = PowerShell.Create();
      command = new PSCommand();
      command.AddScript("Import-PSSession $Session -CommandName Get-Mailbox, Get-MailboxStatistics -AllowClobber -WarningAction SilentlyContinue -ErrorAction Stop -DisableNameChecking | Out-Null");
      command.AddParameter("Session", result[0]);
  
      // This is also strange... without the RunspaceInvoke I always get a SecurityException... 
      RunspaceInvoke scriptInvoker = new RunspaceInvoke();
      scriptInvoker.Invoke("Set-ExecutionPolicy -Scope Process Unrestricted");
  
      var tasks = new List&lt;Task&gt;();
  
      for (var i = 0; i &lt; 3; i++)
      {
          var taskID = i;
          var ps = PowerShell.Create();
          ps.RunspacePool = runspacePool;
          PSCommand cmd = new PSCommand();
          cmd.AddCommand(@".\PSScript1.ps1");
          //cmd.AddScript("Get-Mailbox -ResultSize 5");
          cmd.AddParameter("Session", result[0]);
          ps.Commands = cmd;
          var task = Task&lt;PSDataCollection&lt;PSObject&gt;&gt;.Factory.FromAsync(
                                               ps.BeginInvoke(), r =&gt; ps.EndInvoke(r));
          System.Diagnostics.Debug.WriteLine(
                            string.Format("Task {0} created", task.Id));
          task.ContinueWith(t =&gt; System.Diagnostics.Debug.WriteLine(
                            string.Format("Task {0} completed", t.Id)),
                            TaskContinuationOptions.OnlyOnRanToCompletion);
          task.ContinueWith(t =&gt; System.Diagnostics.Debug.WriteLine(
                            string.Format("Task {0} faulted ({1} {2})", t.Id,
                            t.Exception.InnerExceptions.Count,
                            t.Exception.InnerException.Message)),
                            TaskContinuationOptions.OnlyOnFaulted);
          tasks.Add(task);
      }
  
      Task.WaitAll(tasks.ToArray());               
  }
  
  private static SecureString String2SecureString(string password)
  {
      SecureString remotePassword = new SecureString();
      for (int i = 0; i &lt; password.Length; i++)
          remotePassword.AppendChar(password[i]);
  
      return remotePassword;
  }
  </code></pre>
  
  <p>The Script in short form:</p>
  
  <pre><code>Param($Session)
  
  Import-PSSession $Session -CommandName Get-Mailbox, Get-MailboxStatistics -ErrorAction SilentlyContinue | Out-Null
  
  Get-Mailbox -ResultSize 5 | SElectObject Name, Alias, ...
  </code></pre>
  
  <p>The Script works like that, but when I try to comment out the Import-PSSession part I get the unknown term Get-Mailbox error.</p>
  
  <p>Thanks in advance and best regards
  Gope</p>