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.
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: