Query of two requests to Microsoft Graph through C# code and export a Json file

Carlos Jahir Carreño Hernandez 125 Reputation points
2023-10-17T23:44:56.96+00:00

Good evening, I've followed many Microsoft guides and tutorials, but I've hit a roadblock that hasn't allowed me to progress.

trying to create a program that queries the IDs of devices and then, using a 'for' loop, performs another query with those IDs in Microsoft Graph.

//first request
var devices =  await graphClient.Devices.GetAsync();      
 for (int i = 0; i < devices.Count; i++) 
//at this point, it throws an error 'Operator '<' cannot be applied to operands of type 'int' and 'method group' CS0019.
{
             var deviceId = **devices[i]**.id.ToString();
//var deviceId = **devices[i]**.id.ToString(); with this instruction, it throws another error: Cannot apply indexing with [] to an expression of type 'DeviceCollectionResponse' CS0021."

             var policies = await graphClient.DeviceManagement.ManagedDevices["{managedDevice-id}"].DeviceCompliancePolicyStates.GetAsync((requestConfiguration) =>
             {
                requestConfiguration.QueryParameters.Select = new string []{ "displayName","id" };
                });
                Console.WriteLine("Politicas por dispositivos:" + JsonConvert.SerializeObject(policies));
            }

I'm showing the entire code for it to be analyzed because I haven't found how or the way to continue

using System;
using System.Linq;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.Graph;
using Newtonsoft.Json;

namespace new_project
{
    class Program
    {
        static async Task Main(string[] args)
        {

            //Toda esta seccion es la autenticacion a la aplicaicon cread en azure
            string[] scopes = {"https://graph.microsoft.com/.default"};
           // Credenciales de la aplicacion
           var clientId = "7c403db0-712f-4fc8-b169-9df8c58b8313";
           var tenantId = "bc91deb2-7d0d-4645-b2b0-6a4aefc8d6ff";
           var clientSecret = "b.V8Q~jjjpLk~jRfSMeQ.ThT-YgQUqO5u.HpfajZ";
           // using Azure.Identity;
           var options = new ClientSecretCredentialOptions
           {
            AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
            };
            var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);
            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);



            //consulta de microsoft graph



            var devices =  await graphClient.Devices.GetAsync();          
            for (int i = 0; i < devices.Count; i++) 
            {
             var deviceId = devices[i].id.ToString();
             var policies = await graphClient.DeviceManagement.ManagedDevices["{managedDevice-id}"].DeviceCompliancePolicyStates.GetAsync((requestConfiguration) =>
             {
                requestConfiguration.QueryParameters.Select = new string []{ "displayName","id" };
                });
                Console.WriteLine("Politicas por dispositivos:" + JsonConvert.SerializeObject(policies));
            }
            Console.ReadLine();
        }
    }      
}  

Thank you very much. Any guidance or documentation to help me continue would be helpful.

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,611 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,129 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
22,547 questions
{count} votes

Accepted answer
  1. CarlZhao-MSFT 43,491 Reputation points
    2023-10-18T10:00:45.4066667+00:00

    Hi @carlos carreno

    You should only iterate over the count of the device set's value array.

    var devices = await graphClient.Devices.GetAsync();
    
    for (int i = 0; i < devices.Value.Count; i++) {
    
        var deviceId = devices.Value[i].DeviceId.ToString();
    
    }
    

    Hope this helps.

    If the reply is helpful, please click Accept Answer and kindly upvote it. If you have additional questions about this answer, please click Comment.


1 additional answer

Sort by: Most helpful
  1. Carlos Jahir Carreño Hernandez 125 Reputation points
    2023-10-23T12:37:31.9233333+00:00

    Definitive solution.

    Thanks to the MS community, I present the solution here, now running without any issues and processing my requests.

    This is the corrected code, along with an explanation:

    This code is written in C# and performs the following tasks:

    1. Imports necessary libraries for the application.
    2. Defines a class ResponseData to store device and policy information.
    3. In the Main method, it authenticates with an Azure application using client ID, tenant ID, and client secret.
    4. Initializes a list responseList to store response data.
    5. Uses the Microsoft Graph API to retrieve a list of devices and their device compliance policies.
    6. Iterates through each device, retrieves its compliance policies, and adds the device ID and policy name to the responseList.
    7. Handles exceptions if there are any errors during the process.
    8. Finally, it serializes the responseList to a JSON object and prints it to the console.

    This code is essentially a C# console application that fetches device compliance data from Microsoft Graph and stores it in a list for further processing or analysis.

    [
        {
            "deviceId": "DeviceID1",
            "policyName": "PolicyName1"
        },
        {
            "deviceId": "DeviceID1",
            "policyName": "PolicyName2"
        },
        {
            "deviceId": "DeviceID2",
            "policyName": "PolicyName3"
        },
        {
            "deviceId": "DeviceID2",
            "policyName": "PolicyName4"
        },
        // More entries for other devices and policies...
    ]
    
    

    Here are notes for each significant part of the provided code:

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using Azure.Identity;
    using Microsoft.Graph;
    using Newtonsoft.Json;
    using Microsoft.Kiota.Http.HttpClientLibrary;
    
    • These lines include necessary libraries for the application. Notably, it imports libraries for working with Azure, Microsoft Graph, JSON serialization, and other dependencies.
    namespace new_project
    {
    
    • The code is placed within the new_project namespace.
    public class ResponseData {
        public string deviceId{get; set;}
        public string policyName{get; set;}
    
        public ResponseData(string deviceId, string policyName) {
            this.deviceId = deviceId;
            this.policyName = policyName;
        }
    }
    
    • Defines a class ResponseData with properties deviceId and policyName. It also includes a constructor for initializing these properties.
    class Program
    {
        static async Task Main(string[] args)
        {
    
    • The code enters the Main method, which is the entry point for the application. This method is asynchronous, and it accepts command-line arguments.
    //Toda esta seccion es la autenticacion a la aplicaicon creada en Azure
    string[] scopes = {"https://graph.microsoft.com/.default"};
    
    • This section sets up the authentication for the application using Azure and specifies the required scopes.
    // Credenciales de la aplicacion
    var clientId = "xxxxxxxxxxxxxxxxxxx";
    var tenantId = "xxxxxxxxxxxxxxxxxxxxxx";
    var clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    
    • These lines define the client ID, tenant ID, and client secret used for authentication.
    // using Azure.Identity;
    var options = new ClientSecretCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    };
    var clientSecretCredential = new ClientSecretCredential(
        tenantId, clientId, clientSecret, options);
    
    • It sets up the client secret credential with Azure Identity for authentication.
    var responseList = new List<ResponseData>();
    
    • Initializes a list to store response data.
    //consulta de Microsoft Graph
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
    var devices = await graphClient.Devices.GetAsync();
    
    • Creates a Microsoft Graph client and fetches a list of devices from the Microsoft Graph API.
    for (int i = 0; i < devices.Value.Count; i++) 
    {
        var dispositivoId = devices.Value[i].DeviceId.ToString();
    
    • Iterates through the list of devices retrieved.
    try
    {
        var policies = await graphClient.DeviceManagement.ManagedDevices[dispositivoId].DeviceCompliancePolicyStates.GetAsync();
    
    • Within the loop, it attempts to fetch compliance policies for each device.
    foreach(var policy in policies.Value) {
        responseList.Add(new ResponseData(dispositivoId, policy.DisplayName));
    }
    
    • Iterates through the policies and adds them to the responseList.
    // Print the JSON object to the console
    
    • Indicates the intention to print a JSON object to the console.
    }
    catch (Exception ex)
    {
        // Handle the exception here.
        // For example, log the exception or display a friendly error message to the user.
        Console.WriteLine($"Error getting device compliance policy states for device {dispositivoId}: {ex.Message}");
    }
    
    • Handles exceptions, such as printing an error message if there is an issue with fetching policy data.
    Console.WriteLine(JsonConvert.SerializeObject(responseList));
    
    • Finally, it serializes the responseList to a JSON object and prints it to the console.
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using Azure.Identity;
    using Microsoft.Graph;
    using Newtonsoft.Json;
    using Microsoft.Kiota.Http.HttpClientLibrary;
    
    
    namespace new_project
    {
    
        public class ResponseData {
            public string deviceId{get; set;}
            public string policyName{get; set;}
    
            public ResponseData(string deviceId, string policyName) {
                this.deviceId = deviceId;
                this.policyName = policyName;
    
            }
        }
        class Program
        {
            static async Task Main(string[] args)
            {
                //Toda esta seccion es la autenticacion a la aplicaicon cread en azure
                string[] scopes = {"https://graph.microsoft.com/.default"};
               // Credenciales de la aplicacion
               var clientId = "7c403db0-712f-4fc8-b169-9df8c58b8313";
               var tenantId = "bc91deb2-7d0d-4645-b2b0-6a4aefc8d6ff";
               var clientSecret = "b.V8Q~jjjpLk~jRfSMeQ.ThT-YgQUqO5u.HpfajZ";
               // using Azure.Identity;
               var options = new ClientSecretCredentialOptions
               {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                };
                var clientSecretCredential = new ClientSecretCredential(
                    tenantId, clientId, clientSecret, options);
    
                var responseList = new List<ResponseData>();
                    //consulta de microsoft graph
                var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
                var devices = await graphClient.Devices.GetAsync();
                for (int i = 0; i < devices.Value.Count; i++) 
                {
                    var dispositivoId = devices.Value[i].DeviceId.ToString();
                    try
                    {
                        var policies = await graphClient.DeviceManagement.ManagedDevices[dispositivoId].DeviceCompliancePolicyStates.GetAsync();
                        
                        foreach(var policy in policies.Value) {
                            responseList.Add(new ResponseData(dispositivoId, policy.DisplayName ));
                        }
                        // Print the JSON object to the console
    
                    }
                    catch (Exception ex)
                    {
                        // Handle the exception here.
                        // For example, log the exception or display a friendly error message to the user.
                        Console.WriteLine($"Error getting device compliance policy states for device {dispositivoId}: {ex.Message}");
                    }
                }
                Console.WriteLine(JsonConvert.SerializeObject(responseList));
            }
        } 
    } 
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.