# Connect to Microsoft Graph with necessary scopes
Connect-MgGraph -Scopes "Application.ReadWrite.All", "Directory.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All" -ErrorAction Stop
# Get Tenant ID
$tenantId = (Get-MgOrganization).Id
Write-Host "Tenant ID: $tenantId"
# Find and delete all existing CloudAppUsageExporter apps
$appName = "CloudAppUsageExporter"
$existingApps = Get-MgApplication -Filter "DisplayName eq '$appName'" -ErrorAction Stop
if ($existingApps) {
Write-Host "Found $($existingApps.Count) app(s) named '$appName'. Deleting them..."
foreach ($app in $existingApps) {
try {
Remove-MgApplication -ApplicationId $app.Id -ErrorAction Stop
Write-Host "Deleted app with ID: $($app.AppId)"
} catch {
Write-Warning "Failed to delete app with ID: $($app.AppId). Error: $_"
}
}
Start-Sleep -Seconds 5 # Wait for deletion to propagate
} else {
Write-Host "No existing apps named '$appName' found."
}
# Create a new Azure AD App Registration
$app = New-MgApplication -DisplayName $appName -SignInAudience "AzureADMyOrg" -ErrorAction Stop
$clientId = $app.AppId
Write-Host "Created new app with Client ID: $clientId"
# Define Microsoft Graph API permission: CloudApp-Discovery.Read.All (Application Permission)
$graphServicePrincipal = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'" -ErrorAction Stop # Microsoft Graph App ID
$permission = $graphServicePrincipal.AppRoles | Where-Object { $_.Value -eq "CloudApp-Discovery.Read.All" }
if ($permission) {
# Structure RequiredResourceAccess
$requiredResourceAccess = @(
@{
ResourceAppId = $graphServicePrincipal.AppId
ResourceAccess = @(
@{
Id = $permission.Id
Type = "Role"
}
)
}
)
Update-MgApplication -ApplicationId $app.Id -RequiredResourceAccess $requiredResourceAccess -ErrorAction Stop
Write-Host "Added CloudApp-Discovery.Read.All permission to the app."
} else {
Write-Error "Could not find CloudApp-Discovery.Read.All permission."
Disconnect-MgGraph
exit
}
# Create a Service Principal for the app
$sp = Get-MgServicePrincipal -Filter "AppId eq '$clientId'" -ErrorAction SilentlyContinue
if (-not $sp) {
$sp = New-MgServicePrincipal -AppId $clientId -ErrorAction Stop
Start-Sleep -Seconds 10 # Wait for propagation
Write-Host "Created new service principal for app."
}
$servicePrincipalId = $sp.Id
# Grant admin consent for the permission
try {
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipalId `
-PrincipalId $servicePrincipalId `
-ResourceId $graphServicePrincipal.Id `
-AppRoleId $permission.Id `
-ErrorAction Stop
Write-Host "Admin consent granted for the permission."
} catch {
Write-Warning "Failed to grant admin consent programmatically: $_"
Write-Host "Please grant consent manually in the Azure Portal after running this script."
}
# Create a client secret
$secret = Add-MgApplicationPassword -ApplicationId $app.Id -PasswordCredential @{ DisplayName = "CloudAppUsageSecret"; EndDateTime = (Get-Date).AddYears(1) } -ErrorAction Stop
$clientSecret = $secret.SecretText
Write-Host "Client Secret: $clientSecret"
# Output the values for your records
Write-Host "Save these values:"
Write-Host "Tenant ID: $tenantId"
Write-Host "Client ID: $clientId"
Write-Host "Client Secret: $clientSecret"
# Disconnect from Microsoft Graph
Disconnect-MgGraph