Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PowerShell

Import PowerShell modules and excute CmdLets using Automation library

5.00/5 (1 vote)
22 Feb 2013CPOL3 min read 36.1K   722  
importing powershell modules and executes CmdLets in windows application using Automation library APIs

Introduction 

This article describes how to provide PowerShell support in windows applications using Microsoft's Automation Library. 

After reading this article you would understand how to import PowerShell modules into runspace and how to execute CmdLets with the use of Microsoft's Automation library. So If you are trying to execute powershell CmdLets/scripts using CreateProcess/ShellExecute APIs, stop doing that and proceed reading this article.

I have attached sample project MonadUtil (Monad is a codename for PowerShell) with this article. Before you proceed using code it is recommended to install PowerShell SDK. You can download PowerShell SDK from here.

Compilation and references 

If you see below errors during compilation of code, It means System.Management.Automation.dll is not referenced in your code. You can resolve references browsing at : C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll 

C++
The type or namespace name 'RunspaceInvoke' could not be found (are you missing a using directive or an assembly reference?)	
The type or namespace name 'Runspace' could not be found (are you missing a using directive or an assembly reference?)	
The type or namespace name 'InitialSessionState' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'Automation' does not exist in the namespace 'System.Management' (are you missing an assembly reference?)
The name 'PowerShell' does not exist in the current context
The name 'RunspaceFactory' does not exist in the current context

Using the code 

We need below namespaces to use Automation/PowerShell functionality support in our code.

C#
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Host;

m_Monad is an object of PowerShell class and using PowerShell.Create() method we create an empty pipe to PowerShell. m_SessionState is an object of InitialSessionState class which provides default and loaded module commands provided by powershell. m_SessionState is initiated by InintalSessionState.CreateDefault() method.

C#
m_Monad             =   PowerShell.Create();
m_SessionState      =   InitialSessionState.CreateDefault();

Once m_Monad and m_SessionState are initiated we'll load some modules in runspace, there are various modules supoorted by powershell. Some of default modules are listed below:

  • ActiveDirectory
  • AppLocker
  • BestPractices
  • BitsTransfer
  • FailoverClusters
  • PSDiagnostics
  • SeverManager
  • TroubleshootingPack

In MonadUtil I've loaded ActiveDirectory and BitsTransfer modules. A string array named modules is populated with these module names.

As shown in below code snippet m_SessionState imports list of modules that I've passed as a parameter. Then we create a single PowerShell runspace that uses the default host and runspace configuration that has been passed.

Opening runspace will load all cmdlets supported by loaded modules. Then I've initiated m_invoker, which will be used to execute cmdlets loaded in runspace.

C#
m_SessionState.ImportPSModule(modules);
m_rSpace = RunspaceFactory.CreateRunspace(m_SessionState);
m_rSpace.Open();
m_invoker = new RunspaceInvoke(m_rSpace);

After creation of invoker, it's a time to invoke a script. Now script is as shown below, which will list down all the running processes with name starting with either C,O,D or E.

get-process c*,o*,d*,e*

As shown in below code snippet m_invoker.Invoke() method is used to execute PowerShell script. After successful execution of script m_invoker will return collection of PSObjects, which we are storing in results object to iterate the result set.

In case bad CmdLet is passed as a script, Exception would be generated and It can be caught in System.Management.Automation.RuntimeException handler and read exception message/text from ex.Message.

In case bad parameters are passed to CmdLets, erroneous output can be read in ErrorRecord collection using m_Monad.streams.Error.ReadAll() method. We'll iterate this collection and display error string error.FullyQualifiedErrorId as a error message.

C#
Collection<ErrorRecord> errors = null;

Collection<PSObject> results = m_invoker.Invoke(script);
errors = m_Monad.Streams.Error.ReadAll();
if (errors.Count != 0)
{
    foreach (ErrorRecord error in errors)
    {
        Console.WriteLine("{0}", error.FullyQualifiedErrorId);
    }
    return -1;
}

As we know after successful execution of script output is stored in PsObject collection, we'll interate this collection to get appropriate result.

C#
foreach (PSObject result in results)
{
    Console.WriteLine("{0}", result.Members["ProcessName"].Value);                    
}

Conclusion 

I hope this might be useful to you and I'm sure, after reading this article and going through the code you would be able to load required modules and execute CmdLets/Script with the use of Automation APIs.

Please comment If you have any suggestions in order to improve this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)