In a dynamic enterprise environment, organizations often need to restructure their Azure resources for better cost allocation, governance, or compliance. For IT teams managing multiple SQL Server instances enabled by Azure Arc, a reorganization may require moving some instances to a different resource group or subscription.
Moving Azure Arc-enabled SQL Server instances is generally straightforward, similar to relocating other Azure resources. However, it becomes more complex when dependent features like Best Practice Assessment (BPA) are enabled.
Understanding the Migration Scenarios
- Instances without BPA enabled: These can be moved seamlessly using the Azure portal by following the official Microsoft documentation: Move resources to a new resource group or subscription – SQL Server enabled by Azure Arc | Microsoft Learn.
- Instances with BPA enabled: Since BPA settings do not persist automatically after migration, additional steps are required to ensure continuity.
Migration Approach
To ensure a smooth transition while preserving BPA configurations and updating Log Analytics Workspace (LAW) settings, the process involves:
- Identifying servers where the BPA feature is enabled.
- Disabling BPA before moving the resource.
- Migrating the SQL Server instance to the new resource group or subscription.
- Re-enabling BPA for the affected servers.
- Updating the Log Analytics Workspace configuration to align with the target subscription’s LAW.
Automating the Process
This blog provides a step-by-step PowerShell script to automate these tasks for at-scale migrations, minimizing manual effort and ensuring a seamless transition.
Alternative Approach: If automation isn't required, you can also use Azure Policy to enable or disable BPA and move Arc resources through the Azure portal.
By leveraging either automation or Azure-native tools, organizations can efficiently manage Azure Arc-enabled SQL Server migrations while maintaining their configurations.
Steps to Migrate SQL Server Enabled by Azure Arc to a New Resource Group or Subscription
Step 1: Open PowerShell as Administrator
- Click on Start, search for PowerShell ISE or PowerShell.
- Right-click and select Run as Administrator to ensure the necessary permissions.
Step 2: Provide Input Parameters
- Define the source and destination subscription IDs, resource group names, and Log Analytics Workspace details.
- Double-check that all values are correctly set before executing the script – “MoveArcResourcesAcrossSubscriptionOrRG.ps1”.
Step 3: Connect to Azure and Set Subscription Context
- Log in to your Azure account when prompted to authenticate the device or application.
- The script will set the context to access and manage the SQL Server instances based on the input parameters provided.
Step 4: Validate the Migration
- Once the script execution is complete, validate the output to confirm that the resource move was successful.
- Check the Azure Portal to ensure that the SQL Server instances have been moved to the new resource group or subscription.
Note:
|
By following these structured steps, organizations can efficiently migrate SQL Server enabled by Azure Arc while maintaining BPA configurations and updating necessary settings to ensure a seamless transition.
MoveArcResourcesAcrossSubscriptionOrRG.ps1
<#
Name: MoveArcResourcesAcrossSubscriptionOrRG.ps1
Purpose: This script manages the prerequisites for disabling the BPA on each Arc server resource before initiating a resource move.
After the resource is successfully relocated to the new resource group (RG), the script then re-enables the BPA settings to their original state.
Warranty: This script is provided on as "AS IS" basis and there are no warranties, express or implied, including, but not limited to implied warranties of merchantability or fitness for a particular purpose. USE AT YOUR OWN RISK.
#>
#____________________________________________
# Input parameters
#____________________________________________
$SourceSubscriptionId='2xxxxxxxx-a798-4265-ab7d-d9xxxxx377' # Set the source subscription ID
$DestinationSubscriptionId ='0xxxxxxxa-399c-4564-9f74-ffxxxxxx46' # Set the Destination subscription ID.
$SourceRgName='arcsqlprod_rg' # Set the Source resource group name
$TargetRgName='arcsqldev_rg' # Set the Destination resource group name
$logAnalyticsWorkspaceName = 'devloganalyticsworkspace' # Set the Log Analytics Workspace in the destination subscription.
#__________________
#local Variables
#__________________
$global:ExcludedServerlist = @();$arcServers = @() ;$allResources = @();$global:ArcEnabledServerlist = @();
cls
#_________________________________________________
# Check if the Az module is installed & Imported
#_________________________________________________
Function LoadRequiredModules {
if (-not (Get-Module -Name Az) -and -not (Get-Module -ListAvailable -Name Az) -and -not (Get-Module -ListAvailable -Name Az.Accounts)) {
# Install the Az module if not already installed
Write-Host "[$(Get-Date)]: Installing the required Az module, please wait."
Install-Module -Name Az -AllowClobber -Force -Scope CurrentUser -WarningAction SilentlyContinue
}
# Import the Az module
Write-Host "[$(Get-Date)]: Importing the required Az module, please wait."
Import-Module Az.Accounts
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
Connect-AzAccount -Subscription $SourceSubscriptionId -WarningAction SilentlyContinue | Out-Null
}
#____________________________________________________________________
# Module to verify the existence of the destination resource group
#____________________________________________________________________
function CheckDestinationResourceGroup {
Set-AzContext -SubscriptionId $DestinationSubscriptionId -WarningAction SilentlyContinue| Out-Null
$destinationRG = Get-AzResourceGroup -Name $TargetRgName -ErrorAction SilentlyContinue
if (-not $destinationRG) {
Write-Host "[$(Get-Date)]: The destination resource group [$TargetRgName] does not exist." -BackgroundColor Yellow -ForegroundColor Red
return
}
else { Write-Host "[$(Get-Date)]: The destination resource group [$TargetRgName] exists."
}
}
#____________________________________________________________________
# Module to verify the existence of Log Analytics Workspace name.
#____________________________________________________________________
function CheckLogAnalyticsWorkspace {
Set-AzContext -subscriptionId $DestinationSubscriptionId -WarningAction SilentlyContinue | Out-Null *>$null
$LAW = Get-AzOperationalInsightsWorkspace | Where-Object { $_.Name -eq $logAnalyticsWorkspaceName }
if (-not $LAW) {
Write-Host "[$(Get-Date)]: Log Analytics Workspace [$logAnalyticsWorkspaceName] does not exist in [Subscription:$($DestinationSubscription.Name), ResourceGroup:$TargetRgName]." -BackgroundColor Yellow -ForegroundColor Black
$userInput = Read-Host "Would you like to create a new Log Analytics Workspace? Press any key to create and continue or [N or 0] to stop the execution"
if ($userInput -ieq 'N' -or $userInput -ieq 0) {
Write-Host "[$(Get-Date)]: Execution stopped." -ForegroundColor Red
EXIT;
} else {
Write-Host "[$(Get-Date)]: Proceeding to create a new Log Analytics Workspace. Please wait.."
try{
$NewLAW=New-AzOperationalInsightsWorkspace -ResourceGroupName $TargetRgName -Name $logAnalyticsWorkspaceName -Location (Get-AzResourceGroup -Name $TargetRgName).Location
if ($NewLAW) {
Write-Host "[$(Get-Date)]: Successfully created a new Log Analytics Workspace:`n"("_" * 160)
Write-Host " Resource ID: $($NewLAW.ResourceId)"
Write-Host " Location : $($NewLAW.Location)`n"("_" * 160)
}
}
catch{
Write-Host "[$(Get-Date)]: An error occurred while creating the Log Analytics Workspace." -ForegroundColor Red
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
}
}
} else {
Write-Host "[$(Get-Date)]: Log Analytics Workspace [$logAnalyticsWorkspaceName] found."
}
Set-AzContext -SubscriptionId $SourceSubscriptionId -WarningAction SilentlyContinue | Out-Null
}
#____________________________________________
# Function to check the status of BPA
#____________________________________________
function Get-BPAStatus {
param ( [string]$machineID,[string]$mode)
$subscriptionId = ($machineID -split '/')[2]
$resourceGroup = ($machineID -split '/')[4]
$machineName = ($machineID -split '/')[8]
$MachineState=(Get-AzConnectedMachine -ResourceGroupName $resourceGroup -Name $machineName).Status
if ($MachineState -eq 'Disconnected') {
Write-Host "[$(Get-Date)]: The Azure Arc machine [$($machineName)] is currently offline or disconnected, which will block the movement of resources or the enabling/disabling of features." -BackgroundColor Yellow -ForegroundColor Red
return 'DISCONNECTED';
}
else
{
$extn=$null;
$extn= Get-AzConnectedMachineExtension -ResourceGroupName $resourceGroup -MachineName $machineName | where Name -Like 'WindowsAgent.SqlServer' | select ProvisioningState
if ($extn -eq $null) {
Write-Host "[$(Get-Date)]: SQL Server Extension is not installed on the Machine : [$($machineName)]." -BackgroundColor Green -ForegroundColor black
return 'DISCONNECTED-MISSING-SQLExtention';
}
elseif (($extn.ProvisioningState -eq 'Succeeded') -or ($extn.ProvisioningState -eq 'Updating'))
{
$uri = "https://edge.management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$($machineName)/extensions/WindowsAgent.SqlServer`?api-version=2022-03-10"
try{
$token = (Get-AzAccessToken -ResourceUrl https://management.azure.com/ -AsSecureString -WarningAction SilentlyContinue).Token}
catch {
Write-Error "Failed to retrieve the Azure Access Token. Error: $_"
}
$headers = @{Authorization = "Bearer "+[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token))}
$retryCount = 0
while ($retryCount -lt 4)
{
try{
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers}
catch {
Write-Error "Error occurs during the REST API request. Error: $_"
}
$bpaconfig=$response.properties.settings.AssessmentSettings.Enable
if ( -not [string]::IsNullOrEmpty($response) -and -not [string]::IsNullOrEmpty($bpaconfig) ) {
break}
else{
if ($retryCount -eq 0){ Write-Host "[$(Get-Date)]: Waiting to get the BPA status after the recent update " -NoNewline } else {Write-Host "....reattempt in 15 seconds."}
Start-Sleep -Seconds 15
$retryCount++
}
}
$global:licenceType=$response.properties.settings.LicenseType
if ($mode -eq "Validate"){
return $bpaconfig}
if ( [string]::IsNullOrEmpty($global:licenceType) -or $LicenseType -eq "LicenseOnly") {
switch ($global:licenceType) {
$null { Write-Host "[$(Get-Date)]: License Type is NOT configured for machine [$($arcMachine.Name)]." }
"LicenseOnly" { Write-Host "[$(Get-Date)]: Best Practices Assessment is not supported on license type '$LicenseType' for machine [$($arcMachine.Name)]." }
default { Write-Host "[$(Get-Date)]: Unknown License Type for machine [$($arcMachine.Name)]." }
}
$global:skippedmachine += $arcMachine.Name}
switch ($bpaconfig) {
$false { Write-Host "[$(Get-Date)]: SQL Best Practice Assessment is [Disabled] on Machine: [$($machineName)]"}
$true { Write-Host "[$(Get-Date)]: SQL Best Practice Assessment is [Enabled] on Machine: [$($machineName)]" }
default{ Write-Host "[$(Get-Date)]: SQL Best Practice Assessment is [Not Configured] on Machine: [$($machineName)]" }
}
return $bpaconfig;
}
else
{
Write-Host "[$(Get-Date)]: SQL Server Extension is in [$($extn.ProvisioningState)] state on the Machine : [$($machineName)]. Cannot update the BPA configuration." -BackgroundColor Yellow -ForegroundColor black
return 'DISCONNECTED-Unknown-SQLExtention';
}
}
}
#__________________________________________________________
# Function to Enable/Disable BPA for each machine
#__________________________________________________________
function Set-BPAConfiguration {
param (
[string]$machineID,
[string]$valuetoset
)
$subscriptionId = ($machineID -split '/')[2]
$resourceGroup = ($machineID -split '/')[4]
$machineName = ($machineID -split '/')[8]
Write-Host "[$(Get-Date)]: $($(($valuetoset).Substring(0, $valuetoset.Length - 1)) + 'ing') BPA for machine [$($machineName)]...."
$setvalue = if ($valuetoset -eq "Enable") { $true } else { $false }
$uri = "https://edge.management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$($machineName)/extensions/WindowsAgent.SqlServer?api-version=2022-03-10"
$token = (Get-AzAccessToken -ResourceUrl https://management.azure.com/ -AsSecureString -WarningAction SilentlyContinue).Token
$headers = @{Authorization = "Bearer " + [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token))}
# Get the current response to inspect the existing values
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
if ($setvalue -eq $true){
if ([string]::IsNullOrEmpty($response.properties.settings.AssessmentSettings))
{
$response.properties.settings | Add-Member -MemberType NoteProperty -Name "AssessmentSettings" -Value @{}
}
$response.properties.settings.AssessmentSettings.Enable =$true
$response.properties.settings.AssessmentSettings.WorkspaceResourceId=$LAW.ResourceId
$response.properties.settings.AssessmentSettings.WorkspaceLocation=$LAW.Location
$response.properties.settings.AssessmentSettings.ResourceNamePrefix=$null
$response.properties.settings.AssessmentSettings.RunImmediately=$true
$response.properties.settings.AssessmentSettings.schedule = @{
dayOfWeek = "Sunday"
Enable = $true
monthlyOccurrence = $null
StartDate = $null
startTime = "00:00"
WeeklyInterval = 1
}
}
else
{
$response.properties.settings.AssessmentSettings.Enable =$false
$response.properties.settings.AssessmentSettings.WorkspaceResourceId=$null
$response.properties.settings.AssessmentSettings.WorkspaceLocation=$null
}
$jsonPayload = $response| ConvertTo-Json -Depth 10
#$jsonPayload #for debug
# Prepare the PATCH request headers
$headers = @{
Authorization = "Bearer " + [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token))
"Content-Type" = "application/json" # Specify content type as JSON
}
# Make the PATCH request
try {
$response = Invoke-RestMethod -Uri $uri -Method Patch -Headers $headers -Body $jsonPayload
Write-Host "[$(Get-Date)]: Successfully submitted the request to [$($valuetoset)] Best Practices Assessment for machine [$($machineName)]."
} catch {
# Handle the error
Write-Host "[$(Get-Date)]: An error occurred while $($BPAtargetstate +'ing') BPA for [$($arcMachine.Name)]: $_"
}
Start-Sleep -Seconds 10
#Valdate after the change
$CurrentState=Get-BPAStatus -machineID $machineID -mode "Validate"
switch ($CurrentState) {
$true { $state = "Enabled" }
$false { $state = "Disabled" }
default { $state = $CurrentState } # Default case
}
if ($setvalue -eq $CurrentState){
Write-Host "[$(Get-Date)]: Successfully [$state] Best Practices Assessment for machine [$($machineName)]."
return $setvalue
}
else
{
Write-Host "[$(Get-Date)]: Updating the BPA configuration for machine [$($machineName)] has failed. The CurrentState is [$CurrentState]" -BackgroundColor Yellow -ForegroundColor Red
return "Error-$CurrentState"}
}
#__________________________________________________________
# Module to make sure that BPA is disable for each machine
#__________________________________________________________
Function Ensure-BPA-IsDisabled {
$arcMachines = Get-AzResource -ResourceGroupName $SourceRgName -ResourceType "Microsoft.HybridCompute/machines"
Write-Host "[$(Get-Date)]: A total of $($arcMachines.Count) Azure Arc machine(s) found." -BackgroundColor Green -ForegroundColor Black
foreach ($arcMachine in $arcMachines) {
Write-Host "[$(Get-Date)]: Validating the configuration for Azure Arc machine :[$($arcMachine.Name)]"
$MachineState=(Get-AzConnectedMachine -ResourceGroupName $SourceRgName -Name $arcMachine.Name).Status
if ($MachineState -eq 'Disconnected') {
Write-Host "[$(Get-Date)]: The Azure Arc machine [$($arcMachine.Name)] is currently OFFLINE/DISCONNECTED, Cannot update the BPA configuration. This will also prevent the resource movement of this/child resource(s)." -BackgroundColor Yellow -ForegroundColor Red
}
else
{
$extn=$null;
$extn= Get-AzConnectedMachineExtension -ResourceGroupName $SourceRgName -MachineName $arcMachine.Name | where Name -Like 'WindowsAgent.SqlServer' | select ProvisioningState
if ($extn -eq $null) {
Write-Host "[$(Get-Date)]: SQL Server Extension is not installed on the Machine : [$($arcMachine.Name)]." -BackgroundColor Green -ForegroundColor black}
elseif ($extn.ProvisioningState -eq 'Succeeded')
{
$status = Get-BPAStatus -machineID $($arcMachine.ResourceId) -mode "Validate"
if ($status -eq $true) {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is set to : [$($status.ToString().ToUpper())] for Machine:[$($arcMachine.Name)]"
Write-Host "[$(Get-Date)]: Attempting to DISABLE SQL Best Practice AssessmentSettings for Machine:[$($arcMachine.Name)]" -BackgroundColor White -ForegroundColor Black
$status= Set-BPAConfiguration -machineID $($arcMachine.ResourceId) -valuetoset 'Disable'
#$status= Get-BPAStatus -machineID $($arcMachine.ResourceId) -mode "Validate"
if ($status -eq $false){
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is now set to : [$($status.ToString().ToUpper())] for Machine:[$(($($arcMachine.ResourceId) -split '/')[($($arcMachine.ResourceId) -split '/').IndexOf('machines') + 1])] and added to the re-enablement list."
$global:ArcEnabledServerlist =$global:ArcEnabledServerlist+$($arcMachine.ResourceId)
}
else{
Write-Host "[$(Get-Date)]: Failed to update SQL Best Practice AssessmentSetting for Machine:[$(($($arcMachine.ResourceId) -split '/')[($($arcMachine.ResourceId) -split '/').IndexOf('machines') + 1])] and added to the exclusion list."
$global:ExcludedServerlist+=$($arcMachine.Name)
}
}
else {
switch ($status) {
$null {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is NOT configured on Machine: [$($arcMachine.Name)]"
}
$False {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is already set to [$($status.ToString().ToUpper())] for Machine: [$($arcMachine.Name)]"
}
"Not-Configured" {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is [$($status.ToString().ToUpper())] for Machine: [$($arcMachine.Name)]"
}
default {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is [Unknown] for Machine: [$($arcMachine.Name)]"
$global:ExcludedServerlist+=$($arcMachine.Name)
}
}
}
}
else
{
Write-Host "[$(Get-Date)]: SQL Server Extension is in [$($extn.ProvisioningState)] state on the Machine : [$($arcMachine.Name)]. Cannot update the BPA configuration." -BackgroundColor Yellow -ForegroundColor Red
}
}
}
}
#____________________________________________________________________
# Start the move resource operation
#____________________________________________________________________
Function move-Arc-machines{
$arcServers= Get-AzResource -ResourceGroupName $SourceRgName -ResourceType "microsoft.hybridcompute/machines" | Where-Object { $_.Name -notin $global:ExcludedServerlist }
if ($arcServers.Count -gt 0)
{
Write-Host "[$(Get-Date)]: Starting the move of Arc server resources. This process may take some time, so please wait until it is completed."
if ($global:ExcludedServerlist) {
Write-Host "[$(Get-Date)]: List of servers which are skipped for move due to failure in disabling BPA feature:" -ForegroundColor Yellow
Write-Host $global:ExcludedServerlist -ForegroundColor Red -BackgroundColor Yellow
} else {
Write-Host "[$(Get-Date)]: Total resources considered for move : $($arcServers.Count)`n"
$arcServers.ResourceID
if($arcServers.Count -gt 0){
Write-Host "`n[$(Get-Date)]: Starting the MOVE of Arc server resources. This process may take a few minutes, please do not close the window."
Move-AzResource -DestinationSubscriptionId $DestinationSubscriptionId -DestinationResourceGroupName $TargetRgName -ResourceId $arcServers.ResourceId -Force
Write-Host "[$(Get-Date)]: Initialization of the resource move has been successfully completed. Moving the child (SQL Server) resource(s) may take some time. Please check the Azure portal later."}
}
}
else
{
Write-Host "[$(Get-Date)]: No Arc Machines available for the move operation."
}
}
#____________________________________________________________________
# Check for remaining resources in the old resource group
#____________________________________________________________________
Function validate-after-MachineMove {
$allResources = @();
Set-AzContext -SubscriptionId $SourceSubscriptionId -WarningAction SilentlyContinue | Out-Null
$arcServers = Get-AzResource -ResourceGroupName $SourceRgName -ResourceType "microsoft.hybridcompute/machines"
$allResources += $arcServers
if ($allResources) {
Write-Host "[$(Get-Date)]: There are still [$($allResources.count)] resources in the old resource group '$SourceRgName':`n"
$allResources.ResourceID
} else {
Write-Host "[$(Get-Date)]: No resources remaining in the old resource group '$SourceRgName'."
if ($global:ArcEnabledServerlist.Count -gt 0) {
Write-Host "[$(Get-Date)]: Enabling the BPA for [$($global:ArcEnabledServerlist.Count)] resource(s) on the target resource group."
Set-AzContext -SubscriptionId $DestinationSubscriptionId -WarningAction SilentlyContinue | Out-Null
$arcMachines=$global:ArcEnabledServerlist
foreach ($arcMachine in $arcMachines) {
Write-Host "[$(Get-Date)]: Validating the BPA status for Machine:[$($arcMachine.Split('/')[-1])]"
$arcMachine = $arcMachine.Replace($SourceSubscriptionId, $DestinationSubscriptionId).Replace($SourceRgName, $TargetRgName)
$status = Get-BPAStatus -machineID $($arcMachine) -mode "Validate"
switch ($status) {
$true {Write-Host "[$(Get-Date)]: `nSQL Best Practice AssessmentSettings is already set to : [$($status.ToString().ToUpper())] for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]"}
"Not-Configured" {Write-Host "[$(Get-Date)]: Failed to update SQL Best Practice AssessmentSettings for Machine: [$(($($arcMachine.ResourceId) -split '/')[($($arcMachine.ResourceId) -split '/').IndexOf('machines') + 1])] as it is not Configured" -BackgroundColor Yellow -ForegroundColor Red }
$false {
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is set to : [$($status.ToString().ToUpper())] for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]"
Write-Host "[$(Get-Date)]: Attempting to ENABLE SQL Best Practice AssessmentSettings for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]" -BackgroundColor White -ForegroundColor Black
# Perform status update and check
$status = Set-BPAConfiguration -machineID $($arcMachine) -valuetoset 'Enable'
#$status = Get-BPAStatus -machineID $($arcMachine) -mode "Validate"
switch ($status) {
$true {
$machineName = ($arcMachine.ResourceId -split '/')[($arcMachine.ResourceId -split '/').IndexOf('machines') + 1]
Write-Host "[$(Get-Date)]: SQL Best Practice AssessmentSettings is now set to : [$($status.ToString().ToUpper())] for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]"
}
$false {
$machineName = ($arcMachine.ResourceId -split '/')[($arcMachine.ResourceId -split '/').IndexOf('machines') + 1]
Write-Host "[$(Get-Date)]: Failed to update SQL Best Practice AssessmentSettings for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]"
$global:ExcludedServerlist += $arcMachine.Name
}
}
}
"DISCONNECTED" {Write-Host "[$(Get-Date)]: Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])] is in DISCONNECTED state, Skipping the BPA enablement" -BackgroundColor Red -ForegroundColor White}
"DISCONNECTED-MISSING-SQLExtention" {Write-Host "[$(Get-Date)]: SQL Extension is missing for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])] , Skipping the BPA enablement" -BackgroundColor Red -ForegroundColor White}
default {Write-Host "[$(Get-Date)]: Unknown status value [$status] for Machine:[$(($arcMachine -split '/')[($arcMachine -split '/').IndexOf('machines') + 1])]" -BackgroundColor Red -ForegroundColor White}
}
}
}
else {Write-Host "[$(Get-Date)]: No machines found for BPA enablement."}
}
}
# Start capturing the output to the file
$outputFile = ([System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "MoveArcResourcesOutput_" + (Get-Date -Format "yyyy-MM-dd_HH.mm.ss") + '.txt'))
Start-Transcript -Path $outputFile > $null
#1. Load required modules
LoadRequiredModules
# Get subscription details for Source and Destination
Set-AzContext -SubscriptionId $DestinationSubscriptionId -WarningAction SilentlyContinue | Out-Null
$SourceSubscription = Get-AzSubscription -SubscriptionId $SourceSubscriptionId -WarningAction SilentlyContinue
Set-AzContext -SubscriptionId $SourceSubscriptionId -WarningAction SilentlyContinue| Out-Null
$DestinationSubscription = Get-AzSubscription -SubscriptionId $DestinationSubscriptionId -WarningAction SilentlyContinue
Cls
# Display the details of inputparameters
Write-Host "[$(Get-Date)]: __________________Start of script_______________________________`n[$(Get-Date)]: Input Parameters considered for this execution:`n"
Write-Host "Source Subscription ID : $SourceSubscriptionId ($($SourceSubscription.Name)`) `nDestination Subscription ID : $DestinationSubscriptionId ($($DestinationSubscription.Name)`) `nSource Resource Group Name : $SourceRgName `nTarget Resource Group Name : $TargetRgName `nLogAnalyticsWorkspaceName : $logAnalyticsWorkspaceName `n"
#2. Check if both subscriptions are in the same tenant
if ($sourceSubscription.TenantId -ne $destinationSubscription.TenantId) {
Write-Host "[$(Get-Date)]: Cannot move resource as the subscriptions are in different tenants."
} else {
Write-Host "[$(Get-Date)]: Both subscriptions are in the same tenant. You can proceed with the move."
#3. Checks whether a specified destination resource group exists
CheckDestinationResourceGroup
#4. Verifies the existence and configuration of a Log Analytics Workspace on the Target subscription
CheckLogAnalyticsWorkspace
#5. Retrieves the current status of the Best Practice Analyzer (BPA) for a Arc machine and disables it to prepare for resource move
Ensure-BPA-IsDisabled
#6. Initialize the resource move
move-Arc-machines
#7. Validate the resource move
validate-after-MachineMove
}
Write-Host "[$(Get-Date)]: __________________END of script_______________________________`n`n"
# Stop capturing output
Stop-Transcript > $null
Start-Process "notepad.exe" -ArgumentList $outputFile
Sample output