Introduction
We want to have a system user that is able to provision subscriptions as part of our vending machine. There's currently no user interface to do this, only some preview APIs from 2019.
The code
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]
$IdentityId,
[Parameter(Mandatory)]
[string]
[ValidateSet('SubscriptionCreator', 'DepartmentReader', 'EA purchaser', 'EnrollmentReader')]
$BillingRole
)
function Get-AzureBillingAccounts {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
$Headers
)
$data = (Invoke-RestMethod -Method Get -Uri "https://management.azure.com/providers/Microsoft.Billing/billingAccounts?api-version=2019-10-01-preview" -Headers $Headers).value |
Select-Object Name, @{'N' = 'accountStatus'; 'E' = { $_.properties.accountStatus } },
@{'N' = 'agreementType'; 'E' = { $_.properties.agreementType } },
@{'N' = 'displayName'; 'E' = { $_.properties.displayName } }, Id
Write-Output $data
}
function Get-AzureEnrollmentAccounts {
[CmdletBinding()]
param (
[Parameter()] [string] $BillingAccountName,
[Parameter(Mandatory)] $Headers
)
$data = (Invoke-RestMethod -Method Get -Uri "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$BillingAccountName/enrollmentAccounts?api-version=2019-10-01-preview" -Headers $Headers).value |
Select-Object Name, @{'N' = 'AccountName'; 'E' = { $_.properties.accountName } },
@{'N' = 'DisplayName'; 'E' = { $_.properties.displayName } },
@{'N' = 'Status'; 'E' = { $_.properties.status } }
Write-Output $data
}
function New-AzureBillingRoleAssignment {
[CmdletBinding()]
param (
[Parameter(Mandatory)] $Headers,
[Parameter(Mandatory)] [ValidateSet('SubscriptionCreator', 'DepartmentReader', 'EA purchaser', 'EnrollmentReader')] [string] $BillingRole,
[Parameter(Mandatory)] [string] $IdentityId,
[Parameter(Mandatory)] [string] $BillingAccountName,
[Parameter(Mandatory)] [string] $EnrollmentAccountName,
[Parameter(Mandatory)] [string] $TenantId
)
begin {
$BillingRoles = @{
'SubscriptionCreator' = 'a0bcee42-bf30-4d1b-926a-48d21664ef71'
'DepartmentReader' = 'db609904-a47f-4794-9be8-9bd86fbffd8a'
'EA purchaser' = 'da6647fb-7651-49ee-be91-c43c4877f0c4'
'EnrollmentReader' = '24f8edb6-1668-4659-b5e2-40bb5f3a7d7e'
}
$BillingRoleId = $BillingRoles[$BillingRole]
}
process {
$UniqueRoleAssignmentId = (New-guid).Guid
$RoleAssignmentUrl = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$BillingAccountName/enrollmentAccounts/$EnrollmentAccountName/billingRoleAssignments/$UniqueRoleAssignmentId`?api-version=2019-10-01-preview"
$Body = @{
"properties" = @{
"principalId" = "$IdentityId"
"principalTenantId" = "$TenantId"
"roleDefinitionId" = "/providers/Microsoft.Billing/billingAccounts/$BillingAccountName/enrollmentAccounts/$EnrollmentAccountName/billingRoleDefinitions/$BillingRoleId"
}
} | ConvertTo-Json -depth 100
try {
Invoke-RestMethod -Method Put -Uri $RoleAssignmentUrl -Headers $Headers -Body $Body
Write-verbose "Successfully created the role assignment." -Verbose
}
catch { throw }
}
}
# Use Az PowerShell Module token
$token = $(Get-AzAccessToken).Token
$headers = @{'Authorization' = "Bearer $Token"; 'Content-Type' = 'application/json' }
$TenantId = (get-azcontext).tenant.id
# Interactive selection
$BillingAccount = Get-AzureBillingAccounts -Headers $headers | Out-GridView -PassThru
$EnrollmentAccount = Get-AzureEnrollmentAccounts -BillingAccountName $BillingAccount.Name -Headers $headers | Out-GridView -PassThru
$Params = @{
'Headers' = $headers
'BillingRole' = $BillingRole
'IdentityId' = $IdentityId
'BillingAccountName' = $BillingAccount.Name
'EnrollmentAccountName' = $EnrollmentAccount.Name
'TenantId' = $TenantId
}
New-AzureBillingRoleAssignment @Params