Search code examples
c#azuremicrosoft-graph-api

C# Graph Beta get all Assignment Types with their Detection Rules for all Win32LobApps in 1 call


I'm try to get all MobileApps together with their Detection Rules in just 1 call to GraphAPI Beta. Using PostMan, sending 1 GET request https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?$filter=isof('microsoft.graph.win32LobApp')&$top=1000 would return you a list of Top 100 MobileApps in JSON format. Each object would have a Detection Rules, containing various data which is not really the case when doing the same in C# using the Graph Beta library(at least to my knowledge).

Here's a method I wrote to try and get the assignment ids, detection rules and createdOn:

public async Task<List<GraphResponseModel>> GetAllWin32LobAppWithDetectionRules()
    {
        try
        {
            
            Win32LobAppRegistryDetection detectionRule = null;
            List<GraphResponseModel> graphResponseModelList = new();
            List<string?> idsFromAssignment = [];

            // Get all Win32LobApps
            var mobileApps = await _graphClient.DeviceAppManagement.MobileApps.GetAsync(context =>
            {
                context.QueryParameters.Filter = "isof('microsoft.graph.win32LobApp')";
                context.QueryParameters.Expand = new string[] {"assignments"};
            });

            foreach (var mobileApp in mobileApps.Value)
            {
                mobileApp.Assignments.ForEach(assignment =>
                {
                    idsFromAssignment.Add(assignment.Id);
                });
                // Cast the mobileApp to a Win32LobApp
                var win32LobApp = (Win32LobApp)mobileApp;
                
                _detectionRulesModel = null;
                
                foreach (var detection in win32LobApp.DetectionRules)
                {
                    if (detection.OdataType == "#microsoft.graph.win32LobAppRegistryDetection")
                    {
                        detectionRule = (Win32LobAppRegistryDetection)detection;
                        _detectionRulesModel = new DetectionRulesModel(detectionRule.OdataType, (bool)detectionRule.Check32BitOn64System, detectionRule.KeyPath, detectionRule.ValueName,detectionRule.DetectionType.Value.ToString(), detectionRule.Operator.ToString(), detectionRule.DetectionValue);
                    }
                    else
                    {
                        continue;
                    }
                    _createdOn = mobileApp.CreatedDateTime.Value.DateTime;
                   
                    graphResponseModelList.Add(new GraphResponseModel(idsFromAssignment, _detectionRulesModel, _createdOn));
                }
            }
            return graphResponseModelList;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        } 
    }

Unfortunately, I get a response back with the list containing the actual amount of software I own, but only the _createdOn field is populated, other fields are empty.


Solution

  • I get a response back with the list containing the actual amount of software I own, but only the _createdOn field is populated, other fields are empty.

    First, check that they are correctly accessing the detection rules and assignments. Then, Add the values to the model properly within the loop.

    Code:

    public async Task<List<GraphResponseModel>> GetAllWin32LobAppWithDetectionRules()
    {
        try
        {
            List<GraphResponseModel> graphResponseModelList = new List<GraphResponseModel>();
    
            // Get all Win32LobApps
            var mobileApps = await _graphClient.DeviceAppManagement.MobileApps.GetAsync(context =>
            {
                context.QueryParameters.Filter = "isof('microsoft.graph.win32LobApp')";
                context.QueryParameters.Expand = new string[] { "assignments", "detectionRules" };
            });
    
            foreach (var mobileApp in mobileApps.Value)
            {
                List<string> assignmentIds = mobileApp.Assignments.Select(assignment => assignment.Id).ToList();
                DateTime createdOn = mobileApp.CreatedDateTime.Value.DateTime;
                List<DetectionRulesModel> detectionRulesModels = new List<DetectionRulesModel>();
    
                // Check if the mobileApp has detection rules
                if (mobileApp.DetectionRules != null)
                {
                    foreach (var detectionRule in mobileApp.DetectionRules)
                    {
                        if (detectionRule.ODataType == "#microsoft.graph.win32LobAppRegistryDetection")
                        {
                            var win32LobAppRegistryDetection = (Win32LobAppRegistryDetection)detectionRule;
                            DetectionRulesModel detectionRulesModel = new DetectionRulesModel(
                                detectionRule.ODataType,
                                win32LobAppRegistryDetection.Check32BitOn64System,
                                win32LobAppRegistryDetection.KeyPath,
                                win32LobAppRegistryDetection.ValueName,
                                win32LobAppRegistryDetection.DetectionType?.ToString(),
                                win32LobAppRegistryDetection.Operator?.ToString(),
                                win32LobAppRegistryDetection.DetectionValue
                            );
    
                            detectionRulesModels.Add(detectionRulesModel);
                        }
                    }
                }
    
                graphResponseModelList.Add(new GraphResponseModel(assignmentIds, detectionRulesModels, createdOn));
            }
    
            return graphResponseModelList;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
    
    • In the above we directly accessing mobileApp.Assignments and mobileApp.DetectionRules and correctly populating the DetectionRulesModel list and assignmentIds list within the loop.

    • Then after adding the populated model to the graphResponseModelList list outside of the loop.

    This below represents when the MobileApp was created.

    {
        "assignmentIds": ["assignment1", "assignment2"],
        "detectionRules": {
            "OdataType": "#microsoft.graph.win32LobAppRegistryDetection",
            "Check32BitOn64System": true,
            "KeyPath": "HKEY_LOCAL_MACHINE\\Software\\MyApp",
            "ValueName": "Version",
            "DetectionType": "RegistryValueExists",
            "Operator": "Equals",
            "DetectionValue": "1.0"
        },
        "createdOn": "2024-05-10T15:30:00Z"
    }
    

    Reference: