Share via


A Mobility szolgáltatás automatikus frissítése az Azure-ból Azure-ba replikációban

Az Azure Site Recovery havi kiadási ütemezéssel oldja meg a problémákat, fejleszti a meglévő funkciókat, vagy újakat ad hozzá. Ahhoz, hogy naprakész maradjon a szolgáltatással, minden hónapban meg kell terveznie a javítás üzembe helyezését. Az egyes frissítésekhez kapcsolódó többletterhelés elkerülése érdekében engedélyezheti a Site Recovery számára az összetevők frissítéseinek kezelését.

Ahogy az Azure-ról Az Azure-ba irányuló vészhelyreállítási architektúra is említi, a Mobility szolgáltatás minden olyan Azure-beli virtuális gépen (virtuális gépen) telepítve van, amelyek replikációja engedélyezve van az Egyik Azure-régióból a másikba. Automatikus frissítések használatakor minden új kiadás frissíti a Mobility szolgáltatás bővítményt.

Megjegyzés:

We recommend that you use the Azure Az PowerShell module to interact with Azure. See Install Azure PowerShell to get started. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.

Az automatikus frissítések működése

Amikor a Site Recoveryt használja a frissítések kezelésére, az üzembe helyez egy globális runbookot (amelyet az Azure-szolgáltatások használnak) egy automation-fiókon keresztül, amely a tárolóval azonos előfizetésben jön létre. Minden tároló egy automation-fiókot használ. A tárolóban lévő összes virtuális gép esetében a runbook ellenőrzi az aktív automatikus frissítéseket. Ha elérhető a Mobility szolgáltatás bővítmény újabb verziója, a frissítés telepítve lesz.

Az alapértelmezett runbook-ütemezés naponta 12:00-kor történik a replikált virtuális gép földrajzi helyének időzónájában. A runbook ütemezését az automation-fiókon keresztül is módosíthatja.

Megjegyzés:

A 35. kumulatív frissítéstől kezdve választhat egy meglévő automation-fiókot a frissítésekhez. A 35. kumulatív frissítés előtt a Site Recovery alapértelmezés szerint létrehozta az automation-fiókot. Ezt a beállítást csak akkor választhatja ki, ha engedélyezi a virtuális gépek replikációjának engedélyezését. Nem érhető el olyan virtuális gépekhez, amelyeken már engedélyezve van a replikáció. A kiválasztott beállítás az ugyanabban a tárolóban védett összes Azure-beli virtuális gépre vonatkozik.

Az automatikus frissítések bekapcsolása nem igényli az Azure-beli virtuális gépek újraindítását, és nem befolyásolja a folyamatos replikációt.

A feladatok számlázása az automation-fiókban az egy hónapban használt feladat futásidejű perceinek számán alapul. A feladat végrehajtása naponta néhány másodpercig körülbelül egy percig tart, és ingyenes egységként van lefedve. Alapértelmezés szerint az 500 perc ingyenes egységként jelenik meg egy automation-fiókhoz, ahogyan az az alábbi táblázatban is látható:

Ingyenes egységek (havonta) Ár
Feladat futásideje 500 perc ₹0,14/perc

Automatikus frissítések engedélyezése

A Site Recovery többféleképpen kezelheti a bővítményfrissítéseket:

Kezelés az engedélyezési replikációs lépés részeként

Ha engedélyezi a virtuális gépek replikációjának engedélyezését a virtuálisgép-nézetből vagy a helyreállítási tárból kiindulva, engedélyezheti a Site Recovery számára a Site Recovery bővítmény frissítéseinek kezelését vagy manuálisan történő kezelését.

Extension settings

A bővítményfrissítési beállítások váltása a tárolón belül

  1. A Recovery Services-tárolóból lépjen a Site Recovery-infrastruktúra kezelése>elemre.

  2. Az Azure-beli virtuális gépek>bővítményfrissítése Gépház> Allow Site Recovery kezeléséhez válassza a Be lehetőséget.

    A bővítmény manuális kezeléséhez válassza a Ki elemet.

    Fontos

    Amikor a Site Recovery kezelésének engedélyezése lehetőséget választja, a beállítás a tárolóban lévő összes virtuális gépre lesz alkalmazva.

  3. Válassza a Mentés parancsot.

Extension update settings

Megjegyzés:

Bármelyik lehetőség értesíti a frissítések kezeléséhez használt automation-fiókról. Ha először használja ezt a funkciót egy tárolóban, alapértelmezés szerint létrejön egy új automation-fiók. Másik lehetőségként testre szabhatja a beállítást, és kiválaszthat egy meglévő automatizálási fiókot. A definiálást követően az ugyanabban a tárolóban történő replikáció engedélyezéséhez szükséges összes további művelet ezt a kiválasztott automation-fiókot fogja használni. A legördülő menü jelenleg csak azokat az automatizálási fiókokat listázja, amelyek ugyanabban az erőforráscsoportban találhatók, mint a tároló.

Egyéni automation-fiók esetén használja a következő szkriptet:

Fontos

Futtassa a következő szkriptet egy automation-fiók kontextusában. Ez a szkript a rendszer által hozzárendelt felügyelt identitásokat használja hitelesítési típusként.

param(
    [Parameter(Mandatory=$true)]
    [String] $VaultResourceId,
    [Parameter(Mandatory=$true)]
    [ValidateSet("Enabled",'Disabled')]
    [Alias("Enabled or Disabled")]
    [String] $AutoUpdateAction,
    [Parameter(Mandatory=$false)]
    [String] $AutomationAccountArmId
)
$SiteRecoveryRunbookName = "Modify-AutoUpdateForVaultForPatner"
$TaskId = [guid]::NewGuid().ToString()
$SubscriptionId = "00000000-0000-0000-0000-000000000000"
$AsrApiVersion = "2021-12-01"
$ArmEndPoint = "https://management.azure.com"
$AadAuthority = "https://login.windows.net/"
$AadAudience = "https://management.core.windows.net/"
$AzureEnvironment = "AzureCloud"
$Timeout = "160"
$AuthenticationType = "SystemAssignedIdentity"
function Throw-TerminatingErrorMessage
{
        Param
    (
        [Parameter(Mandatory=$true)]
        [String]
        $Message
        )
    throw ("Message: {0}, TaskId: {1}.") -f $Message, $TaskId
}
function Write-Tracing
{
        Param
    (
        [Parameter(Mandatory=$true)]
        [ValidateSet("Informational", "Warning", "ErrorLevel", "Succeeded", IgnoreCase = $true)]
                [String]
        $Level,
        [Parameter(Mandatory=$true)]
        [String]
        $Message,
            [Switch]
        $DisplayMessageToUser
        )
    Write-Output $Message
}
function Write-InformationTracing
{
        Param
    (
        [Parameter(Mandatory=$true)]
        [String]
        $Message
        )
    Write-Tracing -Message $Message -Level Informational -DisplayMessageToUser
}
function ValidateInput()
{
    try
    {
        if(!$VaultResourceId.StartsWith("/subscriptions", [System.StringComparison]::OrdinalIgnoreCase))
        {
            $ErrorMessage = "The vault resource id should start with /subscriptions."
            throw $ErrorMessage
        }
        $Tokens = $VaultResourceId.SubString(1).Split("/")
        if(!($Tokens.Count % 2 -eq 0))
        {
            $ErrorMessage = ("Odd Number of tokens: {0}." -f $Tokens.Count)
            throw $ErrorMessage
        }
        if(!($Tokens.Count/2 -eq 4))
        {
            $ErrorMessage = ("Invalid number of resource in vault ARM id expected:4, actual:{0}." -f ($Tokens.Count/2))
            throw $ErrorMessage
        }
        if($AutoUpdateAction -ieq "Enabled" -and [string]::IsNullOrEmpty($AutomationAccountArmId))
        {
            $ErrorMessage = ("The automation account ARM id should not be null or empty when AutoUpdateAction is enabled.")
            throw $ErrorMessage
        }
    }
    catch
    {
        $ErrorMessage = ("ValidateInput failed with [Exception: {0}]." -f $_.Exception)
        Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
        Throw-TerminatingErrorMessage -Message $ErrorMessage
    }
}
function Initialize-SubscriptionId()
{
    try
    {
        $Tokens = $VaultResourceId.SubString(1).Split("/")
        $Count = 0
                $ArmResources = @{}
        while($Count -lt $Tokens.Count)
        {
            $ArmResources[$Tokens[$Count]] = $Tokens[$Count+1]
            $Count = $Count + 2
        }
                return $ArmResources["subscriptions"]
    }
    catch
    {
        Write-Tracing -Level ErrorLevel -Message ("Initialize-SubscriptionId: failed with [Exception: {0}]." -f $_.Exception) -DisplayMessageToUser
        throw
    }
}
function Invoke-InternalRestMethod($Uri, $Headers, [ref]$Result)
{
    $RetryCount = 0
    $MaxRetry = 3
    do
    {
        try
        {
            $ResultObject = Invoke-RestMethod -Uri $Uri -Headers $Headers
            ($Result.Value) += ($ResultObject)
            break
        }
        catch
        {
            Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception)
            $RetryCount++
            if(!($RetryCount -le $MaxRetry))
            {
                throw
            }
            Start-Sleep -Milliseconds 2000
        }
    }while($true)
}
function Invoke-InternalWebRequest($Uri, $Headers, $Method, $Body, $ContentType, [ref]$Result)
{
    $RetryCount = 0
    $MaxRetry = 3
    do
    {
        try
        {
            $ResultObject = Invoke-WebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' `
                -Body $InputJson  -ContentType "application/json" -UseBasicParsing
            ($Result.Value) += ($ResultObject)
            break
        }
        catch
        {
            Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception)
            $RetryCount++
            if(!($RetryCount -le $MaxRetry))
            {
                throw
            }
            Start-Sleep -Milliseconds 2000
        }
    }while($true)
}
function Get-Header([ref]$Header, $AadAudience){
    try
    {
        $Header.Value['Content-Type'] = 'application\json'
        Write-InformationTracing ("The Authentication Type is system Assigned Identity based.")
        $endpoint = $env:IDENTITY_ENDPOINT
        $endpoint  
        $Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" 
        $Headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER) 
        $Headers.Add("Metadata", "True")   
        $authenticationResult = Invoke-RestMethod -Method Get -Headers $Headers -Uri ($endpoint +'?resource=' +$AadAudience)
        $accessToken = $authenticationResult.access_token
        $Header.Value['Authorization'] = "Bearer " + $accessToken
        $Header.Value["x-ms-client-request-id"] = $TaskId + "/" + (New-Guid).ToString() + "-" + (Get-Date).ToString("u")
    }
    catch
    {
        $ErrorMessage = ("Get-BearerToken: failed with [Exception: {0}]." -f $_.Exception)
        Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
        Throw-TerminatingErrorMessage -Message $ErrorMessage
    }
}
function Get-ProtectionContainerToBeModified([ref] $ContainerMappingList)
{
    try
    {
        Write-InformationTracing ("Get protection container mappings : {0}." -f $VaultResourceId)
        $ContainerMappingListUrl = $ArmEndPoint + $VaultResourceId + "/replicationProtectionContainerMappings" + "?api-version=" + $AsrApiVersion
        Write-InformationTracing ("Getting the bearer token and the header.")
        Get-Header ([ref]$Header) $AadAudience
        $Result = @()
        Invoke-InternalRestMethod -Uri $ContainerMappingListUrl -Headers $header -Result ([ref]$Result)
        $ContainerMappings = $Result[0]
        Write-InformationTracing ("Total retrieved container mappings: {0}." -f $ContainerMappings.Value.Count)
        foreach($Mapping in $ContainerMappings.Value)
        {
            if(($Mapping.properties.providerSpecificDetails -eq $null) -or ($Mapping.properties.providerSpecificDetails.instanceType -ine "A2A"))
            {
                Write-InformationTracing ("Mapping properties: {0}." -f ($Mapping.properties))
                Write-InformationTracing ("Ignoring container mapping: {0} as the provider does not match." -f ($Mapping.Id))
                continue;
            }
            if($Mapping.Properties.State -ine "Paired")
            {
                Write-InformationTracing ("Ignoring container mapping: {0} as the state is not paired." -f ($Mapping.Id))
                continue;
            }
            Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties.providerSpecificDetails))
            $MappingAutoUpdateStatus = $Mapping.properties.providerSpecificDetails.agentAutoUpdateStatus
            $MappingAutomationAccountArmId = $Mapping.properties.providerSpecificDetails.automationAccountArmId
            $MappingHealthErrorCount = $Mapping.properties.HealthErrorDetails.Count
            if($AutoUpdateAction -ieq "Enabled" -and
                ($MappingAutoUpdateStatus -ieq "Enabled") -and
                ($MappingAutomationAccountArmId -ieq $AutomationAccountArmId) -and
                ($MappingHealthErrorCount -eq 0))
            {
                Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties))
                Write-InformationTracing ("Ignoring container mapping: {0} as the auto update is already enabled and is healthy." -f ($Mapping.Id))
                continue;
            }
            ($ContainerMappingList.Value).Add($Mapping.id)
        }
    }
    catch
    {
        $ErrorMessage = ("Get-ProtectionContainerToBeModified: failed with [Exception: {0}]." -f $_.Exception)
        Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
        Throw-TerminatingErrorMessage -Message $ErrorMessage
    }
}
$OperationStartTime = Get-Date
$ContainerMappingList = New-Object System.Collections.Generic.List[System.String]
$JobsInProgressList = @()
$JobsCompletedSuccessList = @()
$JobsCompletedFailedList = @()
$JobsFailedToStart = 0
$JobsTimedOut = 0
$Header = @{}
$AzureRMProfile = Get-Module -ListAvailable -Name AzureRM.Profile | Select Name, Version, Path
$AzureRmProfileModulePath = Split-Path -Parent $AzureRMProfile.Path
Add-Type -Path (Join-Path $AzureRmProfileModulePath "Microsoft.IdentityModel.Clients.ActiveDirectory.dll")
$Inputs = ("Tracing inputs VaultResourceId: {0}, Timeout: {1}, AutoUpdateAction: {2}, AutomationAccountArmId: {3}." -f $VaultResourceId, $Timeout, $AutoUpdateAction, $AutomationAccountArmId)
Write-Tracing -Message $Inputs -Level Informational -DisplayMessageToUser
$CloudConfig = ("Tracing cloud configuration ArmEndPoint: {0}, AadAuthority: {1}, AadAudience: {2}." -f $ArmEndPoint, $AadAuthority, $AadAudience)
Write-Tracing -Message $CloudConfig -Level Informational -DisplayMessageToUser
ValidateInput
$SubscriptionId = Initialize-SubscriptionId
Get-ProtectionContainerToBeModified ([ref]$ContainerMappingList)
$Input = @{
  "properties"= @{
    "providerSpecificInput"= @{
        "instanceType" = "A2A"
        "agentAutoUpdateStatus" = $AutoUpdateAction
        "automationAccountArmId" = $AutomationAccountArmId
        "automationAccountAuthenticationType" = $AuthenticationType
    }
  }
}
$InputJson = $Input |  ConvertTo-Json
if ($ContainerMappingList.Count -eq 0)
{
    Write-Tracing -Level Succeeded -Message ("Exiting as there are no container mappings to be modified.") -DisplayMessageToUser
    exit
}
Write-InformationTracing ("Container mappings to be updated has been retrieved with count: {0}." -f $ContainerMappingList.Count)
try
{
    Write-InformationTracing ("Start the modify container mapping jobs.")
    ForEach($Mapping in $ContainerMappingList)
    {
    try {
            $UpdateUrl = $ArmEndPoint + $Mapping + "?api-version=" + $AsrApiVersion
            Get-Header ([ref]$Header) $AadAudience
            $Result = @()
            Invoke-InternalWebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' `
                -Body $InputJson  -ContentType "application/json" -Result ([ref]$Result)
            $Result = $Result[0]
            $JobAsyncUrl = $Result.Headers['Azure-AsyncOperation']
            Write-InformationTracing ("The modify container mapping job invoked with async url: {0}." -f $JobAsyncUrl)
            $JobsInProgressList += $JobAsyncUrl;
            # Rate controlling the set calls to maximum 60 calls per minute.
            # ASR throttling for set calls is 200 in 1 minute.
            Start-Sleep -Milliseconds 1000
        }
        catch{
            Write-InformationTracing ("The modify container mappings job creation failed for: {0}." -f $Ru)
            Write-InformationTracing $_
            $JobsFailedToStart++
        }
    }
    Write-InformationTracing ("Total modify container mappings has been initiated: {0}." -f $JobsInProgressList.Count)
}
catch
{
    $ErrorMessage = ("Modify container mapping jobs failed with [Exception: {0}]." -f $_.Exception)
    Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
    Throw-TerminatingErrorMessage -Message $ErrorMessage
}
try
{
    while($JobsInProgressList.Count -ne 0)
    {
        Sleep -Seconds 30
        $JobsInProgressListInternal = @()
        ForEach($JobAsyncUrl in $JobsInProgressList)
        {
            try
            {
                Get-Header ([ref]$Header) $AadAudience
                $Result = Invoke-RestMethod -Uri $JobAsyncUrl -Headers $header
                $JobState = $Result.Status
                if($JobState -ieq "InProgress")
                {
                    $JobsInProgressListInternal += $JobAsyncUrl
                }
                elseif($JobState -ieq "Succeeded" -or `
                    $JobState -ieq "PartiallySucceeded" -or `
                    $JobState -ieq "CompletedWithInformation")
                {
                    Write-InformationTracing ("Jobs succeeded with state: {0}." -f $JobState)
                    $JobsCompletedSuccessList += $JobAsyncUrl
                }
                else
                {
                    Write-InformationTracing ("Jobs failed with state: {0}." -f $JobState)
                    $JobsCompletedFailedList += $JobAsyncUrl
                }
            }
            catch
            {
                Write-InformationTracing ("The get job failed with: {0}. Ignoring the exception and retrying the next job." -f $_.Exception)
                # The job on which the tracking failed, will be considered in progress and tried again later.
                $JobsInProgressListInternal += $JobAsyncUrl
            }
            # Rate controlling the get calls to maximum 120 calls each minute.
            # ASR throttling for get calls is 10000 in 60 minutes.
            Start-Sleep -Milliseconds 500
        }
        Write-InformationTracing ("Jobs remaining {0}." -f $JobsInProgressListInternal.Count)
        $CurrentTime = Get-Date
        if($CurrentTime -gt $OperationStartTime.AddMinutes($Timeout))
        {
            Write-InformationTracing ("Tracing modify cloud pairing jobs has timed out.")
            $JobsTimedOut = $JobsInProgressListInternal.Count
            $JobsInProgressListInternal = @()
        }
        $JobsInProgressList = $JobsInProgressListInternal
    }
}
catch
{
    $ErrorMessage = ("Tracking modify cloud pairing jobs failed with [Exception: {0}]." -f $_.Exception)
    Write-Tracing -Level ErrorLevel -Message $ErrorMessage  -DisplayMessageToUser
    Throw-TerminatingErrorMessage -Message $ErrorMessage
}
Write-InformationTracing ("Tracking modify cloud pairing jobs completed.")
Write-InformationTracing ("Modify cloud pairing jobs success: {0}." -f $JobsCompletedSuccessList.Count)
Write-InformationTracing ("Modify cloud pairing jobs failed: {0}." -f $JobsCompletedFailedList.Count)
Write-InformationTracing ("Modify cloud pairing jobs failed to start: {0}." -f $JobsFailedToStart)
Write-InformationTracing ("Modify cloud pairing jobs timedout: {0}." -f $JobsTimedOut)
if($JobsTimedOut -gt  0)
{
    $ErrorMessage = "One or more modify cloud pairing jobs has timedout."
    Write-Tracing -Level ErrorLevel -Message ($ErrorMessage)
    Throw-TerminatingErrorMessage -Message $ErrorMessage
}
elseif($JobsCompletedSuccessList.Count -ne $ContainerMappingList.Count)
{
    $ErrorMessage = "One or more modify cloud pairing jobs failed."
    Write-Tracing -Level ErrorLevel -Message ($ErrorMessage)
    Throw-TerminatingErrorMessage -Message $ErrorMessage
}
Write-Tracing -Level Succeeded -Message ("Modify cloud pairing completed.") -DisplayMessageToUser

Frissítések manuális kezelése

  1. Ha a virtuális gépekre telepített Mobility szolgáltatás új frissítéseket talál, a következő értesítés jelenik meg: Új Site Recovery replikációs ügynök frissítése érhető el. Kattintson ide a telepítéshez.

    Replicated items window

  2. Válassza ki az értesítést a virtuális gép kijelölési oldalának megnyitásához.

  3. Válassza ki a frissíteni kívánt virtuális gépeket, majd kattintson az OK gombra. A frissítési Mobility szolgáltatás minden kijelölt virtuális gépnél elindul.

    Replicated items VM list

Gyakori problémák és hibaelhárítás

Ha az automatikus frissítésekkel kapcsolatos probléma merül fel, hibaüzenet jelenik meg a tároló irányítópultjának konfigurációs problémái között.

Ha nem tudja engedélyezni az automatikus frissítéseket, tekintse meg az alábbi gyakori hibákat és az ajánlott műveleteket:

  • Hiba: Nincs engedélye azure-beli futtató fiók (szolgáltatásnév) létrehozására és a közreműködői szerepkör szolgáltatásnévnek való megadására.

    Javasolt művelet: Győződjön meg arról, hogy a bejelentkezett fiók közreműködőként van hozzárendelve, majd próbálkozzon újra. Az engedélyek hozzárendelésével kapcsolatos további információkért tekintse meg a How to: Use the portal to create a Microsoft Entra application and service principal to access resources (Útmutató: A portál használata az erőforrásokhoz hozzáférő Microsoft Entra-alkalmazás és szolgáltatásnév létrehozásához) című szakaszt.

    Az automatikus frissítések engedélyezése után felmerülő legtöbb probléma megoldásához válassza a Javítás lehetőséget. Ha a javítási gomb nem érhető el, tekintse meg a bővítményfrissítés beállításai panelen megjelenő hibaüzenetet.

    Site Recovery service repair button in extension update settings

  • Hiba: A futtató fiók nem rendelkezik engedéllyel a helyreállítási szolgáltatások erőforrásának eléréséhez.

    Javasolt művelet: Törölje, majd hozza létre újra a futtató fiókot. Vagy győződjön meg arról, hogy az Automation futtató fiók Microsoft Entra-alkalmazása hozzáfér a helyreállítási szolgáltatások erőforrásához.

  • Hiba: A futtató fiók nem található. Ezek egyikét törölték vagy nem hozták létre – Microsoft Entra-alkalmazás, szolgáltatásnév, szerepkör, Automation-tanúsítványobjektum, Automation Csatlakozás ion-objektum -, vagy az ujjlenyomat nem azonos a tanúsítvány és a Csatlakozás ion között.

    Javasolt művelet: Törölje, majd hozza létre újra a futtató fiókot.

  • Hiba: Az automation-fiók által használt Azure Run as Certificate hamarosan lejár.

    A futtató fiókhoz létrehozott önaláírt tanúsítvány a létrehozástól számított egy évig érvényes. A tanúsítványt bármikor meg lehet újítani a lejárata előtt. Ha feliratkozott az e-mail-értesítésekre, e-maileket is kap, ha az Ön részéről műveletre van szükség. Ez a hiba a lejárati dátum előtt két hónappal jelenik meg, és kritikus hibára változik, ha a tanúsítvány lejárt. A tanúsítvány lejártát követően az automatikus frissítés csak akkor lesz működőképes, ha ugyanazt megújítja.

    Javasolt művelet: A probléma megoldásához válassza a Javítás , majd a Tanúsítvány megújítása lehetőséget.

    renew-cert

    Megjegyzés:

    A tanúsítvány megújítása után frissítse a lapot az aktuális állapot megjelenítéséhez.

További lépések

További információ az Automation-fiókok hitelesítési típusának felügyelt identitásokba való migrálásáról.