-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathGrant-SubscriptionCreatorRole.ps1
More file actions
149 lines (117 loc) · 9.78 KB
/
Grant-SubscriptionCreatorRole.ps1
File metadata and controls
149 lines (117 loc) · 9.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
function Grant-SubscriptionCreatorRole {
<#
.SYNOPSIS
Assigns the 'SubscriptionCreator' role to a specified service principal to allow it to create subscriptions in the specified billing account.
.DESCRIPTION
Assigns the 'SubscriptionCreator' role to a specified service principal to allow it to create subscriptions in the specified billing account.
.EXAMPLE
# Grant the 'SubscriptionCreator' role on the specified Enterprise Agreement billing account - using the 'billingAccountID' and 'enrollmentAccountID' parameters
Grant-SubscriptionCreatorRole -servicePrincipalObjectId "bd42568a-7dd8-489b-bbbb-cb96cfe10fb5" -billingAccountID "1234567" -enrollmentAccountID "987654"
# Grant the 'SubscriptionCreator' role on the specified Enterprise Agreement billing account - using the 'billingResourceID' parameter
Grant-SubscriptionCreatorRole -servicePrincipalObjectId "bd42568a-7dd8-489b-bbbb-cb96cfe10fb5" -billingResourceID "/providers/Microsoft.Billing/billingAccounts/1234567/enrollmentAccounts/987654"
# Grant the 'SubscriptionCreator' role on the specified Microsoft Customer Agreement billing account - using the 'billingAccountID', 'billingProfileID', and 'invoiceSectionID' parameters
Grant-SubscriptionCreatorRole -servicePrincipalObjectId "bd42568a-7dd8-489b-bbbb-cb96cfe10fb5" -billingAccountID "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx" -billingProfileID "AW4F-xxxx-xxx-xxx" -invoiceSectionID "SH3V-xxxx-xxx-xxx"
# Grant the 'SubscriptionCreator' role on the specified Microsoft Customer Agreement billing account - using the 'billingResourceID' parameter
Grant-SubscriptionCreatorRole -servicePrincipalObjectId "bd42568a-7dd8-489b-bbbb-cb96cfe10fb5" -billingResourceID "/providers/Microsoft.Billing/billingAccounts/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx/billingProfiles/AW4F-xxxx-xxx-xxx/invoiceSections/SH3V-xxxx-xxx-xxx"
#>
[CmdletBinding(DefaultParameterSetName = "Default")]
param (
[Parameter(ParameterSetName = "Default", Mandatory = $true, Position = 1, HelpMessage = "(Required) Provide a Service Principal Object ID to grant the 'SubscriptionCreator' role to on the specified billing account. This can be an app registration or a managed identity. Example: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.")]
[string]
$servicePrincipalObjectId,
[Parameter(ParameterSetName = "Default", Mandatory = $false, Position = 2, HelpMessage = "(Optional) If using an Enterprise Agreement or Microsoft Customer Agreement, provide the billing account ID that the service principal will be granted the 'SubscriptionCreator' role upon. Examples: '1234567' or 'aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx'.")]
[string]
$billingAccountID = "",
[Parameter(ParameterSetName = "Default", Mandatory = $false, Position = 3, HelpMessage = "(Optional) If using an Enterprise Agreement, provide the enrollment account ID that the service principal will be granted the 'SubscriptionCreator' role upon. Example: '987654'.")]
[string]
$enrollmentAccountID = "",
[Parameter(ParameterSetName = "Default", Mandatory = $false, Position = 4, HelpMessage = "(Optional) If using a Microsoft Customer Agreement, provide the billing profile ID that the service principal will be granted the 'SubscriptionCreator' role upon. Example: 'AW4F-xxxx-xxx-xxx'.")]
[string]
$billingProfileID = "",
[Parameter(ParameterSetName = "Default", Mandatory = $false, Position = 5, HelpMessage = "(Optional) If using a Microsoft Customer Agreement, provide the invoice section ID that the service principal will be granted the 'SubscriptionCreator' role upon. Example: 'SH3V-xxxx-xxx-xxx'.")]
[string]
$invoiceSectionID = "",
[Parameter(ParameterSetName = "Advanced", Mandatory = $false, Position = 6, HelpMessage = "(Optional) Provide the resource ID for the billing account that the service will be granted the 'SubscriptionCreator' role upon. This differs based on the type of agreement you have. Examples: '/providers/Microsoft.Billing/billingAccounts/1234567/enrollmentAccounts/987654' or '/providers/Microsoft.Billing/billingAccounts/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx/billingProfiles/AW4F-xxxx-xxx-xxx/invoiceSections/SH3V-xxxx-xxx-xxx'.")]
[string]
$billingResourceID = "",
[Parameter(ParameterSetName = "Default", Mandatory = $false, Position = 7, HelpMessage = "(Optional) Provide a the Azure management API url prefix. Default: 'https://management.azure.com'.")]
[string]
$managementApiPrefix = "https://management.azure.com"
)
# Checks
Write-Host "Checking inputs..." -ForegroundColor Cyan
Write-Host ""
if($null -eq $servicePrincipalObjectId -or $servicePrincipalObjectId -eq "") {
$errorMessage = "The 'Service Principal Object ID' parameter is required. Please provide a valid value and try again."
Write-Error $errorMessage
throw $errorMessage
}
$enterpriseAgreementResourceIDFormat = "/providers/Microsoft.Billing/billingAccounts/$billingAccountID/enrollmentAccounts/$enrollmentAccountID"
$microsoftCustomerAgreementResourceIDFormat = "/providers/Microsoft.Billing/billingAccounts/$billingAccountID/billingProfiles/$billingProfileID/invoiceSections/$invoiceSectionID"
if($null -ne $billingAccountID -and $billingAccountID -ne "" -and $null -ne $billingResourceID -and $billingResourceID -ne "" -and $null -ne $invoiceSectionID -and $invoiceSectionID -ne "") {
$billingResourceID = $microsoftCustomerAgreementResourceIDFormat
Write-Host "Microsoft Customer Agreement (MCA) parameters provided..."
}
if($null -ne $billingAccountID -and $billingAccountID -ne "" -and $null -ne $enrollmentAccountID -and $enrollmentAccountID -ne "") {
$billingResourceID = $enterpriseAgreementResourceIDFormat
Write-Host "Enterpruse Agreement (EA) parameters provided..."
}
if($null -ne $billingResourceID -and $billingResourceID -ne "") {
Write-Host "Billing Resource ID or required parameters provided..." -ForegroundColor Green
} else {
$errorMessage = "No Billing Resource ID or required parameters provided."
Write-Error $errorMessage
throw $errorMessage
}
Write-Host "Checking the specified billing account resource ID '$($billingResourceID)' exists..." -ForegroundColor Yellow
# Check $billingResourceID is valid and exists
$getbillingResourceID = $(az rest --method GET --url "$managementApiPrefix$($billingResourceID)?api-version=2024-04-01") | ConvertFrom-Json
if ($null -eq $getbillingResourceID) {
$errorMessage = "The specified billing account resource ID '$($billingResourceID)' does not exist or you do not have access to it. Please check the value and try again. Also ensure you are logged in as the Account Owner for the specified billing account."
Write-Error $errorMessage
throw $errorMessage
} else {
Write-Host "The specified billing account ID '$($billingResourceID)' exists. Continuing..." -ForegroundColor Green
Write-Host ""
}
# Check $existingSpnMiObjectId is valid and exists
Write-Host "Checking the specified service principal 'Object ID' '$($servicePrincipalObjectId)' exists..." -ForegroundColor Yellow
$getexistingSpnMiObjectId = $(az ad sp show --id $servicePrincipalObjectId) | ConvertFrom-Json
if ($null -eq $getexistingSpnMiObjectId) {
$errorMessage = "The specified service principal 'Object ID' '$($existingSpnMiObjectId)' does not exist. Please check the value and try again."
Write-Error $errorMessage
throw $errorMessage
} else {
$finalSpnMiObjectId = $getexistingSpnMiObjectId.id
$finalSpnMiDisplayName = $getexistingSpnMiObjectId.displayName
$finalSpnMiType = $getexistingSpnMiObjectId.servicePrincipalType
Write-Host "The specified service principal 'Object ID' '$($servicePrincipalObjectId)' exists with a Display Name of: '$finalSpnMiDisplayName' with a Type of: '$finalSpnMiType'. Continuing..." -ForegroundColor Green
Write-Host ""
}
# Grant service principal access to the specified EA billing account
$subscriptionCreatorRoleId = "a0bcee42-bf30-4d1b-926a-48d21664ef71"
Write-Host "Pre-reqs passed and complete..." -ForegroundColor Cyan
Write-Host "Granting the 'SubscriptionCreator' role (ID: '$subscriptionCreatorRoleId') on the Billing Account ID of: '$($billingResourceID)' to the AAD Object ID of: '$($finalSpnMiObjectId)' which has the Display Name of: '$($finalSpnMiDisplayName)'..." -ForegroundColor Yellow
# Get the current AAD Tenant ID
$tenantId = $(az account show --query tenantId -o tsv)
# Create GUID for role assignment name
$roleAssignmentName = New-Guid
$roleAssignmentHashTable = [ordered]@{
"properties" = @{
"principalId" = "$finalSpnMiObjectId"
"roleDefinitionId" = "$billingResourceID/billingRoleDefinitions/$subscriptionCreatorRoleId"
"principalTenantId" = $tenantId
}
}
$roleAssignmentPayloadJson = $roleAssignmentHashTable | ConvertTo-Json -Depth 100
$grantRbac = $(az rest --method PUT --url "$managementApiPrefix$($billingResourceID)/billingRoleAssignments/$($roleAssignmentName)?api-version=2024-04-01" --body "$roleAssignmentPayloadJson") | ConvertFrom-Json
if ($null -eq $grantRbac) {
$errorMessage = "The 'SubscriptionCreator' role could not be granted to the service principal. Please check the error message above and try again."
Write-Error $errorMessage
throw $errorMessage
} else {
Write-Host "The 'SubscriptionCreator' role has been granted to the service principal." -ForegroundColor Green
Write-Host ""
}
return
}