chore: updated for ACSC hardening
This commit is contained in:
356
NewAppReg.ps1
356
NewAppReg.ps1
@ -1,178 +1,178 @@
|
||||
# Ensure Microsoft.Graph module is installed
|
||||
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
|
||||
Write-Host "Installing Microsoft.Graph module..."
|
||||
Install-Module -Name Microsoft.Graph -Force -AllowClobber
|
||||
}
|
||||
|
||||
# Ensure ExchangeOnlineManagement module is installed
|
||||
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
|
||||
Write-Host "Installing ExchangeOnlineManagement Module..."
|
||||
Install-Module -Name ExchangeOnlineManagement -Force -AllowClobber
|
||||
}
|
||||
|
||||
|
||||
# Import necessary modules
|
||||
Import-Module Microsoft.Graph.Authentication
|
||||
Import-Module Microsoft.Graph.Applications
|
||||
Import-Module ExchangeOnlineManagement
|
||||
|
||||
# Connect to Microsoft Graph with required permissions
|
||||
Connect-MgGraph -Scopes "Application.ReadWrite.All", "Directory.ReadWrite.All", "AppRoleAssignment.ReadWrite.All" -NoWelcome
|
||||
|
||||
# Application details
|
||||
$Name = "GraphAPI"
|
||||
$Scope = "Application.ReadWrite.All", "DeviceManagementApps.ReadWrite.All", "DeviceManagementConfiguration.ReadWrite.All", "DeviceManagementServiceConfig.ReadWrite.All", "Group.ReadWrite.All", "Policy.ReadWrite.ApplicationConfiguration", "User.ReadWrite.All"
|
||||
|
||||
# Fetch Microsoft Graph Service Principal
|
||||
$graphSp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
|
||||
$graphRoles = $graphSp.AppRoles
|
||||
|
||||
# Debugging: Confirm AppRoles permissions
|
||||
# Write-Host "`n🔍 Retrieved AppRoles from Microsoft Graph:"
|
||||
# $graphRoles | Format-Table DisplayName, Id, Value -AutoSize
|
||||
|
||||
# Build required resource access list
|
||||
$resourceAccess = @()
|
||||
foreach ($perm in $Scope) {
|
||||
$permId = ($graphRoles | Where-Object { $_.Value -eq $perm }).Id
|
||||
if ($permId) {
|
||||
$resourceAccess += @{
|
||||
"id" = $permId
|
||||
"Type" = "Role" # Use "Scope" if using delegated permissions
|
||||
}
|
||||
} else {
|
||||
Write-Host "⚠️ Skipping $perm - Role ID not found in Microsoft Graph."
|
||||
}
|
||||
}
|
||||
|
||||
# Debugging: Confirm matched permissions
|
||||
# Write-Host "`n✅ Final Mapped Permissions:"
|
||||
# $resourceAccess | Format-Table -AutoSize
|
||||
|
||||
# Define app creation body
|
||||
$body = @{
|
||||
DisplayName = $Name
|
||||
SignInAudience = "AzureADMyOrg"
|
||||
RequiredResourceAccess = @(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
|
||||
ResourceAccess = $resourceAccess
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
# Convert body to JSON
|
||||
$payload = $body | ConvertTo-Json -Depth 4
|
||||
|
||||
# Create the application
|
||||
Write-Host "Creating Azure AD application..."
|
||||
$app = New-MgApplication -BodyParameter $payload
|
||||
|
||||
if (-not $app) {
|
||||
Write-Host "❌ Failed to create application. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Application Created: $($app.Id)"
|
||||
|
||||
# Wait for the application to propagate
|
||||
Start-Sleep -Seconds 10
|
||||
Write-Host "⏳ Waiting for application propagation..."
|
||||
|
||||
# Create Service Principal
|
||||
Write-Host "Creating Service Principal..."
|
||||
$servicePrincipal = New-MgServicePrincipal -AppId $app.AppId
|
||||
|
||||
if (-not $servicePrincipal) {
|
||||
Write-Host "❌ Failed to create Service Principal. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Service Principal created: $($servicePrincipal.Id)"
|
||||
|
||||
# Wait for service principal to propagate
|
||||
Start-Sleep -Seconds 10
|
||||
Write-Host "⏳ Waiting for application permissions to propagate..."
|
||||
|
||||
# Grant Admin Consent
|
||||
foreach ($access in $resourceAccess) {
|
||||
# Write-Host "`n🔹 About to grant admin consent for:"
|
||||
# Write-Host " ➜ AppRoleId: $($access.id)"
|
||||
# Write-Host " ➜ ServicePrincipalId: $($servicePrincipal.Id)"
|
||||
# Write-Host " ➜ PrincipalId: $($servicePrincipal.Id)"
|
||||
# Write-Host " ➜ ResourceId: $($graphSp.Id)"
|
||||
|
||||
try {
|
||||
$null = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipal.Id -PrincipalId $servicePrincipal.Id -ResourceId $graphSp.Id -AppRoleId $access.id
|
||||
|
||||
Write-Host "✅ Successfully granted admin consent for AppRoleId: $($access.id)"
|
||||
} catch {
|
||||
Write-Host "❌ Failed to grant admin consent for AppRoleId: $($access.id) - $_"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n🎉 Admin consent process completed!"
|
||||
|
||||
# -------------------------------
|
||||
# CREATE CLIENT SECRET
|
||||
# -------------------------------
|
||||
|
||||
Write-Host "`n🔐 Creating Client Secret..."
|
||||
$secretStartDate = Get-Date
|
||||
$secretEndDate = $secretStartDate.AddYears(1) # Secret valid for 1 year
|
||||
|
||||
$clientSecret = Add-MgApplicationPassword -ApplicationId $app.Id -PasswordCredential @{
|
||||
DisplayName = "GraphAPI-ClientSecret"
|
||||
StartDateTime = $secretStartDate
|
||||
EndDateTime = $secretEndDate
|
||||
}
|
||||
|
||||
if (-not $clientSecret) {
|
||||
Write-Host "❌ Failed to create client secret. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Client Secret Created!"
|
||||
|
||||
# -------------------------------
|
||||
# PRINT CREDENTIALS (STORE SECURELY!)
|
||||
# -------------------------------
|
||||
|
||||
$tenantId = (Get-MgOrganization).Id
|
||||
|
||||
Write-Host "`n🚀 **Application Credentials**"
|
||||
Write-Host "----------------------------------"
|
||||
Write-Host "🌐 Tenant ID: $tenantId"
|
||||
Write-Host "🔑 Client ID: $($app.AppId)"
|
||||
Write-Host "🕵️♂️ Client Secret: $($clientSecret.SecretText)"
|
||||
Write-Host "----------------------------------"
|
||||
|
||||
#Connect-ExchangeOnline -ShowBanner:$false
|
||||
|
||||
$scope = "https://graph.microsoft.com/.default"
|
||||
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
|
||||
|
||||
# Create the body for the token request
|
||||
$body = @{
|
||||
client_id = "$($app.AppId)"
|
||||
scope = $scope
|
||||
client_secret = "$($clientSecret.SecretText)"
|
||||
grant_type = "client_credentials"
|
||||
}
|
||||
|
||||
# Request the token
|
||||
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $body
|
||||
$accessToken = $tokenResponse.access_token
|
||||
|
||||
# Use the token in subsequent requests
|
||||
$headers = @{
|
||||
Authorization = "Bearer $accessToken"
|
||||
}
|
||||
$templates = Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/beta/deviceManagement/templates" -Headers $headers
|
||||
|
||||
# Output the templates
|
||||
$templates
|
||||
|
||||
$null = Disconnect-Graph -ErrorAction SilentlyContinue
|
||||
$null = Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
# Ensure Microsoft.Graph module is installed
|
||||
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
|
||||
Write-Host "Installing Microsoft.Graph module..."
|
||||
Install-Module -Name Microsoft.Graph -Force -AllowClobber
|
||||
}
|
||||
|
||||
# Ensure ExchangeOnlineManagement module is installed
|
||||
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
|
||||
Write-Host "Installing ExchangeOnlineManagement Module..."
|
||||
Install-Module -Name ExchangeOnlineManagement -Force -AllowClobber
|
||||
}
|
||||
|
||||
|
||||
# Import necessary modules
|
||||
Import-Module Microsoft.Graph.Authentication
|
||||
Import-Module Microsoft.Graph.Applications
|
||||
Import-Module ExchangeOnlineManagement
|
||||
|
||||
# Connect to Microsoft Graph with required permissions
|
||||
Connect-MgGraph -Scopes "Application.ReadWrite.All", "Directory.ReadWrite.All", "AppRoleAssignment.ReadWrite.All" -NoWelcome
|
||||
|
||||
# Application details
|
||||
$Name = "GraphAPI"
|
||||
$Scope = "Application.ReadWrite.All", "DeviceManagementApps.ReadWrite.All", "DeviceManagementConfiguration.ReadWrite.All", "DeviceManagementServiceConfig.ReadWrite.All", "Group.ReadWrite.All", "Policy.ReadWrite.ApplicationConfiguration", "User.ReadWrite.All"
|
||||
|
||||
# Fetch Microsoft Graph Service Principal
|
||||
$graphSp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
|
||||
$graphRoles = $graphSp.AppRoles
|
||||
|
||||
# Debugging: Confirm AppRoles permissions
|
||||
# Write-Host "`n🔍 Retrieved AppRoles from Microsoft Graph:"
|
||||
# $graphRoles | Format-Table DisplayName, Id, Value -AutoSize
|
||||
|
||||
# Build required resource access list
|
||||
$resourceAccess = @()
|
||||
foreach ($perm in $Scope) {
|
||||
$permId = ($graphRoles | Where-Object { $_.Value -eq $perm }).Id
|
||||
if ($permId) {
|
||||
$resourceAccess += @{
|
||||
"id" = $permId
|
||||
"Type" = "Role" # Use "Scope" if using delegated permissions
|
||||
}
|
||||
} else {
|
||||
Write-Host "⚠️ Skipping $perm - Role ID not found in Microsoft Graph."
|
||||
}
|
||||
}
|
||||
|
||||
# Debugging: Confirm matched permissions
|
||||
# Write-Host "`n✅ Final Mapped Permissions:"
|
||||
# $resourceAccess | Format-Table -AutoSize
|
||||
|
||||
# Define app creation body
|
||||
$body = @{
|
||||
DisplayName = $Name
|
||||
SignInAudience = "AzureADMyOrg"
|
||||
RequiredResourceAccess = @(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
|
||||
ResourceAccess = $resourceAccess
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
# Convert body to JSON
|
||||
$payload = $body | ConvertTo-Json -Depth 4
|
||||
|
||||
# Create the application
|
||||
Write-Host "Creating Azure AD application..."
|
||||
$app = New-MgApplication -BodyParameter $payload
|
||||
|
||||
if (-not $app) {
|
||||
Write-Host "❌ Failed to create application. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Application Created: $($app.Id)"
|
||||
|
||||
# Wait for the application to propagate
|
||||
Start-Sleep -Seconds 10
|
||||
Write-Host "⏳ Waiting for application propagation..."
|
||||
|
||||
# Create Service Principal
|
||||
Write-Host "Creating Service Principal..."
|
||||
$servicePrincipal = New-MgServicePrincipal -AppId $app.AppId
|
||||
|
||||
if (-not $servicePrincipal) {
|
||||
Write-Host "❌ Failed to create Service Principal. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Service Principal created: $($servicePrincipal.Id)"
|
||||
|
||||
# Wait for service principal to propagate
|
||||
Start-Sleep -Seconds 10
|
||||
Write-Host "⏳ Waiting for application permissions to propagate..."
|
||||
|
||||
# Grant Admin Consent
|
||||
foreach ($access in $resourceAccess) {
|
||||
# Write-Host "`n🔹 About to grant admin consent for:"
|
||||
# Write-Host " ➜ AppRoleId: $($access.id)"
|
||||
# Write-Host " ➜ ServicePrincipalId: $($servicePrincipal.Id)"
|
||||
# Write-Host " ➜ PrincipalId: $($servicePrincipal.Id)"
|
||||
# Write-Host " ➜ ResourceId: $($graphSp.Id)"
|
||||
|
||||
try {
|
||||
$null = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipal.Id -PrincipalId $servicePrincipal.Id -ResourceId $graphSp.Id -AppRoleId $access.id
|
||||
|
||||
Write-Host "✅ Successfully granted admin consent for AppRoleId: $($access.id)"
|
||||
} catch {
|
||||
Write-Host "❌ Failed to grant admin consent for AppRoleId: $($access.id) - $_"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n🎉 Admin consent process completed!"
|
||||
|
||||
# -------------------------------
|
||||
# CREATE CLIENT SECRET
|
||||
# -------------------------------
|
||||
|
||||
Write-Host "`n🔐 Creating Client Secret..."
|
||||
$secretStartDate = Get-Date
|
||||
$secretEndDate = $secretStartDate.AddYears(1) # Secret valid for 1 year
|
||||
|
||||
$clientSecret = Add-MgApplicationPassword -ApplicationId $app.Id -PasswordCredential @{
|
||||
DisplayName = "GraphAPI-ClientSecret"
|
||||
StartDateTime = $secretStartDate
|
||||
EndDateTime = $secretEndDate
|
||||
}
|
||||
|
||||
if (-not $clientSecret) {
|
||||
Write-Host "❌ Failed to create client secret. Exiting."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "✅ Client Secret Created!"
|
||||
|
||||
# -------------------------------
|
||||
# PRINT CREDENTIALS (STORE SECURELY!)
|
||||
# -------------------------------
|
||||
|
||||
$tenantId = (Get-MgOrganization).Id
|
||||
|
||||
Write-Host "`n🚀 **Application Credentials**"
|
||||
Write-Host "----------------------------------"
|
||||
Write-Host "🌐 Tenant ID: $tenantId"
|
||||
Write-Host "🔑 Client ID: $($app.AppId)"
|
||||
Write-Host "🕵️♂️ Client Secret: $($clientSecret.SecretText)"
|
||||
Write-Host "----------------------------------"
|
||||
|
||||
#Connect-ExchangeOnline -ShowBanner:$false
|
||||
|
||||
$scope = "https://graph.microsoft.com/.default"
|
||||
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
|
||||
|
||||
# Create the body for the token request
|
||||
$body = @{
|
||||
client_id = "$($app.AppId)"
|
||||
scope = $scope
|
||||
client_secret = "$($clientSecret.SecretText)"
|
||||
grant_type = "client_credentials"
|
||||
}
|
||||
|
||||
# Request the token
|
||||
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $body
|
||||
$accessToken = $tokenResponse.access_token
|
||||
|
||||
# Use the token in subsequent requests
|
||||
$headers = @{
|
||||
Authorization = "Bearer $accessToken"
|
||||
}
|
||||
$templates = Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/beta/deviceManagement/templates" -Headers $headers
|
||||
|
||||
# Output the templates
|
||||
$templates
|
||||
|
||||
$null = Disconnect-Graph -ErrorAction SilentlyContinue
|
||||
$null = Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
|
Reference in New Issue
Block a user