From fb2f17196343b4e19a373c383843c816638ba456 Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Tue, 25 Nov 2025 20:48:51 +0530 Subject: [PATCH 1/9] Prevent logging into remote session without credentials to overcome double hopon authentication issue --- .../StackHCI.Autorest/custom/stackhci.ps1 | 35 ++++++++++++------- src/StackHCI/StackHCI/ChangeLog.md | 1 + 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index 499c0e60824e..c9880368e45d 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -500,13 +500,22 @@ function Confirm-UserAcknowledgmentToUpgradeOS { [Microsoft.Azure.PowerShell.Cmdlets.StackHCI.DoNotExportAttribute()] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory=$false)] [System.Management.Automation.Runspaces.PSSession] $ClusterNodeSession ) $osVersionDetectoid = { $displayVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion; $buildNumber = (Get-CimInstance -ClassName CIM_OperatingSystem).BuildNumber; New-Object -TypeName PSObject -Property @{'DisplayVersion'=$displayVersion; 'BuildNumber'=$buildNumber} } - $osVersionInfo = Invoke-Command -Session $clusterNodeSession -ScriptBlock $osVersionDetectoid + + if ($ClusterNodeSession) + { + $osVersionInfo = Invoke-Command -Session $ClusterNodeSession -ScriptBlock $osVersionDetectoid + } + else + { + $osVersionInfo = & $osVersionDetectoid + } + $isOSVersion22H2 = ([Int]::Parse($osVersionInfo.BuildNumber) -le $22H2BuildNumber) $doNotAbort = $true @@ -6042,7 +6051,7 @@ param( try { - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $LogFilePrefix = "AddAzStackHCIVMAttestation" @@ -6238,7 +6247,7 @@ param( try { - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $LogFilePrefix = "RemoveAzStackHCIVMAttestation" @@ -6366,7 +6375,7 @@ param( { try { - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $getImdsOutputList = [System.Collections.ArrayList]::new() @@ -6533,7 +6542,7 @@ function Invoke-DeploymentModuleDownload{ $retryCount = 3 try { - $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Setup-Logging -LogFilePrefix "AzStackHCIRemoteSupport" -DebugEnabled ($DebugPreference -ne "SilentlyContinue") -ClusterNodeSession $clusterNodeSession -IsClusterRegistered $IsClusterRegistered | Out-Null if ($Null -ne $clusterNodeSession) @@ -6572,7 +6581,7 @@ function Install-DeployModule { $ModuleName ) - $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Setup-Logging -LogFilePrefix "AzStackHCIRemoteSupportInstallModule" -DebugEnabled ($DebugPreference -ne "SilentlyContinue") -ClusterNodeSession $clusterNodeSession -IsClusterRegistered $IsClusterRegistered | Out-Null if ($Null -ne $clusterNodeSession) @@ -6612,7 +6621,7 @@ function Install-AzStackHCIRemoteSupport{ [OutputType([Boolean])] param() - $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession @@ -6652,7 +6661,7 @@ function Remove-AzStackHCIRemoteSupport{ [OutputType([Boolean])] param() - $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $IsClusterRegistered, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession Setup-Logging -LogFilePrefix "AzStackHCIRemoteSupportRemove" -DebugEnabled ($DebugPreference -ne "SilentlyContinue") -ClusterNodeSession $clusterNodeSession -IsClusterRegistered $IsClusterRegistered | Out-Null if ($Null -ne $clusterNodeSession) @@ -6720,7 +6729,7 @@ function Enable-AzStackHCIRemoteSupport{ $AgreeToRemoteSupportConsent ) - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession if ($AgreeToRemoteSupportConsent -ne $true) @@ -6767,7 +6776,7 @@ function Disable-AzStackHCIRemoteSupport{ [OutputType([Boolean])] param() - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $agentInstallType = (Get-ItemProperty -Path "HKLM:\SYSTEM\Software\Microsoft\AzureStack\Observability\RemoteSupport" -ErrorAction SilentlyContinue).InstallType @@ -6815,7 +6824,7 @@ function Get-AzStackHCIRemoteSupportAccess{ $IncludeExpired ) - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $agentInstallType = (Get-ItemProperty -Path "HKLM:\SYSTEM\Software\Microsoft\AzureStack\Observability\RemoteSupport" -ErrorAction SilentlyContinue).InstallType @@ -6917,7 +6926,7 @@ function Get-AzStackHCIRemoteSupportSessionHistory{ $FromDate = (Get-Date).AddDays(-7) ) - $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails + $_, $_, $clusterNodeSession, $_ = Get-SetupLoggingDetails -newSession $false Confirm-UserAcknowledgmentToUpgradeOS -ClusterNodeSession $clusterNodeSession $agentInstallType = (Get-ItemProperty -Path "HKLM:\SYSTEM\Software\Microsoft\AzureStack\Observability\RemoteSupport" -ErrorAction SilentlyContinue).InstallType diff --git a/src/StackHCI/StackHCI/ChangeLog.md b/src/StackHCI/StackHCI/ChangeLog.md index 685d51011cef..8715945cb484 100644 --- a/src/StackHCI/StackHCI/ChangeLog.md +++ b/src/StackHCI/StackHCI/ChangeLog.md @@ -18,6 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release +* Prevention of DoubleHopOn Authentication issue. ## Version 2.6.2 * Preannounced breaking changes. Please refer to https://go.microsoft.com/fwlink/?linkid=2333229 From 1f13ef5dcf959d6bd23bd32469a1a44e16afd015 Mon Sep 17 00:00:00 2001 From: Samhitha-Microsoft Date: Tue, 25 Nov 2025 21:02:17 +0530 Subject: [PATCH 2/9] Update src/StackHCI/StackHCI/ChangeLog.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/StackHCI/StackHCI/ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StackHCI/StackHCI/ChangeLog.md b/src/StackHCI/StackHCI/ChangeLog.md index 8715945cb484..64c1e3c114bd 100644 --- a/src/StackHCI/StackHCI/ChangeLog.md +++ b/src/StackHCI/StackHCI/ChangeLog.md @@ -18,7 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release -* Prevention of DoubleHopOn Authentication issue. +* Resolved double hop authentication issue. ## Version 2.6.2 * Preannounced breaking changes. Please refer to https://go.microsoft.com/fwlink/?linkid=2333229 From 9c148143b93714c7b914ec38c8f28bdd339924af Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Fri, 28 Nov 2025 16:46:55 +0530 Subject: [PATCH 3/9] Arc Enablement of nodes before triggering registration in MSI Based registration --- .../StackHCI.Autorest/custom/stackhci.ps1 | 161 +++++++++++++++++- src/StackHCI/StackHCI/ChangeLog.md | 1 + 2 files changed, 160 insertions(+), 2 deletions(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index 60d4c47c23a2..9114df0a9bc1 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -2875,6 +2875,128 @@ function Test-ClusterMsiSupport { return $result -eq $true } +function Enable-ArcOnNodes { + param( + [Parameter(Mandatory=$true)] + [array]$ClusterNodes, + [Parameter(Mandatory=$false)] + [System.Management.Automation.PSCredential]$Credential, + [Parameter(Mandatory=$true)] + [string]$ClusterDNSSuffix, + [Parameter(Mandatory=$true)] + [string]$SubscriptionId, + [Parameter(Mandatory=$true)] + [string]$ResourceGroupName, + [Parameter(Mandatory=$true)] + [string]$TenantId, + [Parameter(Mandatory=$true)] + [string]$Location, + [Parameter(Mandatory=$true)] + [string]$EnvironmentName, + [Parameter(Mandatory=$true)] + [string]$AccessToken, + [Parameter(Mandatory=$false)] + [bool]$UseStableAgent = $false + ) + + Write-VerboseLog "[Arc Enablement] Starting manual Arc enablement on nodes for environment: $EnvironmentName" + + $cloudArgument = $EnvironmentName + if (($EnvironmentName -eq $AzureCanary) -or ($EnvironmentName -eq $AzurePPE)) { + $cloudArgument = $AzureCloud + } + + foreach ($node in $ClusterNodes) { + $nodeName = $node.Name + $nodeFQDN = "$nodeName.$ClusterDNSSuffix" + + Write-VerboseLog "[Arc Enablement] Processing node: $nodeName" + + $session = $null + try { + if ($Credential) { + $session = New-PSSession -ComputerName $nodeFQDN -Credential $Credential + } else { + $session = New-PSSession -ComputerName $nodeFQDN + } + + Invoke-Command -Session $session -ScriptBlock { + param($subId, $rg, $loc, $tenant, $token, $cloud, $UseStableAgent) + + $agentPath = "${env:ProgramFiles}\AzureConnectedMachineAgent\azcmagent.exe" + + # 1. Install Agent if missing + if (-not (Test-Path $agentPath)) { + Write-Verbose "Arc agent not found. Downloading and Installing..." + $installerPath = "$env:TEMP\AzureConnectedMachineAgent.msi" + + $url = 'https://aka.ms/AzureConnectedMachineAgent' + if ($UseStableAgent) { + $url = 'https://aka.ms/hciarcagent' + } + + try { + Invoke-WebRequest -Uri $url -OutFile $installerPath -ErrorAction Stop + } + catch { + throw "Failed to download Azure Connected Machine Agent from $url. Error: $($_.Exception.Message)" + } + + $installArgs = "/i `"$installerPath`" /qn /l*v `"$env:TEMP\install.log`"" + $process = Start-Process msiexec.exe -ArgumentList $installArgs -Wait -PassThru + + if ($process.ExitCode -ne 0) { + throw "Agent installation failed with exit code $($process.ExitCode). Check $env:TEMP\install.log" + } + } + + # 2. Check status + if (Test-Path $agentPath) { + $statusJson = & $agentPath show -j | ConvertFrom-Json + $isConnected = $statusJson.status -eq "Connected" + + if ($isConnected -and + ($statusJson.subscriptionId -eq $subId) -and + ($statusJson.resourceGroup -eq $rg) -and + ($statusJson.tenantId -eq $tenant)) { + Write-Verbose "Node is already connected to correct Subscription/RG." + return + } + } + + # 3. Connect using the passed token + $connectArgs = @("connect", + "--subscription-id", $subId, + "--resource-group", $rg, + "--tenant-id", $tenant, + "--location", $loc, + "--access-token", $token, + "--cloud", $cloud, + "--correlation-id", $(New-Guid).ToString()) + + Write-Verbose "Executing azcmagent connect..." + + # Use call operator & to run command and capture stdout/stderr combined + $output = & $agentPath $connectArgs 2>&1 | Out-String + + if ($LASTEXITCODE -ne 0) { + # Now we throw the ACTUAL error message from azcmagent + throw "azcmagent connect failed with exit code $LASTEXITCODE. Details: $output" + } + + } -ArgumentList $SubscriptionId, $ResourceGroupName, $Location, $TenantId, $AccessToken, $cloudArgument, $UseStableAgent + } + catch { + Write-ErrorLog "Failed to enable Arc on node ${nodeName}: $($_.Exception.Message)" + throw + } + finally { + if ($session) { Remove-PSSession $session } + } + } + Write-VerboseLog "[Arc Enablement] Completed successfully on all nodes." +} + <# Checks whether all nodes in the given cluster are Arc-enabled. [bool] Returns $true if all nodes are Arc-enabled, $false otherwise. @@ -3060,10 +3182,45 @@ function Invoke-MSIFlow { Write-NodeEventLog -Message "[MSI Flow] Starting MSI-based cluster registration." -EventID 9133 -IsManagementNode $IsManagementNode -credentials $Credential -ComputerName $ComputerName $resource = Get-AzResource -ResourceId $ResourceId -ApiVersion $RPAPIVersion -ErrorAction Ignore - #Confirm Arc is enabled on all nodes + # Check if nodes are already Arc enabled $allArcEnabled = Test-ClusterArcEnabled -ClusterNodes $ClusterNodes -Credential $Credential -ClusterDNSSuffix $ClusterDNSSuffix -SubscriptionId $SubscriptionId -ArcResourceGroupName $ArcServerResourceGroupName + if (-not $allArcEnabled) { - throw [System.InvalidOperationException]::new("Not all cluster nodes are Arc-enabled. Aborting MSI registration.") + Write-VerboseLog "[MSI Flow] Not all nodes are Arc-enabled. Attempting to enable Arc on nodes manually..." + + # 2. Retrieve Token Locally + try { + Write-VerboseLog "[MSI Flow] Requesting Access Token for Tenant '$TenantId'" + + $azToken = Get-AzAccessToken -TenantId $TenantId -ErrorAction Stop + $tokenString = $azToken.Token + + if ($tokenString -is [System.Security.SecureString]) { + $tokenString = [System.Net.NetworkCredential]::new("", $tokenString).Password + } + } + catch { + throw "Failed to retrieve Azure Access Token for Arc enablement. Error: $($_.Exception.Message)" + } + + # 3. Call the manual enablement function with the PlainText token + Enable-ArcOnNodes -ClusterNodes $ClusterNodes ` + -Credential $Credential ` + -ClusterDNSSuffix $ClusterDNSSuffix ` + -SubscriptionId $SubscriptionId ` + -ResourceGroupName $ArcServerResourceGroupName ` + -TenantId $TenantId ` + -Location $Region ` + -EnvironmentName $EnvironmentName ` + -AccessToken $tokenString ` + -UseStableAgent $UseStableAgent + + # Re-verify enablement + $allArcEnabled = Test-ClusterArcEnabled -ClusterNodes $ClusterNodes -Credential $Credential -ClusterDNSSuffix $ClusterDNSSuffix -SubscriptionId $SubscriptionId -ArcResourceGroupName $ArcServerResourceGroupName + + if (-not $allArcEnabled) { + throw [System.InvalidOperationException]::new("Failed to enable Arc on all cluster nodes. Aborting registration.") + } } if($Null -eq $resource.Properties.ResourceProviderObjectId) diff --git a/src/StackHCI/StackHCI/ChangeLog.md b/src/StackHCI/StackHCI/ChangeLog.md index 2624f872bc7f..5c710a817042 100644 --- a/src/StackHCI/StackHCI/ChangeLog.md +++ b/src/StackHCI/StackHCI/ChangeLog.md @@ -18,6 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release +ARC Enablement of Nodes Before Triggering Registration in New Registartion Flow. ## Version 2.6.4 * Fixed bug: Buse boolean in comparision From 85bb3d426badaf7d35f3bcbf415e31e0709dc77f Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Fri, 28 Nov 2025 17:38:17 +0530 Subject: [PATCH 4/9] Added Telemetry --- .../StackHCI.Autorest/custom/stackhci.ps1 | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index 9114df0a9bc1..7358cfdc0ce0 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -2896,7 +2896,11 @@ function Enable-ArcOnNodes { [Parameter(Mandatory=$true)] [string]$AccessToken, [Parameter(Mandatory=$false)] - [bool]$UseStableAgent = $false + [bool]$UseStableAgent = $false, + [Parameter(Mandatory=$false)] + [bool]$IsManagementNode = $false, + [Parameter(Mandatory=$false)] + [string]$ComputerName = [Environment]::MachineName ) Write-VerboseLog "[Arc Enablement] Starting manual Arc enablement on nodes for environment: $EnvironmentName" @@ -2987,14 +2991,18 @@ function Enable-ArcOnNodes { } -ArgumentList $SubscriptionId, $ResourceGroupName, $Location, $TenantId, $AccessToken, $cloudArgument, $UseStableAgent } catch { - Write-ErrorLog "Failed to enable Arc on node ${nodeName}: $($_.Exception.Message)" + $errorMsg = "Failed to enable Arc on node ${nodeName}: $($_.Exception.Message)" + Write-ErrorLog $errorMsg + Write-NodeEventLog -Message $errorMsg -EventID 9150 -IsManagementNode $IsManagementNode -Credentials $Credential -ComputerName $ComputerName -Level Error throw } finally { if ($session) { Remove-PSSession $session } } } - Write-VerboseLog "[Arc Enablement] Completed successfully on all nodes." + $successMsg = "[Arc Enablement] Completed successfully on all nodes." + Write-VerboseLog $successMsg + Write-NodeEventLog -Message $successMsg -EventID 9151 -IsManagementNode $IsManagementNode -Credentials $Credential -ComputerName $ComputerName -Level Information } <# @@ -3213,7 +3221,9 @@ function Invoke-MSIFlow { -Location $Region ` -EnvironmentName $EnvironmentName ` -AccessToken $tokenString ` - -UseStableAgent $UseStableAgent + -UseStableAgent $UseStableAgent ` + -IsManagementNode $IsManagementNode ` + -ComputerName $ComputerName # Re-verify enablement $allArcEnabled = Test-ClusterArcEnabled -ClusterNodes $ClusterNodes -Credential $Credential -ClusterDNSSuffix $ClusterDNSSuffix -SubscriptionId $SubscriptionId -ArcResourceGroupName $ArcServerResourceGroupName From ab03208a47dfb8616b27acc42d1bb6854793e56f Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Fri, 28 Nov 2025 18:11:14 +0530 Subject: [PATCH 5/9] Added the missing parameter --- src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 | 4 +++- src/StackHCI/StackHCI/ChangeLog.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index 7358cfdc0ce0..742ead7da88c 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -3182,7 +3182,9 @@ function Invoke-MSIFlow { [Parameter(Mandatory=$false)] [string]$ArcServerResourceGroupName, [Parameter(Mandatory=$false)] - [string]$EnvironmentName = $AzureCloud + [string]$EnvironmentName = $AzureCloud, + [Parameter(Mandatory=$false)] + [bool]$UseStableAgent = $false ) try { diff --git a/src/StackHCI/StackHCI/ChangeLog.md b/src/StackHCI/StackHCI/ChangeLog.md index 5c710a817042..53d39272f76c 100644 --- a/src/StackHCI/StackHCI/ChangeLog.md +++ b/src/StackHCI/StackHCI/ChangeLog.md @@ -18,7 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release -ARC Enablement of Nodes Before Triggering Registration in New Registartion Flow. +ARC Enablement of Nodes Before Triggering Registration in New Registration Flow. ## Version 2.6.4 * Fixed bug: Buse boolean in comparision From d7d3711f8a7733d1849137b51a0b5bfaca35b404 Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Mon, 1 Dec 2025 08:23:33 +0530 Subject: [PATCH 6/9] Added the missing parameter --- src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index 742ead7da88c..ef8710f2aa17 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -4287,7 +4287,7 @@ Set-WacOutputProperty -IsWAC $IsWAC -PropertyName $OutputPropertyWacErrorCode - if ($isRegistrationWithArcMsiCapable -eq $true) { Write-VerboseLog "[Registration] Entered MSI registration path" - Invoke-MSIFlow -ClusterNodes $clusterNodes -Credential $Credential -ClusterDNSSuffix $clusterDNSSuffix -ResourceId $resourceId -RPAPIVersion $RPAPIVersion -TenantId $TenantId -Region $Region -ResourceGroupName $ResourceGroupName -Tag $Tag -ResourceName $ResourceName -SubscriptionId $SubscriptionId -registrationOutput $registrationOutput -ClusterNodeSession $clusterNodeSession -IsManagementNode $IsManagementNode -ComputerName $ComputerName -IsWAC:$IsWAC -ArcServerResourceGroupName $ArcServerResourceGroupName -EnvironmentName $EnvironmentName + Invoke-MSIFlow -ClusterNodes $clusterNodes -Credential $Credential -ClusterDNSSuffix $clusterDNSSuffix -ResourceId $resourceId -RPAPIVersion $RPAPIVersion -TenantId $TenantId -Region $Region -ResourceGroupName $ResourceGroupName -Tag $Tag -ResourceName $ResourceName -SubscriptionId $SubscriptionId -registrationOutput $registrationOutput -ClusterNodeSession $clusterNodeSession -IsManagementNode $IsManagementNode -ComputerName $ComputerName -IsWAC:$IsWAC -ArcServerResourceGroupName $ArcServerResourceGroupName -EnvironmentName $EnvironmentName -UseStableAgent $useStableAgentVersion $operationStatus = [OperationStatus]::Success } else From 0abfec83ab052ce85f540f107badc11f87bcde40 Mon Sep 17 00:00:00 2001 From: Samhitha Mallannagari Date: Mon, 1 Dec 2025 17:26:05 +0530 Subject: [PATCH 7/9] Modified the error to be clear regarding permissions --- src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 index ef8710f2aa17..eca54d2b32e6 100644 --- a/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 +++ b/src/StackHCI/StackHCI.Autorest/custom/stackhci.ps1 @@ -2984,7 +2984,15 @@ function Enable-ArcOnNodes { $output = & $agentPath $connectArgs 2>&1 | Out-String if ($LASTEXITCODE -ne 0) { - # Now we throw the ACTUAL error message from azcmagent + if ($output -match "Forbidden" -or $output -match "AuthorizationFailed" -or $output -match "access is denied") { + $errorMsg = "PERMISSIONS ERROR: Failed to onboard node '$env:COMPUTERNAME' to Azure Arc.`n" + + "REASON: Your account lacks the required permissions on Resource Group '$rg'.`n" + + "ACTION: Ensure your account has ONE of the following roles:`n" + + " - 'Owner'`n" + + " - 'Contributor'`n" + + " - 'Azure Connected Machine Resource Administrator' " + throw $errorMsg + } throw "azcmagent connect failed with exit code $LASTEXITCODE. Details: $output" } From 9d49c0e0aa68988f50f880579f54cae9dd40fba1 Mon Sep 17 00:00:00 2001 From: Samhitha-Microsoft Date: Tue, 2 Dec 2025 09:15:31 +0530 Subject: [PATCH 8/9] Update src/StackHCI/StackHCI/ChangeLog.md Co-authored-by: Yunchi Wang <54880216+wyunchi-ms@users.noreply.github.com> --- src/StackHCI/StackHCI/ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StackHCI/StackHCI/ChangeLog.md b/src/StackHCI/StackHCI/ChangeLog.md index 53d39272f76c..e7dabb70d7e1 100644 --- a/src/StackHCI/StackHCI/ChangeLog.md +++ b/src/StackHCI/StackHCI/ChangeLog.md @@ -18,7 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release -ARC Enablement of Nodes Before Triggering Registration in New Registration Flow. +* ARC Enablement of Nodes Before Triggering Registration in New Registration Flow. ## Version 2.6.4 * Fixed bug: Buse boolean in comparision From 207df1eac5b2fdacdd785dc30b5d47a9f358dd17 Mon Sep 17 00:00:00 2001 From: Samhitha-Microsoft Date: Tue, 2 Dec 2025 09:18:17 +0530 Subject: [PATCH 9/9] Update src/StackHCI/StackHCI/ChangeLog.md Co-authored-by: Yunchi Wang <54880216+wyunchi-ms@users.noreply.github.com>