Click here to Skip to main content
Click here to Skip to main content

Enable Remote PowerShell Execution in C#

, 4 Jun 2014
Rate this:
Please Sign up or sign in to vote.
Talks about executing PowerShell script remotely in PowerShell console; also describes how to do the same thing in C# code.

Introduction

This article introduces how to enable executing PowerShell script remotely in PowerShell console. It also describes how to execute PowerShell scripts locally or remotely in C# code.

All the introduced means are based on my real work and my intention is to manage a remote Windows Server 2008 R2 server by executing PowerShell scripts on a Windows 7 machine. Let me call the remote Windows Server 2008 R2 server as Remote Host and call the Windows 7 machine as Client.

The sample code shows how to execute PowerShell commands locally or remotely. You have to first enable PS remoting on both remote host and local client before executing PowerShell commands remotely.

Enable PowerShell Remote

To enable remote PowerShell execution, I did the following steps:

  1. Install PowerShell 4.0 on both Remote Host and Local Client. 4.0 is not mandatory. 2.0+ is OK. Actually, both Windows Server 2008 R2 and Windows 7 have PowerShell 2.0 installed by default.
  2. Add my Windows account to the Administrators group on both Remote Host and Local Client. If both machines are in the same domain, you can use your domain account; if both are in WORKGROUP, you can create one account on each machine with the same name and password, both in the Administrators group.
  3. Run the following command on Remote Host: winrm quickconfig. This command automatically analyzes and configures the WinRM service which is the core service for remote PowerShell execution.

The winrm quickconfig command is just for quick setup on experimental environment. For production environment, you should carefully configure the permission and firewall according to [2] and [3].

Execute PowerShell Script in C#

To execute PowerShell commands in your C# code, you need to reference "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll" in your project. Note: if your local PowerShell version is lower than 3.0, System.Management.Automation.dll could be in a different folder.

Your may need to use the following two namespaces:

using System.Management.Automation; 
using System.Management.Automation.Runspaces;    

You can use the PowerShell instance directly but a better way is to create a Runspace instance. Every PowerShell instance works in a Runspace. You can have multiple Runspaces to connect to different remote hosts at the same time.

The following code piece shows how to create a local Runspace and execute a command via a PowerShell instance:

Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{ 
    ps.Runspace = runspace;
    ps.AddScript("Get-Process"); 
    var results = ps.Invoke();
    // Do something with result ... 
}  
runspace.Close(); 

The following code demonstrates how to execute command remotely:

WSManConnectionInfo connectionInfo = new WSManConnectionInfo();
connectionInfo.ComputerName = machineAddress;
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{ 
    ps.Runspace = runspace;
    ps.AddScript("Get-Service"); 
    var results = ps.Invoke();
    // Do something with result ... 
}  
runspace.Close(); 

Note: both Runspace and PowerShell classes have implemented IDisposable. So don't forget closing or disposing their instances when you finish using them.

Most of the important methods of Runspace and PowerShell have both sync and async forms, for example, Runspace.Open and OpenAsync, Runspace.Close and CloseAsync, PowerShell.Invoke and BeginInvoke, etc.

Parse Results in C#

The return value type of PowerShell.Invoke is Collection<PSObject>. Each PSObject instance reflects the actual object properties and methods as key-value pairs in PSObject.Members. You can also use PSObject.Properties to access instance properties and use PSObject.Methods to access instance methods. Note: PSObject.BaseObject can be the actual object if the command is executed locally.

Let's take the Get-Process command as an example. When you execute Get-Process using ps.Invoke() like the previous code pieces demonstrates, you will get a Collection<PSObject>. Each PSObject instance represents a process. Then you can use the following code to retrieve process members:

// Execute Get-Process and get results ...
foreach (var result in results)
{ 
    Console.WriteLine(result.Members["Id"].Value);
    Console.WriteLine(result.Members["ProcessName"].Value);
    Console.WriteLine(result.Members["PrivateMemorySize64"].Value);
    result.Methods["Kill"].Invoke();
}
// Clean up code ...  

The code piece above works for both local and remote scenarios. Value is of the Object type. It may be a boxed value type. You can invoke the Kill method for a process and it can succeed if you have proper privileges.

If you execute your code locally, you can cast PSObject.BaseObject to the exact type instance like the following code piece does:

// Code to execute Get-Process and get results ... 
foreach (var result in results) 
{ 
    var process = (System.Diagnostics.Process)result.BaseObject;
    Console.WriteLine(process.Id);
    Console.WriteLine(process.ProcessName);
    Console.WriteLine(process.PrivateMemorySize64);
    process.Kill();
}
// Clean up code ... 

If you execute a big PS script via PowerShell.AddScript and PowerShell.Invoke (or BeginInvoke), the return value will only contain the results of the last executed command in the script.

Please refer to [1] for more details.

References

Most of the knowledge can be found in the following links:

License

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

About the Author

Zhuyun Dai
Architect
China China
Over 10-years experience in using Microsoft technologies.
At present, working as the architect of a clustered real-time data delivery and visualization system, responsible for the design of component architecture, product packaging and deployment, also targeting private cloud solutions for future.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 4 Jun 2014
Article Copyright 2014 by Zhuyun Dai
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid