☁️
OSDCloud.com
OSDeploy.comTwitter
  • About
  • Contributors
    • Damien Van Robaeys | MVP
    • Ákos Bakos
    • David Segura | MVP
    • Gary Blok
    • Jérôme Bezet-Torres | MVP
  • OSDCloud
    • Local Setup
      • OSDCloud Template
        • Build Process
        • Logs
        • Named Templates
        • WinRE WiFi
        • Public Content
        • Languages
        • Cumulative Updates
        • ISO Boot Media
        • Universal WinPE
      • OSDCloud Workspace
        • Get-OSDCloudWorkspace
        • Set-OSDCloudWorkspace
        • New-OSDCloudWorkspace
          • Restore from ISO
          • Restore from ISO URL
          • Restore from USB
        • Update-OSDCloudWorkspace
        • Configuration Files
      • OSDCloud WinPE
        • Default Wallpaper
        • Wallpaper
        • Drivers
        • PSModule
        • Startup
      • OSDCloud ISO
      • OSDCloud USB
        • New-OSDCloudUSB
        • Update-OSDCloudUSB
        • USB Drives
        • Secure USB Drives
      • 🚧OSDCloud VM
        • Get-OSDCloudVMDefaults
        • Get-OSDCloudVMSettings
        • Set-OSDCloudVMSettings
        • Reset-OSDCloudVMSettings
        • New-OSDCloudVM
    • Deployment
      • WinPE
        • Start-OSDCloud
          • OS Parameters
          • ZTI
        • Start-OSDCloudGUI
          • Parameters
          • Defaults
          • Global Variable
          • Customize
        • Start-OSDCloud Wrapping
      • First Boot
      • OOBE
      • Windows
  • Sandbox
    • OSDCloud
      • sandbox.osdcloud.com
      • WinPE Usage
      • OOBE Usage
      • Functions
    • OSDCloud Azure
      • az.osdcloud.com
    • WinPE Downloads
  • OSDCloud Automate
    • 🆕Basic Configuration
    • 🆕OSDCloudGUI Defaults
    • 🆕Autopilot
    • 🆕Provisioning
      • 🆕Windows Configuration Designer
      • 🆕MSI Application PPKG
      • 🆕Bulk Enroll PPKG
      • 🆕PowerShell Script PPKG
    • 🚧Scripts
  • OSDCloud Azure
    • Azure Setup
      • Azure Portal
        • Storage Accounts
        • Storage Containers
          • BootImage
          • DriverPack
        • Storage Access Control (IAM)
      • Infrastructure As Code
        • Prerequisites
        • Technicien
        • Workspace
        • Bicep
        • Terraform
        • Configure Azure
    • Deployment
      • Testing
      • OSDCloudRE Azure
    • Deep Dive
      • Cloud Functions and Scripts
      • Connect Azure in WinPE
      • Azure Tags
      • Log Files
  • Offline Deployment
    • ISO: Adding a WIM
  • Integration
    • ADK: Use the OSDCloud Boot.wim
    • MDT: Use the OSDCloud Boot.wim
    • MDT: Add OSDCloud WinPE Drivers
    • MDT: Use OSDCloud DriverPacks in a Task Sequence
    • OSDCloud IPU
      • Windows In-place Upgrades
      • Windows Media Download
  • Archive
    • 💡Tips
      • 🆕Media Cleanup
      • Firmware Update
      • Quick Setup
    • 🌎Community
      • OSDCloud: The ZTI Way
      • OSDCloud - Image devices without need of infrastructure
      • Trying out Windows 10 Deployment with OSDCloud
      • Deploying Windows 10 to bare metal devices with just WinPE & internet
    • 💔Under Review
      • ISO
      • WIM
    • 🪦Recycle Bin
      • Release Notes
      • Enable-OSDCloudODT
      • Deploy
        • OOBE Phase
      • Guides
        • OSDCloud WIM
        • Custom OSDCloud
        • AutoPilot
          • AutoPilot Configuration File
          • AutoPilot in Audit Mode
          • AutoPilot in OOBE
        • WiFi
      • OOBE
        • Start-OOBE.settings
        • Start-OOBE.wifi
        • Start-OOBE.autopilot
      • Concepts
        • K.I.S.S.
        • OSD Disks Logically
        • Office365 Specialize
        • Specialize DriverPacks
        • Model Reference Image
        • MDT OSDCloud DriverPacks
        • MDT DriverPacks
      • Blob SAS URL
      • Storage Containers (Public)
Powered by GitBook
On this page
  • Connect-AzOSDCloud
  • Required PowerShell Modules
  • Connect-AzAccount (Az.Accounts)
  • -UseDeviceAuthentication
  • -Authscope Storage
  • Subscription
  • Connected to Azure (Subscription)
  • Access Tokens and Headers
  • AzureAD
  • Summary
  • Sponsor

Was this helpful?

Export as PDF
  1. OSDCloud Azure
  2. Deep Dive

Connect Azure in WinPE

David Segura

Connect-AzOSDCloud

This is an OSDCloud function that is used in WinPE to authenticate to Azure using Device Code flow. I'll explain in detail how this works

I sorted all this out while at the MMSMOA 2022 Conference on Day 2, essentially making the OSDCloud Azure session on Day 1 obsolete as SAS Tokens and Key Vault are no longer needed

Required PowerShell Modules

The following Modules are installed or updated when executing this function. This may cause an execution delay depending on the internet connection to the PSGallery Repository

Connect-AzAccount (Az.Accounts)

This is the function used to authenticate to Azure from WinPE

Connect-AzAccount -UseDeviceAuthentication -AuthScope Storage -ErrorAction Stop

-UseDeviceAuthentication

This parameter forces the authentication to occur on a separate device. This can be another computer, a smartphone, or even by a third party by providing them with the code (think Help Desk). The reason this is done is that the standard authentication does not work in WinPE

-Authscope Storage

If this parameter is left out, another Authentication may be required later, so since we know that we must access Azure Storage, we might as well do this now

Subscription

Once you have been authenticated to Azure AD, this Azure Subscription routine is run. By default, Azure will pretty much randomly select the Azure Subscription that is used, which may not be the one you need to use for OSDCloud. This routine will determine if you have more than one Subscription and then prompt you to select the proper Subscription

$Global:AzSubscription = Get-AzSubscription

if (($Global:AzSubscription).Count -ge 2) {
    $i = $null
    $Results = foreach ($Item in $Global:AzSubscription) {
        $i++

        $ObjectProperties = @{
            Number  = $i
            Name    = $Item.Name
            Id      = $Item.Id
        }
        New-Object -TypeName PSObject -Property $ObjectProperties
    }

    $Results | Select-Object -Property Number, Name, Id | Format-Table | Out-Host

    do {
        $SelectReadHost = Read-Host -Prompt "Select an Azure Subscription by Number"
    }
    until (((($SelectReadHost -ge 0) -and ($SelectReadHost -in $Results.Number))))

    $Results = $Results | Where-Object {$_.Number -eq $SelectReadHost}

    $Global:AzContext = Set-AzContext -Subscription $Results.Id
}
else {
    $Global:AzContext = Get-AzContext
}

Additionally the following Global Variables are created for this PowerShell session

$Global:AzSubscription = Get-AzSubscription
$Global:AzContext = Get-AzContext

Connected to Azure (Subscription)

Once you have successfully connected to Azure (by way of having an Azure Context), the following informational routine will take place. This will primarily set some more Global Variables so you can easily access them

If there is a failure in this routine, it is because the value for your Azure Subscription will be empty. This typically means that you do not have access to any Azure Resources. Go back to OSDCloud Azure Setup and give your user access to Azure Storage and this will sort itself out. If you ping me and ask about this error, I will simply ignore it. It's documented here, and in the Warning message. there is no need for a third opinion.

Write-Host -ForegroundColor Green 'Connected to Azure'
Write-Host -ForegroundColor DarkGray "========================================================================="
$Global:AzAccount = $Global:AzContext.Account
$Global:AzEnvironment = $Global:AzContext.Environment
$Global:AzTenantId = $Global:AzContext.Tenant
$Global:AzSubscription = $Global:AzContext.Subscription

Write-Host -ForegroundColor Cyan        '$Global:AzAccount:        ' $Global:AzAccount
Write-Host -ForegroundColor Cyan        '$Global:AzEnvironment:    ' $Global:AzEnvironment
Write-Host -ForegroundColor Cyan        '$Global:AzTenantId:       ' $Global:AzTenantId
Write-Host -ForegroundColor Cyan        '$Global:AzSubscription:   ' $Global:AzSubscription
if ($null -eq $Global:AzContext.Subscription) {
    Write-Warning 'You do not have access to an Azure Subscriptions'
    Write-Warning 'This is likely due to not having rights to Azure Resources or Azure Storage'
    Write-Warning 'Contact your Azure administrator to resolve this issue'
    Break
}
Write-Host -ForegroundColor DarkGray    'Azure Context:             $Global:AzContext'

Access Tokens and Headers

This is probably the most fun you will see while reading this. Since we are authenticated to Azure, this routine will automatically get the Azure Access Tokens and create Headers automatically as Global Variables. These can be used for HTTP RestMethod requests (which will be released later)

Write-Host -ForegroundColor DarkGray    'Access Tokens:             $Global:Az*AccessToken'
Write-Host -ForegroundColor DarkGray    'Headers:                   $Global:Az*Headers'
Write-Host ''
#=================================================
#	AAD Graph
#=================================================
$Global:AzAadGraphAccessToken = Get-AzAccessToken -ResourceTypeName AadGraph
$Global:AzAadGraphHeaders = @{
    'Authorization' = 'Bearer ' + $Global:AzAadGraphAccessToken.Token
    'Content-Type'  = 'application/json'
    'ExpiresOn'     = $Global:AzAadGraphAccessToken.ExpiresOn
}
#=================================================
#	Azure KeyVault
#=================================================
$Global:AzKeyVaultAccessToken = Get-AzAccessToken -ResourceTypeName KeyVault
$Global:AzKeyVaultHeaders = @{
    'Authorization' = 'Bearer ' + $Global:AzKeyVaultAccessToken.Token
    'Content-Type'  = 'application/json'
    'ExpiresOn'     = $Global:AzKeyVaultAccessToken.ExpiresOn
}
#=================================================
#	Azure MSGraph
#=================================================
$Global:AzMSGraphAccessToken = Get-AzAccessToken -ResourceTypeName MSGraph
$Global:AzMSGraphHeaders = @{
    'Authorization' = 'Bearer ' + $Global:AzMSGraphAccessToken.Token
    'Content-Type'  = 'application/json'
    'ExpiresOn'     = $Global:AzMSGraphHeaders.ExpiresOn
}
#=================================================
#	Azure Storage
#=================================================
$Global:AzStorageAccessToken = Get-AzAccessToken -ResourceTypeName Storage
$Global:AzStorageHeaders = @{
    'Authorization' = 'Bearer ' + $Global:AzStorageAccessToken.Token
    'Content-Type'  = 'application/json'
    'ExpiresOn'     = $Global:AzStorageHeaders.ExpiresOn
}

AzureAD

Finally, AzureAD will be connected using the AAD Access Token

#=================================================
#	AzureAD
#=================================================
$Global:AzureAD = Connect-AzureAD -AadAccessToken $Global:AzAadGraphAccessToken.Token -AccountId $Global:AzContext.Account.Id

Summary

Hopefully this gives you some insight on how the connection to Azure is done in WinPE. There are lots of moving parts, but it should support connecting to more than just Azure Storage

Sponsor

PreviousCloud Functions and ScriptsNextAzure Tags

Last updated 3 years ago

Was this helpful?

LogoHomeRecast Software
OSDeploy is sponsored by Recast Software
LogoConnect-AzAccount (Az.Accounts)docsmsft
LogoAuthentication flow support in the Microsoft Authentication Library (MSAL) - Microsoft identity platformdocsmsft