Dell Integrated System for Microsoft Azure Stack Hub Release Notes
Current Release Version: Dell 2502 and Microsoft 2501
Release Type: Major (MA)
NOTE
Dell Azure Stack Hub OEM updates must be installed in sequential order, it is not supported to skip or miss-out an OEM update version. These release notes contain supplemental information for the Dell 2502 release and the Microsoft 2501 release.
This release notes document describes known issues and limitations for the Dell Integrated System for Microsoft Azure Stack Hub solution based on the Dell 2502 release and Microsoft 2501 release.
Item
Description
OEM update
Dell Technologies recommends updating to the n-1 version before applying the latest OEM package.
Microsoft Azure Stack Hub code
For information about known issues and limitations in the Microsoft Azure Stack Hub code, see the Azure Stack Hub 2501 update on the Microsoft website
Notes and warnings
CAUTION
Before you use the Microsoft Patch and Update process to update Azure Stack Hub, close any active session to the ERCS virtual machines. If an active session is open, the update may fail, and must be resumed.
Microsoft fixed issues
For information about fixed issues in this release, see the Azure Stack Hub 2501 update on the Microsoft website.
Dell Integrated System for Microsoft Azure Stack Hub Release Notes
Current Release Version: Dell 2502 and Microsoft 2501
Release Type: Major (MA)
NOTE
Dell Azure Stack Hub OEM updates must be installed in sequential order, it is not supported to skip or miss-out an OEM update version. These release notes contain supplemental information for the Dell 2502 release and the Microsoft 2501 release.
New features, changed features, and fixes
New features
Initial release of the Dell Integrated System for Microsoft Azure Stack Hub Lifecycle Manager which provides an automated way of upgrading Hardware Lifecycle Host (HLH) firmware, software and driver components. See Patch and Update for 16G.
This release notes document describes known issues and limitations for the Dell Integrated System for Microsoft Azure Stack Hub solution based on the Dell 2502 release and Microsoft 2501 release.
Item
Description
OEM update
Dell Technologies recommends updating to the n-1 version before applying the latest OEM package.
Microsoft Azure Stack Hub code
For information about known issues and limitations in the Microsoft Azure Stack Hub code, see the Azure Stack Hub 2501 update on the Microsoft website
Notes and warnings
CAUTION
Before you use the Microsoft Patch and Update process to update Azure Stack Hub, close any active session to the ERCS virtual machines. If an active session is open, the update may fail, and must be resumed.
Microsoft fixed issues
For information about fixed issues in this release, see the Azure Stack Hub 2501 update on the Microsoft website.
Dell Integrated System for Microsoft Azure Stack Hub Release Notes
Current Release Version: Dell 2411 and Microsoft 2408
Release Type: Major (MA)
NOTE
Dell Azure Stack Hub OEM updates must be installed in sequential order, it is not supported to skip or miss-out an OEM update version. These release notes contain supplemental information for the Dell 2411 release and the Microsoft 2408 release.
This release notes document describes known issues and limitations for the Dell Integrated System for Microsoft Azure Stack Hub solution based on the Dell 2411 release and Microsoft 2408 release.
Item
Description
OEM update
Dell Technologies recommends updating to the n-1 version before applying the latest OEM package.
Microsoft Azure Stack Hub code
For information about known issues and limitations in the Microsoft Azure Stack Hub code, see the Azure Stack Hub 2408 update on the Microsoft website
Notes and warnings
CAUTION
Before you use the Microsoft Patch and Update process to update Azure Stack Hub, close any active session to the ERCS virtual machines. If an active session is open, the update may fail, and must be resumed.
Microsoft fixed issues
For information about fixed issues in this release, see the Azure Stack Hub 2408 update on the Microsoft website.
Dell Integrated System for Microsoft Azure Stack Hub Release Notes
Current Release Version: Dell 2411 and Microsoft 2408
Release Type: Major (MA)
NOTE
Dell Azure Stack Hub OEM updates must be installed in sequential order, it is not supported to skip or miss-out an OEM update version. These release notes contain supplemental information for the Dell 2411 release and the Microsoft 2408 release.
This release notes document describes known issues and limitations for the Dell Integrated System for Microsoft Azure Stack Hub solution based on the Dell 2411 release and Microsoft 2408 release.
Item
Description
OEM update
Dell Technologies recommends updating to the n-1 version before applying the latest OEM package.
Microsoft Azure Stack Hub code
For information about known issues and limitations in the Microsoft Azure Stack Hub code, see the Azure Stack Hub 2408 update on the Microsoft website
Notes and warnings
CAUTION
Before you use the Microsoft Patch and Update process to update Azure Stack Hub, close any active session to the ERCS virtual machines. If an active session is open, the update may fail, and must be resumed.
Microsoft fixed issues
For information about fixed issues in this release, see the Azure Stack Hub 2408 update on the Microsoft website.
Dell Integrated System for Microsoft Azure Stack Hub Release Notes
Current Release Version: Dell 2407 and Microsoft 2406
Release Type: Major (MA)
NOTE
Dell Azure Stack Hub OEM updates must be installed in sequential order, it is not supported to skip or miss-out an OEM update version. These release notes contain supplemental information for the Dell 2407 release and the Microsoft 2406 release.
Secure Connect Gateway (SCG) will be uninstalled from existing deployments.
Changed features
There are no changed features for this release.
Fixes
There are no fixes for this release.
Known issues and limitations
This release notes document describes known issues and limitations for the Dell Integrated System for Microsoft Azure Stack Hub solution based on the Dell 2407 release and Microsoft 2406 release.
Item
Description
OEM update
Dell Technologies recommends updating to the n-1 version before applying the latest OEM package.
Microsoft Azure Stack Hub code
For information about known issues and limitations in the Microsoft Azure Stack Hub code, see the Azure Stack Hub 2406 update on the Microsoft website
Notes and warnings
CAUTION
Before you use the Microsoft Patch and Update process to update Azure Stack Hub, close any active session to the ERCS virtual machines. If an active session is open, the update may fail, and must be resumed.
Microsoft fixed issues
For information about fixed issues in this release, see the Azure Stack Hub 2406 update on the Microsoft website.
Dell Integrated System for Microsoft Azure Stack Hub - Valid from Dell 2502 release and Microsoft 2501 release
Abstract
This support matrix provides information about supported software and hardware configurations for Dell Integrated System for Microsoft Azure Stack Hub.
Introduction
The Dell Integrated System for Microsoft Azure Stack Hub Support Matrix describes supported drivers, firmware, applications, and hardware for Dell Integrated System for Microsoft Azure Stack Hub.
NOTE
All references to release dates refer to Dell Technologies releases, unless otherwise indicated.
Dell Integrated System for Microsoft Azure Stack Hub - Valid from Dell 2502 release and Microsoft 2501 release
Abstract
This support matrix provides information about supported software and hardware configurations for Dell Integrated System for Microsoft Azure Stack Hub.
Introduction
The Dell Integrated System for Microsoft Azure Stack Hub Support Matrix describes supported drivers, firmware, applications, and hardware for Dell Integrated System for Microsoft Azure Stack Hub.
NOTE
All references to release dates refer to Dell Technologies releases, unless otherwise indicated.
Dell Integrated Systems for Microsoft Azure Stack Hub OEM extension package with drivers and firmware updates
AzSHub_16G_Dell2502.3_OEMPackage.zip
2502.3
Dell Integrated Systems for Microsoft Azure Stack Hub HLH ISO
MS2406_Dell2502.5.iso
2502.5
Dell Integrated Systems for Microsoft Azure Stack Hub Lifecycle Manager
AzSHub_Dell2502.32_LifecycleManager.zip
2502.32
3.2 - Support Matrix for 2411
3.2.1 - Support Matrix for 14G - 2411
Dell Integrated System for Microsoft Azure Stack Hub - Valid from Dell 2411 release and Microsoft 2408 release
Abstract
This support matrix provides information about supported software and hardware configurations for Dell Integrated System for Microsoft Azure Stack Hub.
Introduction
The Dell Integrated System for Microsoft Azure Stack Hub Support Matrix describes supported drivers, firmware, applications, and hardware for Dell Integrated System for Microsoft Azure Stack Hub.
NOTE
All references to release dates refer to Dell Technologies releases, unless otherwise indicated.
Dell Integrated System for Microsoft Azure Stack Hub - Valid from Dell 2411 release and Microsoft 2408 release
Abstract
This support matrix provides information about supported software and hardware configurations for Dell Integrated System for Microsoft Azure Stack Hub.
Introduction
The Dell Integrated System for Microsoft Azure Stack Hub Support Matrix describes supported drivers, firmware, applications, and hardware for Dell Integrated System for Microsoft Azure Stack Hub.
NOTE
All references to release dates refer to Dell Technologies releases, unless otherwise indicated.
Dell Integrated Systems for Microsoft Azure Stack Hub OEM extension package with drivers and firmware updates
AzSHub_16G_Dell2411.6_OEMPackage.zip
2411.6
Dell Integrated Systems for Microsoft Azure Stack Hub HLH ISO
MS2406_Dell2411.10.iso
2411.10
3.3 - Support Matrix for 2407
3.3.1 - Support Matrix for 14G - 2407
Dell Integrated System for Microsoft Azure Stack Hub - Valid from Dell 2407 release and Microsoft 2406 release
Abstract
This support matrix provides information about supported software and hardware configurations for Dell Integrated System for Microsoft Azure Stack Hub.
Introduction
The Dell Integrated System for Microsoft Azure Stack Hub Support Matrix describes supported drivers, firmware, applications, and hardware for Dell Integrated System for Microsoft Azure Stack Hub.
NOTE
All references to release dates refer to Dell Technologies releases, unless otherwise indicated.
Microsoft Azure Stack Hub operators are faced with the enormous challenge of keeping their solution both secure and functional. They must ensure that the solution is not vulnerable to threats, external or internal, while maintaining negotiated service-level agreements.
Solution overview
As a Microsoft Azure Stack Hub systems provider, Dell Technologies is committed to ensuring that your Azure Stack Hub environment is both secure and functional. In Dell Technologies releases, you will find firmware and driver updates for both the Hardware Lifecycle Host (HLH) and the scale unit (SU) nodes that are contained in the OEM package updates. Dell Technologies delivers these updates quarterly, and you can apply them independently of Microsoft updates.
There are two other types of update packages for the Azure Stack Hub integrated systems: software updates and hotfixes.
This patch and update guide is for Azure Stack Hub 16th-generation (16G) operators who intend to perform lifecycle operations (Patch and Update) for:
Firmware updates for the Hardware Lifecycle Host (HLH)
Operating System updates for the HLH (Windows Server 2022)
Driver updates for the HLH (Windows Server 2022)
Windows Defender Application Control (WDAC) policy updates for the HLH Operating System
Firmware updates for the Top-of-Rack (ToR) switches (S5248F-ON)
Firmware updates for the scale unit (SU) nodes
Driver updates for the scale unit nodes (Windows Server 2022)
Dell Integrated System for Microsoft Azure Stack Hub Lifecycle Manager overview
Dell Integrated System for Microsoft Azure Stack Hub Lifecycle Manager provides an automated way of upgrading HLH firmware, software, and driver components.
Lifecycle Manager will perform the following tasks:
Update firmware on the Hardware Lifecycle Host
Update drivers on the Hardware Lifecycle Host
Install Windows updates for the Hardware Lifecycle Host Operating System
Update the Windows Defender Application Control (WDAC) policy on the Hardware Lifecycle Host
NOTE
Firmware updates for the Top-of-Rack (ToR) switches are not included in the Lifecycle Manager update process and must be updated manually from the Hardware Lifecycle Host (HLH) using SCP and SSH commands. See the section Manually Updating the Switch Firmware from the Hardware Lifecycle Host (HLH) for more information.
Firmware and driver updates for scale unit (SU) nodes are not included in the Lifecycle Manager update process and must be updated manually using the Azure Stack Hub administrator portal. See the section OEM package updates for more information.
Lifecycle Manager should take between 1-2 hours to complete.
The Azure Stack Hub OEM package update contains firmware, device drivers, and hardware management tools in a specialized format used by Azure Stack Hub during initial deployment and update.
Dell Technologies is responsible for the end-to-end servicing lifecycle for the hardware-related firmware and driver update packages.
In addition, Dell Technologies will own and maintain guidance for all software and hardware on the HLH.
Perform the following steps before proceeding with the Lifecycle Manager update process. There are some steps which are a one-time-activity and some that you must perform in every release.
Download the Lifecycle Manager zip file
To download the latest Lifecycle Manager zip file, perform the following steps:
Log in to the HLH with the HLHAdmin default administrator account or a customer specified administrative user account.
The HLH can be accessed via Remote Desktop Protocol (RDP) from a Permitted Network or directly via the iDRAC Direct port (USB to Micro-USB) connection.
The Lifecycle Manager zip file version must match the version of the OEM package zip file, otherwise the Lifecycle Manager will not pass the pre-checks.
For example, if the Lifecycle Manager zip file is 2502, then the OEM package zip file must also be 2502.
Log in to the HLH with the HLHAdmin default administrator account or a customer specified administrative user account.
The HLH can be accessed via Remote Desktop Protocol (RDP) from a Permitted Network or directly via the iDRAC Direct port (USB to Micro-USB) connection.
Download the OEM package update zip file to the HLH E:\Temp directory.
Extract Lifecycle Manager and OEM package update zip files
Lifecycle Manager zip and OEM package update zip files that were downloaded to the HLH from the Dell support website will need to be extracted into their own directories.
To extract Lifecycle Manager and OEM package update zip files, perform the following steps:
Steps
Before beginning the extraction process, first the files in the E:\Temp directory will need to be unblocked. Open a PowerShell terminal as administrator and type the following command:
Lifecycle Manager zip file contents must be unblocked; otherwise, the Lifecycle Manager will not pass the pre-checks.
Once the contents within the E:\Temp directory have been unblocked, you can begin to extract the zip files into their directories.
On the HLH, navigate to the E:\ drive and create a folder named LCM.
On the HLH, navigate to the E:\ drive and create a folder named OEM.
Extract the Lifecycle Manager zip file from the E:\Temp directory to the E:\LCM directory.
Extract the OEM package update zip file from the E:\Temp directory to the E:\OEM directory.
Hardware Lifecycle Host (HLH)
Running Lifecycle Manager
NOTE
Lifecycle Manager will reboot the HLH multiple times during the upgrade process. You will need to log back into the HLH manually after each reboot; otherwise, the upgrade will not continue until you do.
As an optional step you can enable the Auto Logon feature on the HLH. This will allow the HLH to automatically log back in after each reboot.
To run Lifecycle Manager on the HLH, perform the following steps:
Steps
WARNING
Never use PowerShell ISE at any time during the use of this document.
From the HLH, open a PowerShell console window as an administrator.
You will need to export the BitLocker recovery keys before proceeding with the upgrade. Type the command below into your PowerShell prompt to export your BitLocker recovery keys.
You will be prompted to provide credentials for the following endpoints:
Hardware Lifecycle Host OS administrative account credential
iDRAC administrative account credential for the Hardware Lifecycle Host
You will then be prompted to confirm that you have backed up the BitLocker recovery keys. Press Y to confirm if you have backed up the BitLocker recovery keys; otherwise, press N to cancel the update process and back up your BitLocker recovery keys.
Once the update process begins, continue to monitor Lifecycle Manager while it runs. While the automation is running there will be multiple reboots, in order to keep the upgrade process progressing you must log back into the HLH manually; otherwise, the upgrade will not continue until you do.
Some updates are grouped together to limit the amount of reboots. The HLH may reboot for any of the following reasons:
Update Type
Reboot Type
Firmware updates
Separate reboot
Driver updates
Grouped reboot
Operating System updates
Grouped reboot
Windows Defender Application Control (WDAC) policy updates
Grouped reboot
Upon completion, the output should look similar to the image shown below. This shows a list of all completed tasks from Lifecycle Manager, as well as the total elapsed time of the upgrade.
If the upgrade was successful, you will see the Dell AzS Hub Lifecycle Manager completed successfully message in the output.
Finally, you can gather logs by navigating to the directory E:\LCM\Logs on the HLH. These logs can be used for troubleshooting purposes if needed.
Additionally, C:\MASLogs will contain logs related to the firmware update process.
Top-of-Rack (ToR) Switches
Manually Updating the Switch Firmware from the Hardware Lifecycle Host (HLH)
You must manually install the OS10 software image from the HLH using SCP and SSH commands.
WARNING
To maintain the integrity of Dell Azure Stack Hub Integrated System, it is required to perform the switch firmware update in conjunction with the Lifecycle Manager update process.
To update switch firmware, perform the following steps:
Steps
WARNING
Never use PowerShell ISE at any time during the use of this document.
From the HLH, open a PowerShell console window as an administrator.
The HLH can be accessed via Remote Desktop Protocol (RDP) from a Permitted Network.
Change directory to E:\OEM\AzS-Dell-<version>\Firmware\Switches\msftdell
Run the following command to copy the switch firmware from the extracted OEM package update zip file on the HLH to the ToR switches.
For example, if upgrading the firmware on ToR-1 with an IP address of 10.128.164.98 and a switch administrative user account of azsadmin-gtbzp, you would run the following:
For example, if upgrading the firmware on ToR-2 with an IP address of 10.128.164.99 and a switch administrative user account of azsadmin-gtbzp, you would run the following:
The below steps will be repeated on each ToR switch (e.g. ToR-1 and ToR-2) ONLY after fully completing the first switch (e.g. ToR-1).
Run the following commands to connect to the ToR switch.
For example, if upgrading the firmware on ToR-1 with an IP address of 10.128.164.98 and a switch administrative user account of azsadmin-gtbzp, you would run the following:
Enter the password of the switch administrative user account when prompted.
Run the following command to move the SCP copied firmware file to its intended destination (/var/os10-image):
system "sudo mv ./PKGS_OS10-Enterprise-<version>-installer-x86_64.bin /var/os10-image"
Enter the password of the switch administrative user account when prompted.
Verify the image is now located in the image directory.
dir image
The output should look similar to the below example:
Directory contents for folder:
Date (modified) Size (bytes) Name
--------------------- ------------ ------------------------------------------
2025-03-18T18:37:56+00:667040481 PKGS_OS10-Enterprise-<version>-installer-x86_64.bin
To verify that an installation is not already in progress, run the following command:
show image status
The output should look similar to the below example:
Image Upgrade State: idle
==================================================
File Transfer State: idle
--------------------------------------------------
State Detail: No download information available
Task Start: -001-11-30T00:00:00+00:00
Task End: -001-11-30T00:00:00+00:00
Transfer Progress: 0 %
Transfer Bytes: 0 bytes
File Size: 0 bytes
Transfer Rate: 0 kbps
Installation State: idle
--------------------------------------------------
State Detail: No install information available
Task Start: -001-11-30T00:00:00+00:00
Task End: -001-11-30T00:00:00+00:00
Run the following command to install the downloaded image to the standby partition:
To view the image install progress, run the following command:
show image status
The output should look similar to the below example:
Image Upgrade State: idle
==================================================
File Transfer State: idle
--------------------------------------------------
State Detail: No download information available
Task Start: 0000-00-00T00:00:00Z
Task End: 0000-00-00T00:00:00Z
Transfer Progress: 0 %
Transfer Bytes: 0 bytes
File Size: 0 bytes
Transfer Rate: 0 kbps
Installation State: install
--------------------------------------------------
State Detail: In progress: Configure filesystem (3 of 9)
Task Start: 2025-03-17T21:15:16Z
Task End: 0000-00-00T00:00:00Z
Keep checking until the image installation is complete. Then check to verify if the image is installed to the standby partition by running the following command:
show boot
The output should look similar to the below example:
Current system image information:
===================================
Type Boot Type Active Standby Next-Boot
-----------------------------------------------------------------------------------
Node-id 1 Flash Boot [B] 10.5.6.5 [A] 10.6.0.1 [B] active
Set the next boot partition to the standby partition where the downloaded image is installed by running the following command:
boot system standby
Save the currently running configuration and then reload to the configured image by running the following commands:
write memory
reload
After the switch reloads, copy the new active image to the standby boot partition by running the following command:
image copy active-to-standby
Verify the status of the BGP connections on the switches by running the following command:
show ip bgp summary
Verify that BGP is established for all neighbors as indicated by the Up/Down column showing a connection timer. The output should look similar to the below example:
Verify that the switch firmware version was updated by running the following command:
show version
The output should look similar to the below example:
Dell SmartFabric OS10 Enterprise
Copyright (c) 1999-2024 by Dell Inc. All Rights Reserved.
OS Version: 10.6.0.1
Build Version: 10.6.0.1.35
Build Time: 2024-12-02T17:55:39+0000
System Type: S5248F-ON
Architecture: x86_64
Up Time: 1 day 00:11:14
Original Equipment Manufacturer (OEM) package updates
Servicing Policy
Updates for the hardware components in the form of driver updates, firmware updates, and security patches are provided by Dell Technologies. These updates are referred to as OEM package updates. It is recommended to be within N-2 of the current available OEM package for Azure Stack Hub.
WARNING
Azure Stack Hub OEM package updates must be installed in sequential order.
It is not supported to skip an OEM package update version.
Identify the OEM version applied to the Azure Stack Hub
To identify the version of the Original Equipment Manufacturer (OEM) package currently applied to the Azure Stack Hub, perform the following steps:
Steps
Open the Azure Stack Hub administrator portal.
Open the Microsoft Azure Stack Hub - Administration Dashboard and click Dashboard.
Click Update.
The Updates blade will appear as shown below. The Updates blade displays your current Azure Stack Hub version and the latest deployed version of the OEM package update.
Import and Install an OEM package update
In this step you will be uploading and installing the OEM package update utilizing the Azure Stack Hub administrator portal.
CAUTION
Before you apply an OEM package update, always apply the latest Azure Stack Hub hotfix available for your Azure Stack Hub system.
For additional information about Azure Stack Hub updates, please see:
Access the Azure Stack Hub administrator portal of the system you wish to perform the OEM package update on.
Navigate to Storage accounts > updateadminaccount > Containers.
Create a container for the OEM package update by clicking +Container.
In the Name field on the right navigation pane enter the name for your container e.g. 2408oemupdate and then click Create.
Once the container is created, click the name of the container to access it.
Once you have clicked on the container click Upload at the top of the page.
Dell OEM package updates are in a zip format. The zip file contains the oemMetadata.xml file and the OEM package update payload.
You will need to upload both the zip file for the OEM package update and the oemMetadata.xml that is associated with it.
Once uploaded to the storage account container, they should appear in the container that was created in step 3.
Navigate back to the Dashboard and then click the Update tile.
The Updates blade should now show an available OEM package update that can be installed.
Click the update and then click Install to install the OEM package update.
After clicking install on the OEM package update, the update run details can be seen by clicking on the update in the Updates menu once the update has entered into a Preparing or Installing state.
Once completed, Updates blade should display Applied successfully and in the Update history menu the update state should be marked as Installed.
If the update fails, the Update blade reports Needs attention. Click on the failed update and use the Download summary button to get a high-level status of where the update failed.
5 - How To
5.1 - How to create a service principal name for Azure Stack Hub integrated with Active Directory Federation Services identity using PowerShell
Overview
This article explains how to create a service principal name (SPN) to manage Azure Stack Hub integrated with Active Directory Federation Services (AD FS) identity using PowerShell.
Overview of the creation process for Azure Stack Hub SPN
NOTE
The procedure provided is designed for Azure Stack Hub Operators as it requires Privileged Endpoint (PEP) access as well as assumes the Default Provider Subscription and the Administrator Azure Resource Manager endpoint as the defaults; however, the same mechanism can be applied to the User Subscriptions with minimal changes to the code.
If you want to assign a role the SPN for a User Subscription, replace the Administrator Azure Resource Manager endpoint with the Tenant Azure Resource Manager endpoint and the Default Provider Subscription with Subscription Name you want to modify.
Declare your variables accordingly.
Log in to your Azure Stack Hub Default Provider Subscription with administrator user credentials (needs to have the Owner role).
CAUTION
This requires interactive prompt as by default when using AD FS as your identity provider you cannot use user credentials in the non-interactive way.
This is the main reason why you would want to create an SPN so that you can automate your operations.
Create your AD FS application/service principal.
Assign the appropriate Role to your service principal.
NOTE
As a bonus, we include an example of how to assign the Owner role to an AD FS group
The current AzureStack modules do not support it natively, but this example will show you how to do it via API.
It is the preferred method of assigning roles, you should assign roles to a group rather than individual users.
Log in to your Azure Stack Hub Default Provider Subscription using the SPN account.
Verify SPN authentication and the role assignment.
Create Azure Stack Hub SPN
Create a PFX Certificate
#region Declare variables
$CertificateName = "ADFSAutomationCert"
$CertStore = "cert:\LocalMachine\My" # This can also be "cert:\CurrentUser\My" but in general service accounts cannot access CurrentUser cert store
$CertSubject = "CN=$CertificateName"
$PfxFilePath = "C:\Temp"
if (-not (Test-Path -Path $PfxFilePath)) {
New-Item -ItemType Directory -Path $PfxFilePath -Force | Out-Null
}
$PfxFilePathFull = Join-Path -Path $PfxFilePath -ChildPath "$($CertificateName).pfx"
$PfxPassword = '""' | ConvertTo-SecureString -AsPlainText -Force # replace "" with an actual password or leave "" for it to be blank
#endregion
#region Create certificate to pass into new Application
$ExpiryDate = (Get-Date).AddDays(365) # You can change this to whatever fits your security profile better, default is 1 year
$Cert = New-SelfSignedCertificate -CertStoreLocation $CertStore -Subject $CertSubject -KeySpec KeyExchange -NotAfter $ExpiryDate
Write-Verbose -Message "Certificate ""$($Cert.Subject)"" with start date ""$($Cert.NotBefore)"" and end date ""$($Cert.NotAfter)"" created at ""$($PfxFilePathFull)""."
#endregion
#region Get a cert object from a .pfx file - you need it to create the SPN to begin with
$Cert = Get-PfxCertificate -FilePath $PfxFilePathFull -Password $PfxPassword
#endregion
#region Optional steps
#region Export the certificate so that you can import it on other environments
try {
Export-PfxCertificate -Cert $Cert.PsPath -FilePath $PfxFilePathFull -Password $PfxPassword -ErrorAction Stop | Out-Null
} catch {
throw "Failed to export certificate to ""$($PfxFilePathFull)"":`n$($_.Exception.Message)"
}
#endregion
#region Import the certificate into the certificate store on another environment
Import-PfxCertificate -CertStoreLocation $CertStore -FilePath $PfxFilePathFull -Password $PfxPassword -Exportable
#endregion
#endregion
Create Azure Stack Hub SPN that uses certificate credential
#region Declare variables
$CertificateName = "ADFSAutomationCert"
$PfxFilePath = "C:\Temp"
$PfxFilePathFull = Join-Path -Path $PfxFilePath -ChildPath "$($CertificateName).pfx"
$PfxPassword = '""' | ConvertTo-SecureString -AsPlainText -Force
$CertificateObject = Get-PfxCertificate -FilePath $PfxFilePathFull -Password $PfxPassword
$CertificateThumbprint = $CertificateObject.Thumbprint
if (!$CertificateThumbprint) {
throw "Failed to obtain a thumbprint from certificate: $($PfxFilePathFull)"
}
$CloudAdminUsername = "CloudAdmin@azurestack.local"
[SecureString]$CloudAdminPassword = ConvertTo-SecureString "Password123!" -AsPlainText -Force
$ApplicationName = "ADFSAppCert"
$AzureStackRole = "Owner"
$ADGroupName = "AzureStackHubOwners"
$AzureStackAdminArmEndpoint = "https://adminmanagement.local.azurestack.external/"
$EnvironmentName = "AzureStackAdmin"
$PepCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $CloudAdminUsername, $CloudAdminPassword
$PepIPAddress = "x.x.x.224" # e.g. 10.5.30.224
#endregion
#region Register and set an Az environment that targets your Azure Stack Hub instance
Write-Output -InputObject "Connecting to Azure Stack Hub Admin Management Endpoint - $(AzureStackAdminArmEndpoint)"
$null = Add-AzEnvironment -Name $EnvironmentName -ARMEndpoint $AzureStackAdminArmEndpoint
$null = Connect-AzAccount -Environment $EnvironmentName -UseDeviceAuthentication # Interactive prompt
if (((Get-AzContext).Subscription).Name -notlike "Default Provider Subscription") {
throw "Failed to obtain access to the 'Default Provider Subscription'. Please verify the user has been assigned the '$($AzureStackRole)' role for the 'Default Provider Subscription'."
}
#endregion
#region Create a PSSession to the Privileged Endpoint VM
Write-Output -InputObject "Create a PowerShell Session to the Privileged Endpoint VM"
$PepSession = New-PSSession -ComputerName $PepIPAddress -ConfigurationName PrivilegedEndpoint -Credential $PepCreds -SessionOption (New-PSSessionOption -Culture en-US -UICulture en-US)
#endregion
#region Check for existing SPN
Write-Output -InputObject "Check for existing SPN '$($ApplicationName)'"
$SPNObjectCheckJob = Invoke-Command -Session $PepSession -ScriptBlock { Get-GraphApplication } -AsJob | Wait-Job
if ($SPNObjectCheckJob.State -ne "Completed") {
throw "$($SPNObjectCheckJob.ChildJobs | Receive-Job)"
}
$SPNObjectCheck = $SPNObjectCheckJob.ChildJobs.Output | Where-Object { $_.Name -like "Azurestack-$ApplicationName*" } | Select-Object -Last 1
#endregion
#region Create new SPN if one does not exist
if ($SPNObjectCheck) {
Write-Output -InputObject "SPN details`n$($ApplicationName): $($SPNObjectCheck | Out-String)"
} else {
Write-Output -InputObject "No existing SPN found"
Write-Output -InputObject "Create new SPN '$($ApplicationName)'"
$SPNObjectJob = Invoke-Command -Session $PepSession -ScriptBlock { New-GraphApplication -Name $using:ApplicationName -ClientCertificates $using:CertificateObject } -AsJob | Wait-Job
if ($SPNObjectJob.State -ne "Completed") {
throw "$($SPNObjectJob.ChildJobs | Receive-Job)"
}
$SPNObject = $SPNObjectJob.ChildJobs.Output
Write-Output -InputObject "SPN details`n$($ApplicationName): $($SPNObject | Out-String)"
$FullApplicationName = $SPNObject.ApplicationName
#endregion
}
#region Assign SPN the 'Owner' role for the 'Default Provider Subscription'
Write-Output -InputObject "Assign SPN '$($ApplicationName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
if ($FullApplicationName) {
$SPNADFSApp = Get-AzADServicePrincipal | Where-Object { $_.DisplayName -like "$($FullApplicationName)" }
} else {
$SPNADFSApp = Get-AzADServicePrincipal | Where-Object { $_.DisplayName -like "*$($ApplicationName)*" } | Select-Object -Last 1
}
$SPNRoleAssignmentCheck = Get-AzRoleAssignment -ObjectId $SPNADFSApp.AdfsId
if (!($SPNRoleAssignmentCheck) -or ($SPNRoleAssignmentCheck.RoleDefinitionName -ne $AzureStackRole)) {
$null = New-AzRoleAssignment -RoleDefinitionName $AzureStackRole -ServicePrincipalName $SPNADFSApp.ApplicationId.Guid
#region Verify SPN has been assigned the 'Owner' role for the 'Default Provider Subscription'
$SPNRoleAssignment = Get-AzRoleAssignment -ObjectId $SPNADFSApp.AdfsId
if (!($SPNRoleAssignment) -or ($SPNRoleAssignment.RoleDefinitionName -ne $AzureStackRole)) {
throw "Failed to assign SPN '$($ApplicationName)' the '$($AzureStackRole)' role for the Default Provider Subscription"
}
#endregion
}
#endregion
#region Assign AD group 'AzureStackOwners' the 'Owner' role for the 'Default Provider Subscription'
Write-Output -InputObject "Assign AD group '$($ADGroupName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
$ADGroup = Get-AzADGroup -DisplayNameStartsWith $ADGroupName
$SubId = (Get-AzSubscription -SubscriptionName "Default Provider Subscription").Id
$OwnerRoleId = (Get-AzRoleDefinition -Name $AzureStackRole).Id
$APIPayloadHash = @{
"properties" = @{
"roleDefinitionId" = "/subscriptions/$($SubId)/providers/Microsoft.Authorization/roleDefinitions/$($OwnerRoleId)"
"principalId" = "$($ADGroup.AdfsId)"
}
} | ConvertTo-Json -Depth 50
$APIPath = "/subscriptions/$($SubId)/providers/Microsoft.Authorization/roleAssignments/$($OwnerRoleId)?api-version=2015-07-01"
$APIResponse = Invoke-AzRestMethod -Path $APIPath -Method "PUT" -Payload $APIPayloadHash
if ($APIResponse.StatusCode -ne "201") {
throw "Failed to create role assignment for ""$($ADGroup.DisplayName)"" in subscription ""$($SubId)"" with role ""$($AzureStackRole)"" and role ID ""$($OwnerRoleId)"""
}
#endregion
#region Verify AD group 'AzureStackOwners' has been assigned the 'Owner' role for the 'Default Provider Subscription'
$ADGroupRoleAssignment = Get-AzRoleAssignment -ObjectId $ADGroup.AdfsId
if (!($ADGroupRoleAssignment) -or ($ADGroupRoleAssignment.RoleDefinitionName -ne $AzureStackRole)) {
throw "Failed to assign AD group '$($ADGroupName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
}
#endregion
#region Obtain authentication information
# GUID of the directory tenant
$TenantId = (Get-AzContext).Tenant.Id
Write-Output -InputObject "TenantId: $($TenantId)"
Write-Output -InputObject ""
Write-Output -InputObject "ApplicationName: $($SPNADFSApp.DisplayName)"
Write-Output -InputObject ""
Write-Output -InputObject "ApplicationId: $($SPNADFSApp.ApplicationId.Guid)"
Write-Output -InputObject ""
Write-Output -InputObject "CertificateThumbprint: $($CertificateThumbprint)"
Write-Output -InputObject ""
Write-Output -InputObject "Admin ARM Endpoint: $($AzureStackAdminArmEndpoint)"
#endregion
#region Verify if SPN can authenticate to Azure Stack Hub Admin Management Endpoint
Write-Output -InputObject "Verify if SPN can authenticate to Azure Stack Hub Admin Management Endpoint"
$null = Clear-AzContext -Force
$null = Connect-AzAccount -Environment $EnvironmentName -ServicePrincipal -Tenant $TenantId -ApplicationId $SPNADFSApp.ApplicationId.Guid -CertificateThumbprint $CertificateThumbprint
if (((Get-AzContext).Subscription).Name -notlike "Default Provider Subscription") {
throw "Failed to obtain access to the 'Default Provider Subscription'. Please verify the SPN has been assigned the '$($AzureStackRole)' role for the 'Default Provider Subscription'."
} else {
Write-Output -InputObject "Your SPN can successfully authenticate with ARM Endpoint $($AzureStackAdminArmEndpoint) and has got access to the 'Default Provider Subscription'"
}
#endregion
#region Remove sessions
if ($PepSession) {
Write-Output -InputObject "Removing PSSSession to the Privileged Endpoint"
Remove-PSSession -Session $PepSession
}
$CheckContext = Get-AzContext | Where-Object { $_.Environment -like $EnvironmentName }
if ($CheckContext) {
Write-Output -InputObject "Disconnecting from AzS Hub Admin Management Endpoint: $($CheckContext.Environment.ResourceManagerUrl)"
$null = Disconnect-AzAccount
}
#endregion
CAUTION
Using a client secret is less secure than using an X509 certificate credential. Not only is the authentication mechanism less secure, but it also typically requires embedding the secret in the client app source code. As such, for production apps, you’re strongly encouraged to use a certificate credential.
#region Declare variables
$CloudAdminUsername = "CloudAdmin@azurestack.local"
[SecureString]$CloudAdminPassword = ConvertTo-SecureString "Password123!" -AsPlainText -Force
$ApplicationName = "ADFSAppCert"
$AzureStackRole = "Owner"
$ADGroupName = "AzureStackHubOwners"
$AzureStackAdminArmEndpoint = "https://adminmanagement.local.azurestack.external/"
$EnvironmentName = "AzureStackAdmin"
$PepCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $CloudAdminUsername, $CloudAdminPassword
$PepIPAddress = "x.x.x.224" # e.g. 10.5.30.224
#endregion
#region Register and set an Az environment that targets your Azure Stack Hub instance
Write-Output -InputObject "Connecting to Azure Stack Hub Admin Management Endpoint - $(AzureStackAdminArmEndpoint)"
$null = Add-AzEnvironment -Name $EnvironmentName -ARMEndpoint $AzureStackAdminArmEndpoint
$null = Connect-AzAccount -Environment $EnvironmentName -UseDeviceAuthentication # Interactive prompt
if (((Get-AzContext).Subscription).Name -notlike "Default Provider Subscription") {
throw "Failed to obtain access to the 'Default Provider Subscription'. Please verify the user has been assigned the '$($AzureStackRole)' role for the 'Default Provider Subscription'."
}
#endregion
#region Create a PSSession to the Privileged Endpoint VM
Write-Output -InputObject "Create a PowerShell Session to the Privileged Endpoint VM"
$PepSession = New-PSSession -ComputerName $PepIPAddress -ConfigurationName PrivilegedEndpoint -Credential $PepCreds -SessionOption (New-PSSessionOption -Culture en-US -UICulture en-US)
#endregion
#region Check for existing SPN
Write-Output -InputObject "Check for existing SPN '$($ApplicationName)'"
$SPNObjectCheckJob = Invoke-Command -Session $PepSession -ScriptBlock { Get-GraphApplication } -AsJob | Wait-Job
if ($SPNObjectCheckJob.State -ne "Completed") {
throw "$($SPNObjectCheckJob.ChildJobs | Receive-Job)"
}
$SPNObjectCheck = $SPNObjectCheckJob.ChildJobs.Output | Where-Object { $_.Name -like "Azurestack-$ApplicationName*" } | Select-Object -Last 1
#endregion
#region Create new SPN if one does not exist
if ($SPNObjectCheck) {
Write-Output -InputObject "SPN details`n$($ApplicationName): $($SPNObjectCheck | Out-String)"
} else {
Write-Output -InputObject "No existing SPN found"
Write-Output -InputObject "Create new SPN '$($ApplicationName)'"
$SPNObjectJob = Invoke-Command -Session $PepSession -ScriptBlock { New-GraphApplication -Name $using:ApplicationName -GenerateClientSecret } -AsJob | Wait-Job
if ($SPNObjectJob.State -ne "Completed") {
throw "$($SPNObjectJob.ChildJobs | Receive-Job)"
}
$SPNObject = $SPNObjectJob.ChildJobs.Output
Write-Output -InputObject "SPN details`n$($ApplicationName): $($SPNObject | Out-String)"
$FullApplicationName = $SPNObject.ApplicationName
$SPNClientId = $SPNObject.ClientId
$SPNClientSecret = $SPNObject.ClientSecret | ConvertTo-SecureString -AsPlainText -Force
$SPNCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SPNClientId, $SPNClientSecret
#endregion
}
#region Assign SPN the 'Owner' role for the 'Default Provider Subscription'
Write-Output -InputObject "Assign SPN '$($ApplicationName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
if ($FullApplicationName) {
$SPNADFSApp = Get-AzADServicePrincipal | Where-Object { $_.DisplayName -like "$($FullApplicationName)" }
} else {
$SPNADFSApp = Get-AzADServicePrincipal | Where-Object { $_.DisplayName -like "*$($ApplicationName)*" } | Select-Object -Last 1
}
$SPNRoleAssignmentCheck = Get-AzRoleAssignment -ObjectId $SPNADFSApp.AdfsId
if (!($SPNRoleAssignmentCheck) -or ($SPNRoleAssignmentCheck.RoleDefinitionName -ne $AzureStackRole)) {
$null = New-AzRoleAssignment -RoleDefinitionName $AzureStackRole -ServicePrincipalName $SPNADFSApp.ApplicationId.Guid
#region Verify SPN has been assigned the 'Owner' role for the 'Default Provider Subscription'
$SPNRoleAssignment = Get-AzRoleAssignment -ObjectId $SPNADFSApp.AdfsId
if (!($SPNRoleAssignment) -or ($SPNRoleAssignment.RoleDefinitionName -ne $AzureStackRole)) {
throw "Failed to assign SPN '$($ApplicationName)' the '$($AzureStackRole)' role for the Default Provider Subscription"
}
#endregion
}
#endregion
#region Assign AD group 'AzureStackOwners' the 'Owner' role for the 'Default Provider Subscription'
Write-Output -InputObject "Assign AD group '$($ADGroupName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
$ADGroup = Get-AzADGroup -DisplayNameStartsWith $ADGroupName
$SubId = (Get-AzSubscription -SubscriptionName "Default Provider Subscription").Id
$OwnerRoleId = (Get-AzRoleDefinition -Name $AzureStackRole).Id
$APIPayloadHash = @{
"properties" = @{
"roleDefinitionId" = "/subscriptions/$($SubId)/providers/Microsoft.Authorization/roleDefinitions/$($OwnerRoleId)"
"principalId" = "$($ADGroup.AdfsId)"
}
} | ConvertTo-Json -Depth 50
$APIPath = "/subscriptions/$($SubId)/providers/Microsoft.Authorization/roleAssignments/$($OwnerRoleId)?api-version=2015-07-01"
$APIResponse = Invoke-AzRestMethod -Path $APIPath -Method "PUT" -Payload $APIPayloadHash
if ($APIResponse.StatusCode -ne "201") {
throw "Failed to create role assignment for ""$($ADGroup.DisplayName)"" in subscription ""$($SubId)"" with role ""$($AzureStackRole)"" and role ID ""$($OwnerRoleId)"""
}
#endregion
#region Verify AD group 'AzureStackOwners' has been assigned the 'Owner' role for the 'Default Provider Subscription'
$ADGroupRoleAssignment = Get-AzRoleAssignment -ObjectId $ADGroup.AdfsId
if (!($ADGroupRoleAssignment) -or ($ADGroupRoleAssignment.RoleDefinitionName -ne $AzureStackRole)) {
throw "Failed to assign AD group '$($ADGroupName)' the '$($AzureStackRole)' role for the 'Default Provider Subscription'"
}
#endregion
#region Obtain authentication information
# GUID of the directory tenant
$TenantId = (Get-AzContext).Tenant.Id
Write-Output -InputObject "TenantId: $($TenantId)"
Write-Output -InputObject ""
Write-Output -InputObject "ApplicationName: $($SPNADFSApp.DisplayName)"
Write-Output -InputObject ""
Write-Output -InputObject "ApplicationId: $($SPNADFSApp.ApplicationId.Guid)"
Write-Output -InputObject ""
Write-Output -InputObject "ClientSecret: $($SPNObject.ClientSecret)"
Write-Output -InputObject ""
Write-Output -InputObject "Admin ARM Endpoint: $($AzureStackAdminArmEndpoint)"
#endregion
#region Verify if SPN can authenticate to Azure Stack Hub Admin Management Endpoint
Write-Output -InputObject "Verify if SPN can authenticate to Azure Stack Hub Admin Management Endpoint"
$null = Clear-AzContext -Force
$null = Connect-AzAccount -Environment $EnvironmentName -ServicePrincipal -Tenant $TenantId -Credential $SPNCreds
if (((Get-AzContext).Subscription).Name -notlike "Default Provider Subscription") {
throw "Failed to obtain access to the 'Default Provider Subscription'. Please verify the SPN has been assigned the '$($AzureStackRole)' role for the 'Default Provider Subscription'."
} else {
Write-Output -InputObject "Your SPN can successfully authenticate with ARM Endpoint $($AzureStackAdminArmEndpoint) and has got access to the 'Default Provider Subscription'"
}
#endregion
#region Remove sessions
if ($PepSession) {
Write-Output -InputObject "Removing PSSSession to the Privileged Endpoint"
Remove-PSSession -Session $PepSession
}
$CheckContext = Get-AzContext | Where-Object { $_.Environment -like $EnvironmentName }
if ($CheckContext) {
Write-Output -InputObject "Disconnecting from AzS Hub Admin Management Endpoint: $($CheckContext.Environment.ResourceManagerUrl)"
$null = Disconnect-AzAccount
}
#endregion