$cert = New-SelfSignedCertificate -Subject "CN=Automation" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec KeyExchange -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 $base64Cert = [System.Convert]::ToBase64String($cert.RawData)
POST /$batch
After creation, you need to create a service principal for that app to appear in "Enterprise applications": https- graph.microsoft.com v1.0 applications
| Limit | Value | |-------|-------| | Requests per 10 seconds per app | 2,000 | | Requests per 10 seconds per tenant | 5,000 | | Max $top | 999 |
Query for apps with unused delegated permissions: Instead, fetch apps first (no expand), then batch
But that’s not the same as a ( /servicePrincipals ), which is the instance of that app in a specific tenant.
"appId": "<the appId from above>"
But $expand on passwordCredentials or keyCredentials is . Avoid it unless necessary. Instead, fetch apps first (no expand), then batch request credentials:
| Feature | /v1.0 | /beta | |---------|---------|---------| | Federated identity credentials (workload identity federation) | ❌ | ✅ | | App role assignment conditions | ❌ | ✅ | | serviceManagementReference | ❌ | ✅ | | uniqueName (human-readable app identifier) | ❌ | ✅ | fetch apps first (no expand)
$body = @ displayName = "CI/CD Automation App" signInAudience = "AzureADMyOrg" keyCredentials = @( @ type = "AsymmetricX509Cert" usage = "Verify" key = $base64Cert startDateTime = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ") endDateTime = (Get-Date).AddYears(1).ToString("yyyy-MM-ddTHH:mm:ssZ")