使用指令碼將計費角色從某個 MCA 複製到跨租用戶的另一個 MCA

Azure 入口網站會自動進行訂用帳戶移轉,但不會自動移轉角色。 本文中的資訊可幫助計費帳戶擁有者在合併 Microsoft 客戶協定 (MCA) 企業帳戶時自動分配角色。 您可以使用指令碼,將計費角色從某個 MCA 企業帳戶複製到跨租用戶的另一個 MCA 企業帳戶。 以下示例方案描述了整個過程。

Contoso Ltd 收購 Fabrikam, Inc.Contoso 和 Fabrikam 在各自的租用戶中都有一個 MCA。 Contoso 想要將 Fabrikam 訂用帳戶的計費管理帶入自己的 Contoso MCA 之下。 此外,Contoso 也想為 Fabrikam 訂用帳戶產生個別發票,並讓 Fabrikam 租用戶中的使用者指派為計費角色。

Contoso MCA 計費帳戶擁有者會使用下列流程:

  1. 建立 Fabrikam 租用戶與 Contoso MCA 計費帳戶的關聯。
  2. 為 Fabrikam 訂用帳戶建立新的帳單設定檔。
  3. 將帳單設定檔擁有者角色指派給 Fabrikam 租用戶中的使用者。

請記住,來源 Fabrikam MCA 的計費帳戶、帳單設定檔和數個發票區段層級中,有許多具有計費角色的其他使用者。

在來源 MCA 的 Fabrikam「計費帳戶擁有者」角色獲得 Contoso (目標) MCA 的「計費帳戶擁有者」角色之後,他們會使用下列各節,將計費角色從來源 MCA 自動移轉至目標 MCA。

使用下列資訊,將計費角色從來源 (Fabrikam) MCA 自動移轉至目標 (Contoso) MCA。 指令碼適用於帳單設定檔範圍。

先決條件

  • 您必須在目標 MCA 上具有 Billing account owner 角色,並在源 MCA 上具有 Billing account owner 或 billing account contributor 角色。
  • 為指令碼準備的儲存體帳戶。 如需詳細資訊,請參閱開始使用 AzCopy

準備目標環境

  1. 登入 Azure 入口網站,使用的帳戶必須擁有目標租用戶 MCA 計費帳戶的必要權限。
  2. 產生來源租用戶與目標 MCA 計費帳戶的關聯。 如需詳細資訊,請參閱新增相關聯的計費租用戶
  3. 從相關聯的租用戶中新增計費帳戶擁有者。 如需詳細資訊,請參閱指派角色給相關聯計費租用戶中的使用者
  4. 在目標租用戶中,視需要新增帳單設定檔和發票區段。

準備並執行指令碼

使用以下步驟準備並運行腳本。

  1. Role migration script example (角色遷移腳本示例) 部分中複製腳本範例。
  2. 貼上,然後在本機將檔案另存為 PS1 檔案。
  3. 使用來源到目標的映射更新文稿:
    • Tenant
    • Billing account
    • Billing profile
    • Invoice sections
  4. 登入 Azure 入口網站 (來源租用戶),然後開啟 Cloud Shell。 如果系統提示您選取 Bash 或 PowerShell,請選取 [PowerShell]
    顯示 Cloud Shell 符號的螢幕截圖。
  5. 如果您先前使用 Bash,請在 Cloud Shell 工具列中選取 [PowerShell]
    顯示 PowerShell 選擇的螢幕截圖。
  6. 將 PS1 檔案上傳至您的 Azure 儲存體帳戶。
  7. 執行 PS1 檔案。
  8. 向 Azure Cloud Shell 進行驗證。
  9. 在執行指令碼之後,確認角色位於目標 MCA 中。

角色遷移腳本示例

您可以使用以下示例文本自動遷移計費角色。 該角色將從源 MCA 計費配置檔複製到其他租戶中的目標 MCA 計費配置檔。

## Define source target mapping for
##	1. Tenant
##	2. Billing Account
##	3. Billing Profile
##	4. Invoice Sections
##(source) MCA-E details
$tenantId = "" 
$billingAccount=""
$billingProfile = ""
##(destination) MCA-E details
$targetBillingProfile = ""
$targetTenantId = ""
$targetbillingAccount=""
## Invoice section mapping in hash table
$hash = @{
"" = ""; #invoice section 1
"" = ""; #invoice section 2
}
## Connect to Azure account using device authentication using tenantId
Connect-AzAccount -UseDeviceAuthentication -TenantId $tenantId
Set-AzContext -TenantId $tenantId
## Acquire access token for the current user
$var = Get-AzAccessToken
$auth = 'Bearer ' + $var.Token
#### Get Billing Account Role Assignments from source MCA-E
#define parameters for REST API call
$params = @{
    Uri         = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+ $billingAccount +"/billingRoleAssignments?api-version=2019-10-01-preview"
    Headers     = @{ 'Authorization' = $auth }
    Method      = 'GET'
    ContentType = 'application/json'
}
#### Call API with parameters defined above
$ret = Invoke-RestMethod @params 
####Initialize array lists 
$ArrayListBARoles = [System.Collections.Generic.List[string]]::new();
$ArrayListBPRoles = [System.Collections.Generic.List[string]]::new();
$ArrayListISRoles = [System.Collections.Generic.List[string]]::new();
#### Add each billing account role and principal id to array list 
#### Push down the billing account role assignments to billing profile role assignments (replacing 5 series with 4 series)
foreach($j in $ret.value){                                                     
	$BANameArrayArray= $j.name -replace "500000", "500000" #-split '_'                                           
	foreach($i in $BANameArrayArray){
	 $ArrayListBARoles.Add($i)
	 }
 }
#### Get Billing Role assignments for billing profile
$paramsBPRoleAssignments = @{
	Uri         = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+$billingAccount +"/billingProfiles/" +$billingProfile +"/billingRoleAssignments?api-version=2019-10-01-preview"
    Headers     = @{ 'Authorization' = $auth }
    Method      = 'GET'
    ContentType = 'application/json'
		}
$retBPRoles = Invoke-RestMethod @paramsBPRoleAssignments 
####add each role to arraylist
foreach($k in $retBPRoles.value){                                                     
	$BPNameArrayArray= $k.name #-split '_'                                           
	foreach($l in $BPNameArrayArray){
	$ArrayListBPRoles.Add($l)
	}
}
#### Get Invoice sections for billing profile
$invoiceSections = Get-AzInvoiceSection -BillingAccountName $billingAccount -BillingProfile $billingProfile
for ($ii=0; $ii -lt $ArrayListBARoles.count;  $ii=$ii+1){ 
	$paramsBARoleCreation = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+$targetbillingAccount+"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'POST'
		ContentType = 'application/json'
		}
	$BodyBARoleCreation = @{
		principalTenantId = $tenantId
		roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/" +($ArrayListBARoles[$ii] -SPLIT '_')[0]
		principalId=($ArrayListBARoles[$ii] -SPLIT '_')[1]
		}
	$retBARoles = Invoke-RestMethod @paramsBARoleCreation -body @($BodyBARoleCreation | ConvertTo-Json)
}
#BILLING PROFILE	
for ($ii=0; $ii -lt $ArrayListBPRoles.count;  $ii=$ii+1){
	$paramsBPRoleCreation = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'POST'
		ContentType = 'application/json'
	}
	$BodyBPRoleCreation = @{
		principalTenantId = $tenantId
		roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/" +($ArrayListBPRoles[$ii] -SPLIT '_')[0]
		principalId=($ArrayListBPRoles[$ii] -SPLIT '_')[1]
    }
	$retBPRoles = Invoke-RestMethod @paramsBPRoleCreation -body @($BodyBPRoleCreation | ConvertTo-Json)
}
#INVOICE SECTIONS
$targetinvoiceSection=""
#Get Roles for each invoice section
foreach ($m in $invoiceSections){
	if ($hash.ContainsKey($m.Name)){
		$targetinvoiceSection=$hash[$m.Name]
		'targetinvoiceSection'
		$targetinvoiceSection
		
	$paramsISRoleAssignments = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$billingAccount +"/billingProfiles/" + $billingProfile +"/invoiceSections/" +$m.Name+ "/billingRoleAssignments?api-version=2019-10-01-preview"			
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'GET'
		ContentType = 'application/json'
	}
	$retISRoles = Invoke-RestMethod @paramsISRoleAssignments 
	$ISNameArrayArray=$null
	$ArrayListISRoles = [System.Collections.Generic.List[string]]::new();
	foreach($n in $retISRoles.value){  
		$ISNameArrayArray= $n.name #-split '_'                                           
			foreach($o in $ISNameArrayArray){
				$ArrayListISRoles.Add($o)
			}
	}
		for ($ii=0; $ii -lt $ArrayListISRoles.count;  $ii=$ii+1){
			$paramsISRoleCreation = @{
				Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount+ "/billingProfiles/"+ $targetBillingProfile +"/invoiceSections/"+ $targetinvoiceSection +"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
				Headers     = @{ 'Authorization' = $auth }
				Method      = 'POST'
				ContentType = 'application/json'
			}
			$BodyISRoleCreation = @{
				principalTenantId = $tenantId
				roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/invoiceSections/"+ $targetinvoiceSection+ "/" +($ArrayListISRoles[$ii] -SPLIT '_')[0]
				#userEmailAddress = ($graph.UserPrincipalName -Replace '_', '@' -split '#EXT#@' )[0]
				principalId=($ArrayListISRoles[$ii] -SPLIT '_')[1]
			}
			$resISRolesCreation= Invoke-RestMethod @paramsISRoleCreation -body @($BodyISRoleCreation | ConvertTo-Json)
		}
		}
}

後續步驟