Have Powershell process a list of objects from a C# program
I want to add a facility in a c# application where i can:
1) Take a collection of objects, and pass it to a powershell script from inside my c# application
2) Have the powershell script make changes to the the list of objects it was passed
3) Return that list of objects back to c#
I have an external class called Message
public class Message
{
public String name { get; set; }
public String from { get; set; }
public String to { get; set; }
public String date { get; set; }
public String subject { get; set; }
public String body { get; set; }
}
I populate the PSDataCollection list class as such:
PSDataCollection<Message> mlist = new PSDataCollection<Message>()
{
new Message { to="user1", from="user2", date = "1/10/2010 12:00:00 AM EST", subject = "hi there" , body = "hi again" },
new Message { to="user1", from="user3", date = "1/10/2010 12:00:00 AM EST", subject = "new messages" , body = "new messages" }
}
In the powershell script we want it to 1) Read each object 2) Adjust the date field by adding 2 hours to it
Implementation issues:
The following code is our attempt at getting it开发者_运维百科 working. The first issue we hit was how to import the Message class from an external DLL.
We tried this: Add-Type "G:\testBAL\bin\Debug\testBAL.dll" but got errors
Any help would be appreciated.
namespace TestProject
{
class Program
{
static void Main(string[] args)
{
PSDataCollection<Message> mlist = new PSDataCollection<Message>()
{
new Message { to="user1", from="user2", date = "1/10/2010 12:00:00 AM EST", subject = "hi there" , body = "hi again" },
new Message { to="user1", from="user3", date = "1/10/2010 12:00:00 AM EST", subject = "new messages" , body = "new messages" }
};
mlist.Complete();
PowerShell ps = PowerShell.Create()
.AddScript("Add-Type G:\testBAL\bin\Debug\testBAL.dll")
.AddCommand("Select-Object");
IAsyncResult async = ps.BeginInvoke<Message>(mlist);
foreach(PSObject result in ps.EndInvoke(async))
{
String to = ((Message)(result.BaseObject)).to;
Console.WriteLine("to=" + to);
}
}
}
}
You can use a PowerShell Runspace to Set and Get variables in a PowerShell Session created in a .NET application. I edited your date parameter and removed the EST so it could be easily be parsed by PowerShell's Get-Date cmdlet.
HTH
Doug
var mlist = new PSDataCollection<Message>()
{
new Message { to="user1", from="user2", date = "1/10/2010 12:00:00 AM", subject = "hi there" , body = "hi again" },
new Message { to="user1", from="user3", date = "1/10/2010 12:00:00 AM", subject = "new messages" , body = "new messages" }
};
var rs = RunspaceFactory.CreateRunspace();
rs.Open();
rs.SessionStateProxy.SetVariable("list", mlist);
var ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(@"
$list | ForEach {
$_.date = (Get-Date($_.date)).AddHours(2)
}
");
ps.Invoke();
var result = rs.SessionStateProxy.GetVariable("list") as PSDataCollection<Message>;
foreach (var item in result)
{
Console.WriteLine(item.date);
}
rs.Close();
From your description it appears you are missing the -Path switch.
You have to specify the -Path when you pass a DLL directly. See reference documentation here ... http://technet.microsoft.com/en-us/library/dd315241.aspx
I've loaded a C# assembly into a PowerShell script and used it like this:
$dllPath = "C:\path\library.dll"
$tmp = [Reflection.Assembly]::LoadFile($dllPath)
$obj = new-object Namespace.LibraryClass()
精彩评论