jpigott
4 TopicsAzure Update Manager – Patching .NET Core
This blog will share how to configure an Azure Virtual Machine or an Azure Arc-enabled virtual machine to utilize Azure Update Manager for patching .NET Core security updates. There are two different changes that need to be made to the server to allow .NET Core to receive updates with Azure Update Manager: Step 1: Create a registry entry for .NET core updates Step 2: Change the Windows Server to receive other Microsoft Updates for patching. The registry change allows .NET Core to become available to Automatic Updates. .NET Automatic Updates for Server Operating Systems - .NET Blog (microsoft.com) Step 1: Create a registry entry for .NET Core updates You may execute PowerShell to enable this registry setting or create a .reg file to execute. PowerShell example for all of .NET core versions: New-Item -Path "HKLM:\SOFTWARE\Microsoft" -Name ".NET" -Force | Out-Null Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NET" -Name "AllowAUOnServerOS" -Value 1 -Type DWord Or a PowerShell example for a specific .NET core version: New-Item -Path "HKLM:\SOFTWARE\Microsoft\.NET" -Name "6.0" -Force | Out-Null Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NET\6.0" -Name "AllowAUOnServerOS" -Value 1 -Type DWord Registry File example: To use a .reg file for creating the registry entries, copy the text below into a new file (ex: dotnetcore.reg) and execute. This example will create both options for all versions of .NET core and version 6.0 of .NET core. Remove lines as needed. Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NET] "AllowAUOnServerOS"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NET\6.0] "AllowAUOnServerOS"=dword:00000001 Step 2: Change the Windows Server to receive other Microsoft Updates for patching. The other required change to make to the server is to change the Windows Server to receive “other Microsoft products” updates. This change allows other Microsoft products such as SQL Server, and in this example of .NET Core to become available for updating Windows Machines. Configure Windows Update settings in Azure Update Manager | Microsoft Learn Run these commands in PowerShell to change the update settings to receive other Microsoft product updates: $ServiceManager = (New-Object -com "Microsoft.Update.ServiceManager") $ServiceManager.Services $ServiceID = "7971f918-a847-4430-9279-4a52d1efe18d" $ServiceManager.AddService2($ServiceId,7,"") Once these settings are changed. Use the ‘Check for updates’ option in Azure Update Manager. The patch should become available to the virtual machine for .NET Core. In this example, an Azure Windows Server 2022 machine image had the .NET Core 6.0.27 installed. After the machine was checked for new updates, the patch is available now for .NET core 6.0.28. For testing purposes this link is the .NET Core 6.0.27 installer. .NET Core 6.0.27 - Versions of .NET. In conclusion, configuring Azure Update Manager to patch .NET Core security updates is a crucial step in maintaining the security and performance of your Azure Virtual Machines. By enabling the registry setting for automatic updates, you can ensure that your .NET Core installations are always up-to-date with the latest security patches. This process not only simplifies the management of updates but also enhances the overall security posture of your environment. Whether you choose to use PowerShell commands or create a .reg file, the steps outlined in this article provide a clear and effective method for keeping your .NET Core installations secure and up-to-date. *** Disclaimer *** The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.Understanding Windows Server 2012 Extended Security Update Options with Azure Arc
In this article, we will explore the various options of ESU licensing for Windows Server 2012 and demonstrate how visual aids can enhance your understanding and streamline the selection process. Each section has a link back to the license provisioning guidelines for example scenarios. Scenario 1 - Link Scenario 2 - Link Scenario 3 - Link Scenario 4 - Link Scenario 7 - Link Scenario 8 - Link Dev/Test - Link In conclusion, it's crucial to understand the specific needs of your organization and choose the licensing option that best fits your scenario. By leveraging these different options, you can make informed decisions that align with your requirements and ensure a smooth transition to the appropriate ESU licensing. Remember, the key to successful licensing is to thoroughly evaluate your options and select the one that meets your unique needs. With the right approach, you can effectively manage your licensing and continue to benefit from the extended security updates for Windows Server 2012.Using Entra ID Authentication with Arc-Enabled SQL Server in a .NET Windows Forms Application
Introduction: This guide demonstrates how to securely connect a .NET Framework Windows Forms application to an Arc-enabled SQL Server 2022 instance using Entra ID (Azure AD) authentication. It covers user authentication, token management, and secure connection practices, with code samples and screenshots. In many modern applications, it is common practice to use an application web service to mediate access to SQL Server. This approach can offer several advantages, such as improved security, scalability, and centralized management of database connections. However, there are scenarios where directly connecting to SQL Server is more appropriate. This guide focuses on such scenarios, providing a solution for applications that need direct access to SQL Server. This model is particularly useful for applications like SQL Server Management Studio (SSMS), which require direct database connections to perform their functions. By using Entra ID authentication, we can ensure that these direct connections are secure and that user credentials are managed efficiently. By following the steps outlined in this guide, developers can ensure secure and efficient connections between their .NET Windows Forms applications and Arc-enabled SQL Server instances using Entra ID authentication. This approach not only enhances security but also simplifies the management of user credentials and access tokens, providing a robust solution for modern application development. SAMPLE CODE: GitHub Repository Prerequisites Arc-enabled SQL Server 2022/2025 configured for Entra ID authentication Entra ID (Azure AD) tenant and app registration .NET Framework 4.6.2 Windows Forms application (Not required .NET version, only what the solution is based on) Microsoft.Identity.Client, Microsoft.Data.SqlClient NuGet packages Application Overview User authenticates with Entra ID Token is acquired and used to connect to SQL Server Option to persist token cache or keep it in memory Data is retrieved and displayed in a DataGridView Similar setup to use SSMS with Entra ID in articles below. Windows Form Sample Check User Button shows the current user The Connect to Entra ID at Login button will verify if you are logged in and try to connect to SQL Server. If the user is not logged in, an Entra ID authentication window will be displayed or ask you to log in. Once logged in it shows a Connection successful message box stating the connection to the database was completed. The Load Data button queries the Adventure Works database Person table and loads the names into the datagridview. The Cache Token to Disk checkbox option either caches to memory when unchecked and would require reauthentication after the application closes, or the option to cache to disk the token to be read on future application usage. If the file is cached to disk, the location of the cached file is (C:\Users\[useraccount]\AppData\Local). This sample does not encrypt the file which is something that would be recommended for production use. This code uses MSAL (Microsoft Authentication Library) to authenticate users in a .NET application using their Microsoft Entra ID (Azure AD) credentials. It configures the app with its client ID, tenant ID, redirect URI, and logging settings to enable secure token-based authentication. //Application registration ClientID, and TenantID are required for MSAL authentication private static IPublicClientApplication app = PublicClientApplicationBuilder.Create("YourApplicationClientID") .WithAuthority(AzureCloudInstance.AzurePublic, "YourTenantID") .WithRedirectUri("http://localhost") .WithLogging((level, message, containsPii) => Debug.WriteLine($"MSAL: {message}"), LogLevel.Verbose, true, true) .Build(); This method handles user login by either enabling persistent token caching or setting up temporary in-memory caching, depending on the input. It then attempts to silently acquire an access token for Azure SQL Database using cached credentials, falling back to interactive login if no account is found. private async Task<AuthenticationResult> LoginAsync(bool persistCache) { if (persistCache) TokenCacheHelper.EnablePersistence(app.UserTokenCache); else { app.UserTokenCache.SetBeforeAccess(args => { }); app.UserTokenCache.SetAfterAccess(args => { }); } string[] scopes = new[] { "https://database.windows.net//.default" }; var accounts = await app.GetAccountsAsync(); if (accounts == null || !accounts.Any()) return await app.AcquireTokenInteractive(scopes).ExecuteAsync(); var account = accounts.FirstOrDefault(); return await app.AcquireTokenSilent(scopes, account).ExecuteAsync(); } Connecting to SQL Server with Access Token This code connects to an Azure SQL Database using a connection string and an access token obtained through MSAL authentication. It securely opens the database connection by assigning the token to the SqlConnection object, enabling authenticated access without storing credentials in the connection string. This sample uses a self-signed certificate, in production always configure SQL Server protocols with a certificate issued by a trusted Certificate Authority (CA). TrustServerCertificate=True bypasses certificate validation and can allow MITM attacks. For production, use a trusted Certificate Authority and change TrustServerCertificate=True to TrustServerCertificate=False. Configure Client Computer and Application for Encryption - SQL Server | Microsoft Learn string connectionString = $"Server={txtSqlServer.Text};Database=AdventureWorks2019;Encrypt=True;TrustServerCertificate=True;"; var result = await LoginAsync(checkBox1.Checked); using (var conn = new SqlConnection(connectionString)) { conn.AccessToken = result.AccessToken; conn.Open(); // ... use connection ... } Fetching Data into DataGridView This method authenticates the user and connects to an Azure SQL Database using an access token, and runs a SQL query to retrieve the top 1,000 names from the Person table. It loads the results into a DataTable, which can then be used for display or further processing in the application. private async Task<DataTable> FetchDataAsync() { var dataTable = new DataTable(); var result = await LoginAsync(checkBox1.Checked); using (var conn = new SqlConnection(connectionString)) { conn.AccessToken = result.AccessToken; await conn.OpenAsync(); using (var cmd = new SqlCommand("SELECT TOP (1000) [FirstName], [MiddleName], [LastName] FROM [AdventureWorks2019].[Person].[Person]", conn)) using (var reader = await cmd.ExecuteReaderAsync()) { dataTable.Load(reader); } } return dataTable; } Configure Azure Arc SQL Server to use Entra ID authentication Using SQL Server 2022 follow the instructions here to setup the key vault and certificate when configuring. This article can also be used to configure SSMS to use Entra ID authentication. Detailed steps located here: Set up Microsoft Entra authentication for SQL Server - SQL Server | Microsoft Learn Using SQL Server 2025 the setup is much easier as you do not need to configure a Key Vault, or certificates as it is relying on using the managed identity for the authentication. Entra ID App Registration Steps Register a new app in Azure AD Add a redirect URI (http://localhost) Add API permissions for https://database.windows.net/.default On the Entra ID app registration, click on API Permissions. Add the API’s for Microsoft Graph: User.Read.All Application.Read.All Group.Read.All Add a permission for Azure SQL Database. If Azure SQL database is not shown in the list ensure that the Resource Provider is registered for Microsoft.Sql. Choose Delegated permissions and select user_impersonation, Click Add permission for the Azure SQL Database. NOTE: Once the permissions are added ensure that you grant admin consent on the items. Security Considerations Never store client secrets in client apps Use in-memory token cache for higher security, or encrypted disk cache for convenience Use user tokens for auditing and least privilege References Microsoft Docs: Azure AD Authentication for SQL Server MSAL.NET Documentation Arc-enabled SQL Server Documentation Conclusion: By following the steps outlined in this guide, developers can ensure secure and efficient connections between their .NET Windows Forms applications and Arc-enabled SQL Server instances using Entra ID authentication. This approach not only enhances security but also simplifies the management of user credentials and access tokens, providing a robust solution for modern application development. *** Disclaimer *** The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.Managing Hotpatching for Azure Arc connected Machines using APIs
Hotpatching is available as an option for Aure Arc connected Windows Server 2025 Datacenter and Standard machines. To learn more about hotpatching please review this article. Azure Arc portal provides a way for you to enroll or disenroll from hotpatching. To manage hotpatch updates, you can use Azure Update Manager (AUM) or any other patch management tool that has built the hotpatch management capability. You can also choose to use the published APIs to manage hotpatch enrollment and updates. This article provides a sample script of using the APIs to perform the different actions. Always test these scripts in your development environment and tweak to your company’s security posture. Below are the high-level management actions you may perform Enrolling/Disenrolling from hotpatch for Arc connected servers Temporarily opt-in or opt-out of without disenrolling from hotpatch Use Windows Update (WU) API to get the hotpatch update You can perform these steps today through the Azure Arc portal and AUM. However, the ability to manage updates is not limited to AUM and any update management tool can make tooling changes to facilitate hotpatch management. Hotpatch Enrollment & Disenrollment Windows Server 2025 machines that are on-premises or on non-Azure cloud, and are Azure Arc connected can enroll into hotpatch servicing. Traditionally you would have used the Azure Arc portal and manually enrolled the machine for hotpatch servicing. You can also perform the same action using APIs at your disposal. Besides enrollment, you can also disenroll from hotpatch service using these APIs. For details on these API review the specification here. Sample Scripts: Sample scripts that are used in this article may be found here: (GitHub). Examples have been added including utilizing a service principle within the scripts to assisting with automation. See sample code for Enrollment: # Enrollment workflow $subscriptionId = '' #Your subscription id $resourceGroupName = '' # your Resource Group $machineName = '' # Arc resource name $location = "" # The region where the test machine is arc enabled. $subscriptionStatus = "Enable"; # Set SubscriptionStatus to "Disable" for disenrollment $account = Connect-AzAccount -Subscription $subscriptionId $context = Set-azContext -Subscription $subscriptionId $profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.rmProfileClient]::new( $profile ) $token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) $header = @{ 'Content-Type'='application/json' 'Authorization'='Bearer ' + $token.AccessToken } $uri = [System.Uri]::new( "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.HybridCompute/machines/$machineName/licenseProfiles/default?api-version=2023-10-03-preview" ) $contentType = "application/json" $data = @{ location = $location; properties = @{ productProfile = @{ productType = "WindowsServer"; productFeatures = @(@{name = "Hotpatch"; subscriptionStatus = $subscriptionStatus};) }; }; }; $json = $data | ConvertTo-Json -Depth 4; # To create a license profile resource use PUT call $response = Invoke-RestMethod -Method PUT -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; # To update a license profile resource use PATCH call #$response = Invoke-RestMethod -Method PATCH -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; $response.properties.licenseProfile Once this script is completed the hotpatch should be Enabled as shown in the Azure Portal below. When you click into the Hotpatch overview tile, it will display the Virtualization-based security (VBS) status, the license is checked for receiving monthly hotpatches, and the “Enable hotpatching” toggle is turned On. Sample code for Disenrollment # Disenrollment workflow $subscriptionId = '' #Your subscription id $resourceGroupName = '' # your Resource Group $machineName = '' # Arc resource name $location = "" # The region where the test machine is arc enabled. $subscriptionStatus = "Disable"; # Set SubscriptionStatus to "Enable" for enrollment $account = Connect-AzAccount -Subscription $subscriptionId $context = Set-azContext -Subscription $subscriptionId $profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.rmProfileClient]::new( $profile ) $token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) $header = @{ 'Content-Type'='application/json' 'Authorization'='Bearer ' + $token.AccessToken } $uri = [System.Uri]::new( "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.HybridCompute/machines/$machineName/licenseProfiles/default?api-version=2023-10-03-preview" ) $contentType = "application/json" $data = @{ location = $location; properties = @{ productProfile = @{ productType = "WindowsServer"; productFeatures = @(@{name = "Hotpatch"; subscriptionStatus = $subscriptionStatus};) }; }; }; $json = $data | ConvertTo-Json -Depth 4; # To create a license profile resource use PUT call $response = Invoke-RestMethod -Method PUT -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; # To update a license profile resource use PATCH call #$response = Invoke-RestMethod -Method PATCH -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; $response.properties.licenseProfile The Hotpatch tile displays Canceled after Disenrollment. The checkbox is unchecked as well for receiving monthly hotpatches. OPT-in /OPT-out There could be scenarios where users want to temporarily opt out of Hotpatch, without disenrolling from Hotpatch service. That could be for troubleshooting or any other scenario. The option to opt-in and opt-out is available on the Azure Arc Portal, once you have enrolled in the Hotpatch service. It appears as a toggle switch for “Enable hotpatching” option. To do this programmatically review the sample code below. Opt out Sample code: # Change the following params for your test machine. $subscriptionId = '' #Your subscription id $resourceGroupName = '' # your Resource Group $machineName = '' # Arc resource name $location = "" # The region where the test machine is arc enabled. $hotpatchStatus = $false # Do you want to opt-in ($true) or Opt-Out ($false) for receiving hotpatch without changing the license to get hotpatch. $account = Connect-AzAccount -Subscription $subscriptionId $context = Set-azContext -Subscription $subscriptionId $profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.rmProfileClient]::new( $profile ) $token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) $header = @{ 'Content-Type'='application/json' 'Authorization'='Bearer ' + $token.AccessToken } $uri = [System.Uri]::new( "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.HybridCompute/machines/$machineName ?api-version=2024-07-10" ) $contentType = "application/json" $data = @{ location = $location; properties = @{ osProfile = @{ windowsConfiguration=@{ patchSettings=@{ enableHotpatching=$hotpatchStatus; }; }; }; }; }; $json = $data | ConvertTo-Json -Depth 4; $response = Invoke-RestMethod -Method PATCH -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; The Hotpatch tile now shows disabled after Opting out. The Enable hotpatching slider is turned off. Opt in Sample code: # Change the following params for your test machine. $subscriptionId = '' #Your subscription id $resourceGroupName = '' # your Resource Group $machineName = '' # Arc resource name $location = "" # The region where the test machine is arc enabled. $hotpatchStatus = $true # Do you want to opt-in ($true) or Opt-Out ($false) for receiving hotpatch without changing the license to get hotpatch. $account = Connect-AzAccount -Subscription $subscriptionId $context = Set-azContext -Subscription $subscriptionId $profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.rmProfileClient]::new( $profile ) $token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) $header = @{ 'Content-Type'='application/json' 'Authorization'='Bearer ' + $token.AccessToken } $uri = [System.Uri]::new( "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.HybridCompute/machines/$machineName ?api-version=2024-07-10" ) $contentType = "application/json" $data = @{ location = $location; properties = @{ osProfile = @{ windowsConfiguration=@{ patchSettings=@{ enableHotpatching=$hotpatchStatus; }; }; }; }; }; $json = $data | ConvertTo-Json -Depth 4; $response = Invoke-RestMethod -Method PATCH -Uri $uri.AbsoluteUri -ContentType $contentType -Headers $header -Body $json; The Enable hotpatching slider is turned on after the Opting In. Hotpatch Management To manage the Hotpatches you can leverage existing Windows Update APIs along with some additional functionalities that gives you even more control over the updates. Below is a sample code that allows you to scan for updates relevant to your machine. You can loop through the updates and determine if the updates will cause a reboot or not. Hotpatch updates should not cause a reboot unless any of the below two conditions is true: The device has a pending reboot from a previous update The device was on an update prior to the latest baseline update. So, when a hotpatch is offered during a hotpatch month it installs the latest baseline update followed by the hotpatch. The baseline update needs a reboot while the hotpatch itself is installed without a restart. # Create Update Session $session = New-Object -ComObject "Microsoft.Update.Session" $session.ClientApplicationID = "Sample Code" # Create Update Searcher and search for updates Write-Host "Creating Update Searcher and searching for updates.." $updateSearcher = $session.CreateUpdateSearcher() $searchResult = $updateSearcher.Search("IsInstalled=0 and DeploymentAction='Installation'") # If no updates found, exit if ($searchResult.Updates.Count -eq 0) { Write-Host "No updates found!" Exit } # Loop over each update in the Search result Update Collection foreach ($update in $searchResult.Updates) { Write-Host "Update title: '$($update.Title)'" Write-Host "Querying static 'ContainsUpdateBootstrapper' property.." # Query for static extended property # https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateex-get_extendedstaticproperty $containsUpdateBootstrapper = $update.ExtendedStaticProperty("ContainsUpdateBootstrapper") # If the update contains bootstrapper, perform pre-download and query for dynamic extended property if ($containsUpdateBootstrapper) { Write-Host "Update '$($update.Title)' contains update bootstrapper" Write-Host "Creating Update Downloader and performing pre-download of update bootstrapper.." # Create an update collection and add updates to download $downloadColl = New-Object -ComObject "Microsoft.Update.UpdateColl" $downloadColl.Add($update) # Create an Update Downloader and set the update collection to download $downloader = $Session.CreateUpdateDownloader() $downloader.Updates = $downloadColl # Perform pre-download to download only update bootstrapper # https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatedownloaderex-download2 $downloadResult = $downloader.Download2(1) if ($downloadResult.HResult -eq 0) { Write-Host "Successfully downloaded update bootstrapper" Write-Host "Evaluating dynamic 'DoesUpdateRequireReboot' property.." # Query for dynamic extended property # https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateex-evaluateextendeddynamicproperty $doesUpdateRequireReboot = $update.EvaluateExtendedDynamicProperty("DoesUpdateRequireReboot") if ($doesUpdateRequireReboot) { # If update requires reboot, skip download/install Write-Host "Update: '$($update.Title)' requires reboot, skipping" } else { # If update does not require reboot, it is a rebootless update, hence perform full download and install Write-Host "Update: '$($update.Title)' does not require reboot" Write-Host "Performing full download of update '$($update.Title)'.." # Perform full download of the update $fullDownloadResult = $downloader.Download() if ($fullDownloadResult.HResult -eq 0) { Write-Host "Successfully downloaded update: '$($update.Title)'" Write-Host "Creating Update Installer to install update: '$($update.Title)'.." # Create an update collection and add updates to install $installColl = New-Object -ComObject "Microsoft.Update.UpdateColl" $installColl.Add($update) # Create an Update Installer, set the update collection to install and install the updates $installer = $Session.CreateUpdateInstaller() $installer.Updates = $installColl # Install the updates $installResult = $installer.Install() if ($installResult.HResult -eq 0) { Write-Host "Successfully installed update: '$($update.Title)'" } else { Write-Host "Failed to install update: '$($update.Title)'!" Exit } } else { Write-Host "Failed to download update: '$($update.Title)'!" Exit } } } else { Write-Host "Failed to download update bootstrapper for update: '$($update.Title)'!" Exit } } else { Write-Host "Update '$($update.Title)' does not contain update bootstrapper, skipping" } } Below is a sample snippet of an update. This shows that the cumulative update does not require a reboot and that it was Hotpatch capable. This update will be installed as part of this update check. Use Azure Resource Graph to determine which machines are enabled for hot patching. Resources | where type == "microsoft.hybridcompute/machines" | extend hotpatchEnabled = tostring(properties.osProfile.windowsConfiguration.patchSettings.enableHotpatching) | extend hotpatchStatus = tostring(properties.osProfile.windowsConfiguration.patchSettings.status.hotpatchEnablementStatus) | project name, location, resourceGroup, hotpatchEnabled, hotpatchStatus | order by hotpatchEnabled desc In summary, effective management of hotpatching for Azure Arc connected machines requires a thoughtful approach that balances automation, security, and operational needs. By leveraging the provided sample scripts and APIs, organizations can streamline patch deployment while maintaining control over their environments. It is essential to rigorously test all automation in a development setting and adapt solutions to align with your company’s security posture. By embracing these strategies, organizations can proactively safeguard their systems, minimize downtime, and stay ahead in an ever-evolving cloud environment. If you have questions, please feel to reach out to our team: hotpatchfeedback@microsoft.com *** Disclaimer *** The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.