admin管理员组

文章数量:1237563

I am doing this PowerShell command Get-DistributionGroupMember but it is not returning the user's middle name. Is there something I am missing? Any other way to do this?

public List<EmailGroup> GetDistributionGroupMember(string distributionAddress, string displayName)
{
    ClearPowerShell();
    List<EmailGroup> EmailGroups = new List<EmailGroup>();

    powerShell.AddCommand("get-distributiongroupmember")
              .AddParameter("Identity", distributionAddress)
              .AddParameters(new Dictionary<string, object>()
              {
                    { "ResultSize", "Unlimited" }
              })
              .AddCommand("Select-Object")
              .AddArgument(new string[] { "PrimarySMTPAddress", "DisplayName", "FirstName", "Initials", "LastName" });

    Collection<PSObject> results = powerShell.Invoke();

    foreach (var result in results)
    {
        var propertyName = result.Properties.Where(w => w.Name == "DisplayName").Select(s => s.Value).FirstOrDefault();
        var propertyEmail = result.Properties.Where(w => w.Name == "PrimarySmtpAddress").Select(s => s.Value).FirstOrDefault();
        var FirstName = result.Properties.Where(w => w.Name == "FirstName").Select(s => s.Value).FirstOrDefault();
        var Initials = result.Properties.Where(w => w.Name == "Initials").Select(s => s.Value).FirstOrDefault();
        var LastName = result.Properties.Where(w => w.Name == "LastName").Select(s => s.Value).FirstOrDefault();

        EmailGroup emailGroup = new EmailGroup();
        emailGroup.Email = (string)propertyEmail;
        string fullName = string.Format("{0},{1},{2}", LastName, FirstName, Initials);

        emailGroup.FullName = fullName;
        emailGroup.GroupName = displayName;
        EmailGroups.Add(emailGroup);
    }


    if (powerShell.HadErrors)
    {
        var exception = powerShell.Streams.Error.ElementAt(0).Exception;
    }

    return EmailGroups;
}

Updated

I had to add a Get-contact ps call in order to get the Initials its very slow.

public List<EmailGroup> GetDistributionGroupMember(string distributionAddress, string displayName)
{
    ClearPowerShell();
    List<EmailGroup> EmailGroups = new List<EmailGroup>();
    Console.WriteLine(distributionAddress);
    powerShell.AddCommand("get-distributiongroupmember")
              .AddParameter("Identity", distributionAddress)
              .AddParameters(new Dictionary<string, object>()
              {
                    { "ResultSize", "Unlimited" }
              });



    Collection<PSObject> results = powerShell.Invoke();

    foreach (PSObject result in results)
    {
        ClearPowerShell();
        string propertyEmail = result.Properties.Where(w => w.Name == "PrimarySmtpAddress").Select(s => s.Value).FirstOrDefault().ToString();
        Console.WriteLine(propertyEmail);
        powerShell.AddCommand("Get-contact")
                  .AddParameter("Identity", propertyEmail)
                  .AddCommand("Select-Object")
                  .AddArgument(new string[] { "FirstName", "Initials", "LastName" });

        Collection<PSObject> contact = powerShell.Invoke();

        if (contact.Count != 0)
        {
            var FirstName = contact[0].Properties.Where(w => w.Name == "FirstName").Select(s => s.Value).FirstOrDefault();
            var Initials = contact[0].Properties["Initials"].Value;
            var LastName = contact[0].Properties.Where(w => w.Name == "LastName").Select(s => s.Value).FirstOrDefault();

            EmailGroup emailGroup = new EmailGroup();
            emailGroup.Email = propertyEmail;

            string fullName = string.Format("{0},{1},{2}", LastName, FirstName, Initials);

            emailGroup.FullName = fullName;
            emailGroup.GroupName = displayName;
            EmailGroups.Add(emailGroup);
        }
    }


    if (powerShell.HadErrors)
    {
        var exception = powerShell.Streams.Error.ElementAt(0).Exception;
    }

    return EmailGroups;
}

I am doing this PowerShell command Get-DistributionGroupMember but it is not returning the user's middle name. Is there something I am missing? Any other way to do this?

public List<EmailGroup> GetDistributionGroupMember(string distributionAddress, string displayName)
{
    ClearPowerShell();
    List<EmailGroup> EmailGroups = new List<EmailGroup>();

    powerShell.AddCommand("get-distributiongroupmember")
              .AddParameter("Identity", distributionAddress)
              .AddParameters(new Dictionary<string, object>()
              {
                    { "ResultSize", "Unlimited" }
              })
              .AddCommand("Select-Object")
              .AddArgument(new string[] { "PrimarySMTPAddress", "DisplayName", "FirstName", "Initials", "LastName" });

    Collection<PSObject> results = powerShell.Invoke();

    foreach (var result in results)
    {
        var propertyName = result.Properties.Where(w => w.Name == "DisplayName").Select(s => s.Value).FirstOrDefault();
        var propertyEmail = result.Properties.Where(w => w.Name == "PrimarySmtpAddress").Select(s => s.Value).FirstOrDefault();
        var FirstName = result.Properties.Where(w => w.Name == "FirstName").Select(s => s.Value).FirstOrDefault();
        var Initials = result.Properties.Where(w => w.Name == "Initials").Select(s => s.Value).FirstOrDefault();
        var LastName = result.Properties.Where(w => w.Name == "LastName").Select(s => s.Value).FirstOrDefault();

        EmailGroup emailGroup = new EmailGroup();
        emailGroup.Email = (string)propertyEmail;
        string fullName = string.Format("{0},{1},{2}", LastName, FirstName, Initials);

        emailGroup.FullName = fullName;
        emailGroup.GroupName = displayName;
        EmailGroups.Add(emailGroup);
    }


    if (powerShell.HadErrors)
    {
        var exception = powerShell.Streams.Error.ElementAt(0).Exception;
    }

    return EmailGroups;
}

Updated

I had to add a Get-contact ps call in order to get the Initials its very slow.

public List<EmailGroup> GetDistributionGroupMember(string distributionAddress, string displayName)
{
    ClearPowerShell();
    List<EmailGroup> EmailGroups = new List<EmailGroup>();
    Console.WriteLine(distributionAddress);
    powerShell.AddCommand("get-distributiongroupmember")
              .AddParameter("Identity", distributionAddress)
              .AddParameters(new Dictionary<string, object>()
              {
                    { "ResultSize", "Unlimited" }
              });



    Collection<PSObject> results = powerShell.Invoke();

    foreach (PSObject result in results)
    {
        ClearPowerShell();
        string propertyEmail = result.Properties.Where(w => w.Name == "PrimarySmtpAddress").Select(s => s.Value).FirstOrDefault().ToString();
        Console.WriteLine(propertyEmail);
        powerShell.AddCommand("Get-contact")
                  .AddParameter("Identity", propertyEmail)
                  .AddCommand("Select-Object")
                  .AddArgument(new string[] { "FirstName", "Initials", "LastName" });

        Collection<PSObject> contact = powerShell.Invoke();

        if (contact.Count != 0)
        {
            var FirstName = contact[0].Properties.Where(w => w.Name == "FirstName").Select(s => s.Value).FirstOrDefault();
            var Initials = contact[0].Properties["Initials"].Value;
            var LastName = contact[0].Properties.Where(w => w.Name == "LastName").Select(s => s.Value).FirstOrDefault();

            EmailGroup emailGroup = new EmailGroup();
            emailGroup.Email = propertyEmail;

            string fullName = string.Format("{0},{1},{2}", LastName, FirstName, Initials);

            emailGroup.FullName = fullName;
            emailGroup.GroupName = displayName;
            EmailGroups.Add(emailGroup);
        }
    }


    if (powerShell.HadErrors)
    {
        var exception = powerShell.Streams.Error.ElementAt(0).Exception;
    }

    return EmailGroups;
}
Share Improve this question edited Feb 11 at 19:20 Santiago Squarzon 60.3k5 gold badges23 silver badges51 bronze badges asked Feb 7 at 19:59 JeffersonJefferson 673 gold badges14 silver badges45 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 1

The issue seem to be a typo, you're projecting Initials with Select-Object yet are filtering for Initial on your Where. However, according to the docs, Get-DistributionGroupMember outputs a ReducedRecipient object, and said object doesn't seem to have such property.

In this case, you could also benefit from Invoke<T>() as long as you reference include the assembly in your project, in which case you could do:

Collection<ReducedRecipient> results;
using (PowerShell powerShell = PowerShell.Create())
{
    results = powerShell
        .AddCommand("Get-DistributionGroupMember")
        .AddParameters(new Dictionary<string, object>()
        {
            { "Identity", distributionAddress },
            { "ResultSize", "Unlimited" }
        })
        .Invoke<ReducedRecipient>();
}

foreach (ReducedRecipient result in results)
{
    // do work
}

To help you find the assembly to add it to your project, if it's a Binary module, you can do:

(Get-Command Get-DistributionGroupMember).Module.ImplementingAssembly.Location

And, according to the .NET doc of ReducedRecipient, the assembly should be called: Microsoft.Exchange.Data.Directory.dll.

If you can't include the assembly and have to stick to Collection<PSObject>, you should note that .Properties implements it's own indexer so this is perfectly valid:

foreach (PSObject result in results)
{
    object? displayName = result.Properties["DisplayName"].Value;
    // and so on
}

Regarding the new update, having to use Get-Contact and the code being too slow, you might be able to improve performance by letting PowerShell do all the work instead of having to do multiple PowerShell invocations calling Get-Contact for each group member.

This is how it'd look:

public EmailGroup[] GetDistributionGroupMember(
    string distributionAddress,
    string displayName)
{
    ClearPowerShell();
    Console.WriteLine(distributionAddress);

    Collection<Hashtable> results = powerShell.AddScript(@"
        param($identity)

        $members = Get-DistributionGroupmember -Identity $identity -ResultSize Unlimited
        foreach ($member in $members) {
            if (-not $member.PrimarySmtpAddress) {
                continue
            }

            $contact = Get-contact $member.PrimarySmtpAddress -ErrorAction SilentlyContinue
            if (-not $contact) {
                continue
            }

            @{
                PrimarySmtpAddress = $member.PrimarySmtpAddress
                FirstName          = $contact.FirstName
                Initials           = $contact.Initials
                LastName           = $contact.LastName
            }
        }")
        .AddParameter("identity", distributionAddress)
        .Invoke<Hashtable>();

    List<EmailGroup> EmailGroups = new List<EmailGroup>(results.Count);
    foreach (Hashtable result in results)
    {
        EmailGroup emailGroup = new EmailGroup()
        {
            GroupName = displayName,
            Email = result["PrimarySmtpAddress"].ToString(),
            FullName = $"{result["LastName"]},{result["FirstName"]},{result["Initials"]}"
        };

        EmailGroups.Add(emailGroup);
    }

    return EmailGroups.ToArray();
}

Last consideration

Assuming you are referencing the PowerShell SDK 7.0 or above in your project, you could change the foreach loop for a ForEach-Object -Parallel loop, allowing you to process the $members array in parallel, however by doing so, the complexity of the PowerShell script will increase, for example, you may need to handle throttling responses from the Exchange API.

本文标签: cexchange online GetDistributionGroupMember command not getting InitialsStack Overflow