Search code examples
c#powershelloffice365runspace

Using PowerShell to Read Office 365 Group Members in C#


I'm attempting to connect to an Office 365 Group and list the membership of the Group using Powershell through a C# Project.

From this article, I've determined the command I need to use is

Get-UnifiedGroupLinks –Identity groupalias –LinkType Members

Here is my current code:

string connectionUri = "https://outlook.office365.com/powershell-liveid/";
SecureString secpassword = new SecureString();
foreach (char c in Password)
{
    secpassword.AppendChar(c);
}
PSCredential credential = new PSCredential(UserName, secpassword);

Runspace runspace = RunspaceFactory.CreateRunspace();
PSObject SessionHolder = null;
using (PowerShell powershell = PowerShell.Create())
{
    PSCommand command = new PSCommand();
    command.AddCommand("New-PSSession");
    command.AddParameter("ConfigurationName", "Microsoft.Exchange");
    command.AddParameter("ConnectionUri", new Uri(connectionUri));
    command.AddParameter("Credential", credential);
    command.AddParameter("Authentication", "Basic");
    powershell.Commands = command;

    runspace.Open();
    powershell.Runspace = runspace;
    Collection<System.Management.Automation.PSObject> result = powershell.Invoke();
    if (powershell.Streams.Error.Count > 0 || result.Count != 1)
    {
        throw new Exception("Fail to establish the connection");
    }
    else
        SessionHolder = result[0];
}
using (PowerShell powershell = PowerShell.Create())
{
    PSCommand command = new PSCommand();
    // –Identity groupalias –LinkType Members
    command = new PSCommand();
    command.AddCommand("Invoke-Command");
    command.AddParameter("ScriptBlock", System.Management.Automation.ScriptBlock.Create("Get-UnifiedGroupLinks"));
    command.AddParameter("Session", SessionHolder);
    command.AddParameter("Identity", groupAddress);
    command.AddParameter("LinkType", "Members");
    powershell.Commands = command;
    powershell.Runspace = runspace;

    Collection<PSObject> PSOutput = powershell.Invoke();
    // loop through each output object item
    foreach (PSObject outputItem in PSOutput)
    {

    }
}

Variables used above, declaration not shown: "UserName", "Password", "groupAddress"

I am able to make a connection to the service, but when I try to get the group members I get the error "A parameter cannot be found that matches parameter name 'Identity'"

I'm not sure how to proceed in troubleshooting my code. I've tried the Group email, Group Alias, and Group Display Name in the Identity parameter. Perhaps I have something else wrong?

I'm using the following Libraries in Visual Studio 2017 on a Windows 10 machine:

using System.Management.Automation;
using System.Management.Automation.Runspaces;

Solution

  • I found a bit of code that makes things work... It slows it down, so I'm not sure if there is a better way, but here is my updated code:

    string connectionUri = "https://outlook.office365.com/powershell-liveid/";
    SecureString secpassword = new SecureString();
    foreach (char c in Password)
    {
        secpassword.AppendChar(c);
    }
    PSCredential credential = new PSCredential(UserName, secpassword);
    
    Runspace runspace = RunspaceFactory.CreateRunspace();
    PSObject SessionHolder = null;
    using (PowerShell powershell = PowerShell.Create())
    {
        string connectionUri = "https://outlook.office365.com/powershell-liveid/";
        SecureString secpassword = new SecureString();
        foreach (char c in Password)
        {
            secpassword.AppendChar(c);
        }
        PSCredential credential = new PSCredential(UserName, secpassword);
        PSCommand command = new PSCommand();
        command.AddCommand("New-PSSession");
        command.AddParameter("ConfigurationName", "Microsoft.Exchange");
        command.AddParameter("ConnectionUri", new Uri(connectionUri));
        command.AddParameter("Credential", credential);
        command.AddParameter("Authentication", "Basic");
        powershell.Commands = command;
    
        runspace.Open();
        powershell.Runspace = runspace;
        Collection<System.Management.Automation.PSObject> result = powershell.Invoke();
        if (powershell.Streams.Error.Count > 0 || result.Count != 1)
            throw new Exception("Fail to establish the connection");
        else
            SessionHolder = result[0];
    
        PSCommand ImportSession = new PSCommand();
        ImportSession.AddCommand("Import-PSSession");
        ImportSession.AddParameter("Session", SessionHolder);
        powershell.Commands = ImportSession;
        powershell.Invoke();
    
        PSCommand GrabGroup = new PSCommand();
        GrabGroup.AddCommand("Get-UnifiedGroupLinks");
        GrabGroup.AddParameter("Identity", GroupAddress);
        GrabGroup.AddParameter("LinkType", "Members");
        powershell.Commands = GrabGroup;
        Collection<PSObject> PSOutput_GroupMembers = powershell.Invoke();
        foreach (PSObject outputItem in PSOutput_GroupMembers)
        {
            //Process Members
        }
    }
    

    The key seems to be that I need to Import the session before I can begin using it.