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!


Reply via email to