Here are the "guts" out of a minimal (very minimal) PowerShell host. Note that this code is not production quality (it doesn't have any anti-injection protection). But it should get you started, and starts out with references.
// references: // // [appdomain]::currentdomain.getassemblies() | sort -property fullname | format-table fullname -- for assemblies in web.config // http://blogs.msdn.com/powershell/Default.aspx?p=3 -- regarding impersonation // http://www.thescripts.com/forum/thread416915.html -- regarding assemblies // http://msdn2.microsoft.com/en-us/library/bfyb45k1.aspx -- assemblies element definition // http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2097064&SiteID=17 -- embedded PowerShell command execution // http://knicksmith.blogspot.com/2007/03/managing-exchange-2007-recipients-with.html -- exchange management shell wrapper class // http://www.leastprivilege.com/HostingPowerShellInASPNET.aspx -- the original basic script protected void _btnInvoke_Click (object sender, EventArgs e) { bool processResults; PipelineReader<object> errorList; Runspace rs; Pipeline cmd; Collection<PSObject> results; StringBuilder sb; rs = GetRunspace(); cmd = rs.CreatePipeline(_txtCommand.Text); sb = new StringBuilder(); results = null; processResults = true; try { results = cmd.Invoke(); } catch (System.Management.Automation.CommandNotFoundException) { sb.AppendLine("The command you entered is not recognized as a cmdlet, function, operable program, or script file. Verify the command and try again."); sb.AppendLine(); processResults = false; } catch (System.Management.Automation.ParameterBindingException) { sb.AppendLine("An error exists in the parameters provided to the command you entered."); sb.AppendLine(); processResults = false; } if (processResults) { sb.AppendLine("Command: " + _txtCommand.Text); sb.AppendLine(); foreach (PSObject ps in results) { sb.AppendLine(ps.ToString()); } errorList = cmd.Error; if (errorList.Count > 0) { sb.AppendLine(); sb.AppendLine("Error(s):"); sb.AppendLine(); foreach (object error in errorList.ReadToEnd()) { sb.AppendLine(error.ToString()); } } sb.AppendLine(); } _txtOutput.Text += sb.ToString(); cmd = null; } protected Runspace GetRunspace() { if (Cache["rs"] == null) { Runspace rs = RunspaceFactory.CreateRunspace(); rs.Open(); Cache["rs"] = rs; } return (Runspace)Cache["rs"]; } Regards, Michael B. Smith Consultant and Exchange MVP http://TheEssentialExchange.com From: mck1012 [mailto:mck1...@gmail.com] Sent: Friday, June 25, 2010 12:09 AM To: MS-Exchange Admin Issues Subject: Re: .Net Programming for Exchange 2010 Would someone be able to post some of their code so others an use as a reference. I am trying to learn c# for this exact reason and some samples would be great. The On Thu, Jun 24, 2010 at 4:40 PM, Michael B. Smith <mich...@smithcons.com<mailto:mich...@smithcons.com>> wrote: Just kind-of reinforcing what Rob said, with a bit more detail. Exchange System Objects (XSO) are the internal Exchange interfaces represented via Microsoft.Exchange.*. Except for a handful of documentation on data formats, XSO is undocumented. Given how reflection works in the CLR, obviously quite a bit is discoverable. Using that undocumented information isn't a good idea. The interfaces change DRAMATICALLY from release to release and may change from service pack to service pack. Since they are undocumented, Microsoft doesn't have to keep them compatible. There are three supported ways to interface to Exchange 2010: MAPI (challenging, not legally accessible from managed code, but very powerful), Exchange Web Services (EWS, very much about user mailboxes and address books, not about system management), and PowerShell (all about management). There are some exceptions, but basic MAPI is very consistent, ever since Exchange 5.5. EWS is somewhat new (Exchange 2007 sp1), but I think that all code written since then is compatible with the current implementation, and Exchange 2010 adds some new features. PowerShell had breaking changes going from 2007 -> 2010, but I don't think anything broke between 2007 <-> 2007 sp1 <-> 2007 sp2. There may be a breaking change in 2010 going to sp1 in one of the DAG cmdlets, but if so, it was necessary. Writing a PowerShell host is fairly simple. It only requires a few dozen lines of C#. You can, of course, also call complex Windows Forms and Windows Presentation Format windowing objects from within PowerShell, since it is a fairly well-behaved .NET environment (I've taught workshops in doing this and this is, I believe, what Rob did himself). From within the PowerShell host, you load the Exchange profile (just like the Exchange Management Shell) and off you go... This is exactly what the Exchange Management Console does. You can even have the PowerShell host as a web page (although that requires the application pool to have an Exchange administrator as an Identity - not something to be done lightly). This is what Remote PowerShell does (in combination with Windows Remote Management). Regards, Michael B. Smith Consultant and Exchange MVP http://TheEssentialExchange.com<http://theessentialexchange.com/> From: Paul Steele [mailto:paul.ste...@acadiau.ca<mailto:paul.ste...@acadiau.ca>] Sent: Thursday, June 24, 2010 3:01 PM To: MS-Exchange Admin Issues Subject: .Net Programming for Exchange 2010 I like to write simple C#-based GUI utilities for my staff to simplify some of the repetitive tasks such as creating accounts. Now that we've upgraded to Exchange 2010 I have a few utilities that need updating. I've been doing some Google searches for sample programs and the examples refer to a class library Microsoft.Exchange. Unfortunately I haven't been able to find where this class is located in order to add it to my Visual Studio Project. There are a lot of built-in Microsoft.* components in the reference library, but not Microsoft.Exchange. I've looked on the Exchange installation media and also checked on MSDN but don't see anything there. Does anyone know where I can find the components needed for .Net programming for Exchange 2010? Thanks!