We're currently in the process of transitioning to client certificate authentication for our application and got this working code from previous ask on retrieving the deleted application objects from Microsoft Graph Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The specified network password is not correct.'
using Azure.Identity;
using Microsoft.Graph;
using System.Security.Cryptography.X509Certificates;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "appID";
var tenantId = "tenantId";
var certificatePath = "C:/MYPATH";
var certificatePassword = "xxxxxxxx";
var clientCertificate = new X509Certificate2(certificatePath, certificatePassword);
var options = new ClientCertificateCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientCertCredential = new ClientCertificateCredential(
tenantId, clientId, clientCertificate, options);
var graphClient = new GraphServiceClient(clientCertCredential, scopes);
var apps= await graphClient.Directory.DeletedItems.GraphApplication.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Count = true;
requestConfiguration.QueryParameters.Orderby = new string[] { "deletedDateTime asc" };
requestConfiguration.QueryParameters.Select = new string[] { "appId", "DisplayName", "deletedDateTime" };
requestConfiguration.Headers.Add("Consistencylevel", "Eventual");
});
Console.WriteLine($"Total deleted apps: {apps.OdataCount}\n");
foreach (var app in apps.Value)
{
Console.WriteLine($"App ID: {app.AppId}");
Console.WriteLine($"Application Name: {app.DisplayName}");
Console.WriteLine($"Deleted Date and Time: {app.DeletedDateTime}");
Console.WriteLine();
}
While the code effectively retrieves deleted application objects, we now have a specific requirement to restore only those deleted applications whose names begin with "dev" We've attempted to modify the code to achieve this by including a filter condition, but encountered difficulties in implementation.
Could you please provide guidance on how to integrate a filter condition to selectively restore deleted applications based on their names starting with "dev"? Any assistance or insights would be greatly appreciated.
To restore the deleted application, you need to grant Application.ReadWrite.All permission of Application type:
I have 3 deleted applications that starts with 'dev' in my tenant like this:
Now, you can make use of below modified code to restore these deleted applications by filtering them starting with 'dev' :
using Azure.Identity;
using Microsoft.Graph;
using System.Security.Cryptography.X509Certificates;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "appID";
var tenantId = "tenantId";
// Load certificate from file
var certificatePath = "C:/demo/graphcert20.pfx";
var certificatePassword = "password"; // Provide the password here
var clientCertificate = new X509Certificate2(certificatePath, certificatePassword);
// using Azure.Identity;
var options = new ClientCertificateCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientCertCredential = new ClientCertificateCredential(
tenantId, clientId, clientCertificate, options);
var graphClient = new GraphServiceClient(clientCertCredential, scopes);
var deletedApps = await graphClient.Directory.DeletedItems.GraphApplication.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Count = true;
requestConfiguration.QueryParameters.Filter = "startsWith(displayName, 'dev')";
requestConfiguration.QueryParameters.Select = new string[] { "displayName", "Id", "deletedDateTime" };
requestConfiguration.Headers.Add("Consistencylevel", "Eventual");
});
Console.WriteLine($"Total deleted apps starting with 'dev': {deletedApps.OdataCount}\n");
foreach (var deletedApp in deletedApps.Value)
{
var appId = deletedApp.Id;
Console.WriteLine($"Restoring app with ID: {appId}");
var restoreResponse = await graphClient.Directory.DeletedItems[appId].Restore.PostAsync();
if (restoreResponse != null)
{
Console.WriteLine($"App with display name '{deletedApp.DisplayName}' restored successfully.\n");
}
else
{
Console.WriteLine($"Failed to restore app with ID {appId}.");
}
}
Response:
To confirm that, I checked the same in Portal where deleted applications starting with 'dev' restored successfully like this: