none
Handling Multivalue Properties When Using a powershell runspace.

    Question

  • Hello,

    I am using powershell automation from C#.  I am having trouble with handling multi-value attributes when they are returned from an invoked pipeline. The command I am using is Get-Mailbox. I get the results back using the following code. However when an attribute is not a string but rather an MultiValue it is returned as a PSObject Type.  I you use a .ToString() it takes the multivalue attribute and just returns the value a space separated value. What I would like to do is have get the value back as an array. I was looking at (and tried) the suggestion made here: http://blogs.msdn.com/b/webdav_101/archive/2008/02/08/handling-results-of-calling-powershell-multivalued-and-string-arrays.aspx but in my case this did not work. In fact the values returned when a multivalued attribute is involved are of type PSObject. It is not obvious to me how to get the values out of the collection. Does anyone have a suggestion?

    Thanks

    Bill 

                    

    Collection<PSObject> ecscommandResults = commandPipeLine.Invoke();                 if (ecscommandResults.Count > 0)                 {                     foreach (PSObject ecscommandResult in ecscommandResults)                     {                         Hashtable thisObjectProperties = newHashtable();                         int thisObjectPropertiesCount = 0;                         foreach (PSProperty property in ecscommandResult.Properties)                         {                             string propertyName;                             propertyName = property.Name;                             Object propertyValue = property.Value;                             if (property.Value != null)                             {                                                                 Console.WriteLine(propertyValue.ToString());         

                        }                         }                     }                 }

     
    Wednesday, February 29, 2012 4:01 AM

Answers

  • Hello,

    I worked this out. When the type of the property value is a PSObject you can retrive the BaseObject property as an ArrayList. Problem solved.

    Bill

    				Type propertyValueType = propertyValue.GetType();
                                    switch(propertyValueType.Name)
                                    {
                                        case "PSObject":
                                            PSObject multivalueAttribute = (PSObject)propertyValue;
                                            ArrayList attributeValues = (ArrayList)multivalueAttribute.BaseObject;
    • Marked as answer by williamtholmes Wednesday, March 14, 2012 1:57 AM
    Wednesday, March 14, 2012 1:57 AM

All replies

  • ecscommandResult.Properties returns PSPropertyInfo. So make that change and it should work. So your code should look like this:

    foreach (PSObject ecscommandResult in results)
                        {
                            foreach (PSPropertyInfo property in ecscommandResult.Properties)
                            {
                                try
                                {
                                    string propertyName;
                                    propertyName = property.Name;
                                    Object propertyValue = property.Value;
                                    if (property.Value != null)
                                    {
                                        Console.WriteLine(propertyValue.ToString());
                                    }
                                }
                                catch (Exception ex)
                                {
                                    string s = ex.Message;
                                }
                            }


    Thanks & Regards
    Bhavik Solanki

    Please click “Mark as Answer” if this post answers your question and click "Vote as Helpful if this Post helps you.

    Wednesday, February 29, 2012 6:22 AM
  • Hello,

    I am not having any trouble getting the property values. No exceptions are occuring.  What I am having trouble with is getting the multivalue properties values out as individual items. I have been attempting to use the code example from: http://blogs.msdn.com/b/webdav_101/archive/2008/02/08/handling-results-of-calling-powershell-multivalued-and-string-arrays.aspx which I have appended below. Unfortunately in the case of the EmailAddresses attribute from a Get-Mailbox command, the multivalue properties which are returned as type: PSObject are not "Castable" to an ICollection.  It is not clear to me how to access the individual items in the PSObject that is returned. What I am after is the indivdual EmailAddress Values. If you use the propertyValue.ToString() method as I have shown in the example you get a string with the following format: {smpt:address@domain.com SMTP:anotheraddress@domain.com}  while I could split this string into the individaul values using the space as a delimiter I am not comfortable with that technique.  I would like to be able to handle (in a general sense) multivalue attributes as Arrays or ArrayLists.

    Again there are no errors occuring in my current code. I just want to improve its handling of multi-value attributes when they are returned.

    Thanks

    Bill

        //==============================================================================================
        // DumpAllProperties
        //============================================================================================== 
     
        static void DumpAllProperties(ref ICollection<PSObject> results)
     
        {
            // === All properties =================================================================
     
     
            // Use this foreach for getting all properties:
     
            Trace.WriteLine("\n");
     
            Trace.WriteLine("------=======***************************=======------");
            Trace.WriteLine("------=======*****  ALL PROPERTIES  ****=======------");
            Trace.WriteLine("------=======***************************=======------");
     
            Trace.WriteLine("\n");
     
            foreach (PSObject result in results)  // process result set.
            {
                foreach (PSProperty prop in result.Properties)
                {
                    String propName = prop.Name;
                    Object propValue = prop.Value;
     
                    //string strMsg;
     
                    if (propValue != null)
                    {
                        Trace.WriteLine("----[Begin: " + prop.Name + "]---------------------------------\n");
                        Trace.WriteLine("    TypeNameOfValue:  " + prop.TypeNameOfValue + "");
                        Trace.WriteLine("    MemberType:       " + prop.MemberType.ToString() + "");
                        Trace.WriteLine(" ");
                        if (propValue is ICollection)
                        {
                            ICollection collection = (ICollection)propValue;
                            Trace.WriteLine("    Multi-valued Property:");
                            foreach (object value in collection)
                            {
                                Trace.WriteLine("      Value:  " + value.ToString() + "");
                            }
                            Trace.WriteLine("");
                        }
                        else
                        {
                            Trace.WriteLine("    Value:  " + propValue.ToString() + "");
                            Trace.WriteLine("");
                        }
                    }
                }
            }
        }
    Wednesday, February 29, 2012 8:57 PM
  • Hi,

    Based on my understanding, propertyValue is a multivalued object, the Handling results of calling Powershell - Multivalued and string arrays blog should work, please try below code, and post out the message here:

    foreach (PSProperty property in ecscommandResult.Properties)
                            {
                                
    String propertyName = property.Name;
    Object propertyValue = property.Value;
                                if (property.Value != null)
                                {
                                   
                                    Console.WriteLine(propertyValue.ToString());
            
                        }
    if (propertyValue != null)
    {
    Trace.WriteLine("----[Begin: " + property.Name + "]---------------------------------\n");
    Trace.WriteLine(" TypeNameOfValue: " + property.TypeNameOfValue + "");
    Trace.WriteLine(" MemberType: " + property.MemberType.ToString() + "");
    Trace.WriteLine(" ");
    if (propertyValue is ICollection)
    {
    ICollection collection = (ICollection)propertyValue;
    Trace.WriteLine(" Multi-valued Property:");
    foreach (object value in collection)
    {
    Trace.WriteLine(" Value: " + value.ToString() + "");
    }
    Trace.WriteLine("");
    }
    else
    {
    Trace.WriteLine(" Value: " + propertyValue.ToString() + "");
    Trace.WriteLine("");
    }
    }
    }

    Hope this helps.

    Best Regards,

    Yan Li

    TechNet Subscriber Support

    If you are TechNet Subscription user and have any feedback on our support quality, please send your feedback here.


    Yan Li

    TechNet Community Support

    Monday, March 05, 2012 2:40 AM
    Moderator
  • Hi ,
     
    We have not heard from you in a couple of days.
    Please post back at your convenience if we can assist further.
     
    Enjoy your day!

    Best Regards,

    Yan Li

    TechNet Subscriber Support

    If you are TechNet Subscription user and have any feedback on our support quality, please send your feedback here


    Yan Li

    TechNet Community Support

    Wednesday, March 07, 2012 1:37 AM
    Moderator
  • Hello,

    I posted that exact code and clearly indicated that it DID NOT WORK! The property value is not an ICollection. Does anyone else have a suggestion?

    Bill

    Friday, March 09, 2012 7:56 PM
  • Hello,

    I worked this out. When the type of the property value is a PSObject you can retrive the BaseObject property as an ArrayList. Problem solved.

    Bill

    				Type propertyValueType = propertyValue.GetType();
                                    switch(propertyValueType.Name)
                                    {
                                        case "PSObject":
                                            PSObject multivalueAttribute = (PSObject)propertyValue;
                                            ArrayList attributeValues = (ArrayList)multivalueAttribute.BaseObject;
    • Marked as answer by williamtholmes Wednesday, March 14, 2012 1:57 AM
    Wednesday, March 14, 2012 1:57 AM