<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:cs="http://blogs.iis.net/"><channel><title>Blog:\&amp;gt;_ : Extended Types</title><link>http://blogs.iis.net/sergeia/archive/tags/Extended+Types/default.aspx</link><description>Tags: Extended Types</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Simple way of extending PowerShell objects with custom methods</title><link>http://blogs.iis.net/sergeia/archive/2008/09/08/extending-powershell-objects-with-custom-methods.aspx</link><pubDate>Mon, 08 Sep 2008 07:45:00 GMT</pubDate><guid isPermaLink="false">50bcf3b4-f6fe-4638-adff-0c150e922e99:2606290</guid><dc:creator>sergeia</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/sergeia/rsscomments.aspx?PostID=2606290</wfw:commentRss><comments>http://blogs.iis.net/sergeia/archive/2008/09/08/extending-powershell-objects-with-custom-methods.aspx#comments</comments><description>&lt;P&gt;As you may know, IIS configuration is extensible. You could add new section, extend existing one by adding new schema file into folder containing schemas. All this was described in full details in the &lt;A href="http://learn.iis.net/page.aspx/241/configuration-extensibility/" mce_href="http://learn.iis.net/page.aspx/241/configuration-extensibility/"&gt;article&lt;/A&gt; of Tobin Titus. When we provide methods on configuration elements with COM extension, the only way to call it using configuration APIs is through creation of method instance, then creation of input parameters element on this instance, etc -- quite convoluted way. In PowerShell we expose it in more convenient way, like intrinsic methods on the object. User is able to call these methods exactly the same way as any other intrinsic methods of given object. Let's see how runtime methods work on site element:&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;&amp;gt;$site = get-webconfiguration '/system.applicationHost/sites/site[@name="mysite"]'&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;&amp;gt;$site.Stop()&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;&amp;gt;$site.State&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;Stopped&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;&amp;gt;$site.Start()&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;&amp;gt;$site.State&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=SourceCode&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;Started&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Methods that are coming from configuration extension could be called directly. Properties from extension are updated dynamically, like property State on web site object. In this post I will explain how it is done.&lt;/P&gt;
&lt;P&gt;PowerShell SDK provides number of ways to add new functionality to any object. You could add note property, script property or code property. You also could add script and code methods. When I started my implementation, my first attempt was to expose extended methods as PSCodeMethod, but this requires code reference to real code that will be executed when my exposed method is called. That was a problem. This real code has to be generated dynamically. It is simple enough code that will take input parameters and do all required actions to call configuration API. It could be implemented using type DynamicMethod, but it has to be done through emitting code into buffer, and this is quite tricky even for simple code. After spending couple of days with code generators and managed assembly language reference I started looking for alternative.&lt;/P&gt;
&lt;P&gt;PowerShell PSCodeMethod inherits from PSMethodInfo type. PSMethodInfo is an abstract class that PowerShell uses to work with extended methods: it has name, description and Invoke method. You could inherit your type from PSMethodInfo and it will be used exactly the same way as regular code method. Problem is that property Name is not virtual and there is no way to set it from inherited class. Fortunately, you could do it through reflection. After I realized that, coding took just couple of hours. PSMethodInfo is public class, therefore it has stay the same in future, and property Name shouldn't go away. Using reflection here is OK -- it is a workaround for mistake in type design.&lt;/P&gt;
&lt;P&gt;You will find implementation code at the end of this post. Two methods of CodeMethod class are specific to IIS 7 configuration: one is Invoke() -- that uses configuration APIs to call extension method, and another one is GetDefinition() that produces human readable signature for the methods using method definition from IIS configuration schema. You could use the same approach for any other type of method: defined in XML, or in WMI, or in ADSI, any time when you have programmatically accessible method definition and some generic way to invoke this method, for example passing its name and parameters. With direct implementation of extension method you don't need to bend your code to be compatible with PSCodeMethod -- you could access your native method directly.&lt;/P&gt;
&lt;P&gt;Class CodeProperty is implemented very similarly, the only difference is that it inherits from PSPropertyInfo and declares itself as type PSPropertyInfo.CodeProperty. You also have to do the same dirty hack with name. In CodeProperty methods get() and set() call native implementation, because of this property value is refreshing at every access. Let's see how this will looks like in PowerShell.&lt;/P&gt;
&lt;P class=style2&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;$s = get-webconfiguration "//sites/site[@name='test']"&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=style2&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;$s | gm Start&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#000080&gt;&amp;nbsp;&lt;SPAN class=style2&gt;TypeName: Microsoft.IIs.PowerShell.Framework.ConfigurationElement&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;BR class=style2&gt;&lt;SPAN class=style2&gt;Name&amp;nbsp; MemberType Definition&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;SPAN class=style2&gt;----&amp;nbsp; ---------- ----------&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;SPAN class=style2&gt;Start CodeMethod void Start()&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style2&gt;$s.bindings.Collection[0] | gm AddSslCertificate | fl *&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;BR class=style2&gt;&lt;SPAN class=style2&gt;TypeName : Microsoft.IIs.PowerShell.Framework.ConfigurationElement&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;SPAN class=style2&gt;Name : AddSslCertificate&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;SPAN class=style2&gt;MemberType : CodeMethod&lt;/SPAN&gt; &lt;BR class=style2&gt;&lt;SPAN class=style2&gt;Definition : void AddSslCertificate(System.String certificateHash, System.String certificateStoreName)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Method AddSslCertificate() is an extension, defined on each binding element of the site, and it has the following schema:&lt;/P&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style2&gt;&amp;lt;element name="bindings"&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;  &amp;lt;collection addElement="binding" clearElement="clear"&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style2&gt;  ...&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;  &amp;lt;method name="AddSslCertificate" extension="Microsoft.ApplicationHost.RscaExtension"&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;     &amp;lt;inputElement&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;        &amp;lt;attribute name="certificateHash" type="string" /&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;        &amp;lt;attribute name="certificateStoreName" type="string" defaultValue="MY" /&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;     &amp;lt;/inputElement&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=style2&gt;  &amp;lt;/method&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=style2&gt;&lt;FONT color=#000080&gt;   ... &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;How to use CodeMethod? Every time you have to return your object into PowerShell, you will convert it into PSObject, right? If you not doing this, PowerShell will do it for you, and it don't know that you have extended methods that has to be exposed in some specific way. So, you have to add those methods manually.&lt;/P&gt;
&lt;P&gt;PSObject myObject = new PSObject()&lt;/P&gt;
&lt;P&gt;myObject.Methods.Add(new CodeMethod("methodName", configurationMethod));&lt;/P&gt;
&lt;P&gt;...send object to PowerShell&lt;/P&gt;
&lt;P&gt;In my case I am adding CodeMethod created from extended configuration method instance and name of the method. In your case&amp;nbsp;you could pass and store any other type that will be used to call native&amp;nbsp;method implementation.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Enjoy,&lt;/P&gt;
&lt;P&gt;Sergei Antonov&lt;/P&gt;
&lt;P&gt;Here is CodeMethod implementation (provided as is without any support):&lt;/P&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;public class CodeMethod : PSMethodInfo&lt;/SPAN&gt;
{
&lt;SPAN class=style1&gt;   private ConfigurationMethod configMethod;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   string definition;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public CodeMethod(string name, ConfigurationMethod method)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      FieldInfo nameField = this.GetType().GetField("name", &lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          BindingFlags.NonPublic | BindingFlags.Instance);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (nameField != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          nameField.SetValue(this, name);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      configMethod = method;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      definition = GetDefinition(method);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public override PSMemberTypes MemberType&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      get {return PSMemberTypes.CodeMethod;}&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public override Collection&amp;lt;string&amp;gt; OverloadDefinitions&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      get&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          Collection&amp;lt;string&amp;gt; returnValue = new Collection&amp;lt;string&amp;gt;();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          returnValue.Add(this.definition);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          return returnValue;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public override string ToString()&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      StringBuilder returnValue = new StringBuilder();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      foreach (string overload in OverloadDefinitions)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;         returnValue.Append(overload);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;         returnValue.Append(", ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      returnValue.Remove(returnValue.Length - 2, 2);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      return returnValue.ToString();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public override string TypeNameOfValue&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      get { return typeof(CodeMethod).FullName;}&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;    public override PSMemberInfo Copy()&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      return new CodeMethod(Name, configMethod);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=style1&gt;&lt;FONT color=#000080&gt;   // This code is specific to IIS 7 configuration, &lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=style1&gt;&lt;FONT color=#000080&gt;   // and I put it here for illustration&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;   public override object Invoke(params object[] arguments)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;   {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (arguments == null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          throw new ArgumentNullException("arguments");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      ConfigurationMethodInstance mi = configMethod.CreateInstance();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      ConfigurationElementSchema input &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;         = configMethod.Schema.InputSchema;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (arguments.Length &amp;gt; 0)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          if (input != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              int parametersCount = 0;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              if (input.AttributeSchemas != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  parametersCount += input.AttributeSchemas.Count;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              if (input.ChildElementSchemas != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  parametersCount += input.ChildElementSchemas.Count;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              if (arguments.Length != parametersCount)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  throw new ArgumentException();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              PSObject argObject = new PSObject();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              // We produced definition from attributes first, then &lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              // from child elements. &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;              // We expect the same order on input.&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              int index = 0;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              if (input.AttributeSchemas != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  foreach (ConfigurationAttributeSchema s &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                     in input.AttributeSchemas)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                     argObject.Properties.Add(&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                        new PSNoteProperty(s.Name, &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                        arguments[index++]));&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              if (input.ChildElementSchemas != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  foreach (ConfigurationElementSchema s &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                     in input.ChildElementSchemas)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                     argObject.Properties.Add(&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                        new PSNoteProperty(s.Name, &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                        arguments[index++]));&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              mi.Input.Update(argObject);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      try&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          mi.Execute();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      catch (COMException ex)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          if (ex.ErrorCode == unchecked((int)0x80070490))&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;             // This happens when there is no binding &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;             // for FTP on the site.&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          else&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;             throw;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (mi.Output != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          if (configMethod.Schema&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                 .OutputSchema.AttributeSchemas.Count == 1)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              return mi.Output.Attributes[0].ToPSObject();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          else&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              return mi.Output.ToPSObject(null);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      return null;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;  }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;  private static string GetDefinition(ConfigurationMethod method)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;  {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      ConfigurationMethodSchema ms = method.Schema;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      ConfigurationElementSchema input = ms.InputSchema;&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      ConfigurationElementSchema output = ms.OutputSchema;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;       StringBuilder builder = new StringBuilder();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (output != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          if (output.AttributeSchemas.Count == 1)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              // Configuration returns any result as element. &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;              // We could produce&lt;/SPAN&gt;&lt;SPAN class=style1&gt; more reasonable signature here&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              ConfigurationAttributeSchema a &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                 = output.AttributeSchemas[0];&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append(a.ClrType.Name);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          else&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append("object");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      else&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          builder.Append("void");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      builder.Append(" ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      builder.Append(ms.Name);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      builder.Append("(");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      if (input != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;      {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          foreach (ConfigurationAttributeSchema a &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;             in input.AttributeSchemas)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append(a.ClrType);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append(" ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append(a.Name);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              builder.Append(", ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;           if (input.ChildElementSchemas != null)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              foreach (ConfigurationElementSchema child &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000080&gt;&lt;SPAN class=style1&gt;                 in input.ChildElementSchemas)&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              {&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  builder.Append("object");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  builder.Append(" ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  builder.Append(child.Name);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;                  builder.Append(", ");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;              }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;          builder.Remove(builder.Length - 2, 2);&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;       }&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;       builder.Append(")");&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;       return builder.ToString();&lt;/SPAN&gt;
&lt;SPAN class=style1&gt;    }&lt;/SPAN&gt;
}&lt;/FONT&gt;&lt;/PRE&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=2606290" width="1" height="1"&gt;</description><category domain="http://blogs.iis.net/sergeia/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.iis.net/sergeia/archive/tags/PSMethodInfo/default.aspx">PSMethodInfo</category><category domain="http://blogs.iis.net/sergeia/archive/tags/Extended+Types/default.aspx">Extended Types</category></item></channel></rss>