Public Key-Infrastruktur (PKI) für getrennte Vorgänge in Azure Local

In diesem Artikel werden die Anforderungen der Public Key-Infrastruktur (PKI) für getrennte Vorgänge in Azure Local erläutert. Sie erfahren, wie Sie Zertifikate zum Sichern von Appliance-Endpunkten erstellen und die sichere Kommunikation in Ihrer Umgebung sicherstellen.

PKI-Übersicht über getrennte Vorgänge

PKI für abgekoppelte Operationen ist unerlässlich für die Sicherung der Endpunkte, die das abgekoppelte Operationsgerät bereitstellt. Erstellen und verwalten Sie digitale Zertifikate, um eine sichere Kommunikation und Datenübertragung in Ihrer lokalen Azure-Umgebung sicherzustellen.

PKI-Anforderungen

Zertifikate müssen von einer öffentlichen Zertifizierungsstelle (CA) oder einer Unternehmenszertifizierungsstelle stammen. Stellen Sie sicher, dass Ihre Zertifikate Teil des Microsoft Trusted Root Program sind. Weitere Informationen finden Sie unter "Teilnehmerliste – Microsoft Trusted Root Program".

Gruppieren Sie verpflichtende Zertifikate nach Themenbereich mit dem entsprechenden Subject Alternative Name (SAN). Bevor Sie die Zertifikate erstellen, überprüfen Sie die folgenden Anforderungen:

  • Die Verwendung von selbstsignierten Zertifikaten wird nicht unterstützt. Es wird empfohlen, von einer Unternehmenszertifizierungsstelle ausgestellte Zertifikate zu verwenden.
  • Bei getrennten Vorgängen sind 23 externe Zertifikate für die verfügbaren Endpunkte erforderlich.
  • Generieren Sie einzelne Zertifikate für jeden Endpunkt, und kopieren Sie sie in die entsprechende Verzeichnis- oder Ordnerstruktur. Diese Zertifikate sind für die Bereitstellung getrennter Vorgänge erforderlich.
  • Definieren Sie den Betreff und SAN für alle Zertifikate, wie für die meisten Browser erforderlich.
  • Alle Zertifikate sollten dieselbe Vertrauenskette nutzen und ab dem Tag der Bereitstellung mindestens eine Gültigkeitsdauer von zwei Jahren haben.
  • Exportieren Sie alle Stammzertifikate im Base64-codierten Format. Die resultierende Datei weist in der Regel die Erweiterung .cer, CRT oder PEM auf.
  • Für vollständig getrennte Bereitstellungen:
    • Verwenden Sie eine private oder interne Zertifizierungsstelle (CA).
    • Es ist nur interner Netzwerkzugriff auf den Zertifikatsperrlistenendpunkt (Certificate Revocation List, CRL) erforderlich.
    • Die Internetverbindung ist nicht erforderlich.
    • Stellen Sie sicher, dass die Infrastruktur für getrennte Vorgänge den CRL-Endpunkt erreichen kann, der im CRL-Verteilungspunkt (CRL Distribution Point, CDP) der Zertifikate angegeben ist.
    • Verwenden Sie das Skript im Anhang, um Ihre CRL-Endpunkte zu überprüfen, wenn Sie nicht sicher sind, ob Das Setup korrekt ist.
    • Verwenden Sie keine öffentliche oder externe Zertifizierungsstelle. Bereitstellungen schlagen fehl, wenn Zertifikate von einer öffentlichen Zertifizierungsstelle stammen, da für den Zugriff auf die CRL- und OCSP-Dienste (Online Certificate Status Protocol) für HTTPS eine Internetverbindung erforderlich ist.

Ingress-Endpunktzertifikatsanforderungen

In dieser Tabelle sind die obligatorischen Zertifikate aufgeführt, die für getrennte Vorgänge in Azure Local erforderlich sind.

Dienstleistung Erforderlicher Zertifikatsbetreff und alternativer Antragstellername (SAN)
Azure Blob-Speicher *.blob.fqdn
Azure Container Registry (Registrierungsdienst für Container von Azure) *.edgeacr.fqdn
Azure-Warteschlangenspeicher *.queue.fqdn
Azure-Servicebus *.servicebus.fqdn
Azure-Tabellenspeicher *.table.fqdn
Azure Key Vault (ein Dienst zur sicheren Verwaltung kryptografischer Schlüssel) *.vault.fqdn
Administrationsverwaltung adminmanagement.fqdn
Arc for Server-Agent-Datenservice agentserviceapi.fqdn
Arc Monitor Agent amcs.monitoring.fqdn
Arc-Konfigurationsdatenebene

Azure Arc-fähige Kubernetes
arckubernetesconfig.fqdn
Azure Resource Manager armmanagement.fqdn

management.fqdn
Apis für öffentliche Portalkataloge catalogapi.fqdn
Azure-Datenrichtlinie data.policy.fqdn
Azure Arc-Ressourcenbrücke – Datenebene dp.appliances.fqdn
Lizenzierung dp.aszrp.fqdn
Front-End-Geräte frontend.appliances.fqdn
Graph graph.fqdn
Arc-Gastbenachrichtigungsdienst guestnotificationservice.fqdn
Arc für Server his.fqdn
Öffentliches Portalhosting hosting.fqdn
Sicherer Tokendienst login.fqdn
Arc-Metriken metricsingestiongateway.monitoring.fqdn
Öffentliches Portal portal.fqdn

Verwaltungsendpunkte

Der Verwaltungsendpunkt erfordert zwei Zertifikate. Platzieren Sie diese Zertifikate im selben Ordner, ManagementEndpointsCerts. Die Zertifikate sind:

Verwaltungsendpunktzertifikat Erforderlicher Zertifikatsbetreff
Server IP-Adresse des Verwaltungsendpunkts: $ManagementIngressIpAddress.
Wenn die IP-Adresse des Verwaltungsendpunkts 192.168.50.100 ist, muss der Betreffname des Serverzertifikats exakt übereinstimmen. Betreff = 192.168.50.100. Sie können auch einen vollqualifizierten Domänennamen (Fully Qualified Domain Name, FQDN) als Servernamen (SN) verwenden, solange er in die Verwaltungs-IP-Adresse aufgelöst wird.
Kunde Verwenden Sie einen Zertifikatsbetreff, der Ihnen hilft, ihn von anderen zu unterscheiden. Eine beliebige Zeichenfolge ist akzeptabel.
Beispiel: Subject = ManagementEndpointClientAuth.

Erstellen von Zertifikaten zum Sichern von Endpunkten

Eingangsendpunkte

Führen Sie auf dem Hostcomputer oder der Active Directory virtuellen Maschine (VM) die Schritte in diesem Abschnitt aus, um Zertifikate für den Ingress-Traffic und externe Endpunkte der Appliance für den Trennungsbetrieb zu erstellen. Das OperationsModule bietet Hilfsmethoden zum Generieren von Zertifikatsignaturanforderungen oder zum Automatisieren der vollständigen Zertifikaterstellung.

Sie benötigen diese Zertifikate, um die Appliance für den Betrieb in getrennten Umgebungen bereitzustellen. Außerdem benötigen Sie den öffentlichen Schlüssel für Ihre lokale Infrastruktur, um eine sichere Vertrauenskette bereitzustellen.

Hinweis

IngressEndpointsCerts ist der Ordner, in dem Sie alle Zertifikatdateien speichern. IngressEndpointPassword ist eine sichere Zeichenfolge mit dem Zertifikatkennwort.

  1. Stellen Sie eine Verbindung mit der Zertifizierungsstelle her.
  2. Erstellen Sie einen Ordner namens "IngressEndpointsCerts". Verwenden Sie diesen Ordner, um alle Zertifikate zu speichern.
  3. Erstellen Sie die Zertifikate mithilfe der OperationsModule-Hilfsmethode mit dem Zielordner "IngressEndpointsCerts ".
  4. Anzeigen und Kopieren der Zertifikate (23 PFX-Dateien), die in IngressEndpointsCerts exportiert wurden.

Das folgende Skript zeigt, wie Sie mithilfe von OperationsModule Zertifikate generieren. Das Skript erstellt Zertifikatsignaturanforderungen (Certificate Signing Requests, CSRs), sendet sie an Ihre Zertifizierungsstelle und exportiert dann die generierten Zertifikate mit Kennwortschutz.

Hinweis

Führen Sie dieses Skript auf einem computer, der einer Domäne beigetreten ist, mithilfe eines Kontos mit Domänenadministratorzugriff aus, um Zertifikate auszustellen.

# Make sure you have the OperationsModule in this folder
# In the Appendix you can find an alternative to the OperationModule if you prefer writing your own automation

$applianceConfigBasePath = "C:\AzureLocalDisconnectedOperations\"
$fqdn = "autonomous.cloud.private" 
$IngressEndpointsCertsFolder = 'C:\Certs\IngressEndpointsCerts'
$certPassword  = Read-Host 'Password for output certificate file .pfx' -AsSecureString
## Automation alternative
## $certPassword =  (ConvertTo-SecureString "REPLACEME" -AsPlainText -Force)
$caName = "mycaserver.contoso.com\Contoso-RootCA" # Replace with your CA server and CA name (Run certutil -config - -ping to find the names)

Import-Module "$applianceConfigBasePath\OperationsModule\Azure.Local.DisconnectedOperations.psd1" -Force

New-ApplianceExternalCertificatesFromCA -ExternalFQDN $fqdn -OutputFolder $IngressEndpointsCertsFolder -CAConfig $caName -CertificatePassword $certPassword

Verwaltungsendpunkt

Hier ist ein Beispiel für das Erstellen von Zertifikaten zum Sichern des Verwaltungsendpunkts.

Hinweis

Führen Sie dieses Skript auf einem computer, der einer Domäne beigetreten ist, mithilfe eines Kontos mit Domänenadministratorzugriff aus, um Zertifikate auszustellen.

Nachdem Sie die Zertifikate erstellt haben, kopieren Sie die Verwaltungszertifikate (*.pfx) in die Verzeichnisstruktur, die in "ManagementEndpointCerts" dargestellt ist.

$applianceConfigBasePath = "C:\AzureLocalDisconnectedOperations\"
$fqdn = "autonomous.cloud.private" 
$managementEndpointIp = '192.168.100.25'
$managementEndpointCertsFolder = 'C:\Certs\ManagementEndpointsCerts'
$certPassword  = Read-Host 'Password for output certificate file .pfx' -AsSecureString
## Automation alternative
## $certPassword =  (ConvertTo-SecureString "REPLACEME" -AsPlainText -Force)
$caName = "mycaserver.contoso.com\Contoso-RootCA" # Replace with your CA server and CA name (Run certutil -config - -ping to find the names)

Import-Module "$applianceConfigBasePath\OperationsModule\Azure.Local.DisconnectedOperations.psd1" -Force

New-ApplianceManagementCertificatesFromCA -ManagementEndpoint $managementEndpointIp -OutputFolder $managementEndpointCertsFolder -CAConfig $caName -CertificatePassword $certpassword

Stamm-CA-Zertifikat exportieren

Sie benötigen den öffentlichen Stammzertifikatschlüssel für die Bereitstellung. Exportieren Sie das Stammzertifikat mit base64-Codierung.

Hier ist ein Beispiel zum Exportieren des öffentlichen Stammzertifikatschlüssels:

$applianceRootcert = "C:\AzureLocalDisconnectedOperations\applianceRoot.cer"
$dcName = "corp.contoso.com"
$caName = "$($dcname)$\Contoso-RootCA" # Replace with your CA server and CA name (Run certutil -config - -ping to find the names)

# Option 1) Get the Root CA certificate by its name:
$RootCACert = Get-ChildItem -Path Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*$($dcname)*" } | Select-Object -First 1

# # Option 2) Get the Root CA certificate by its thumbprint:
$RootCACert = Get-ChildItem -Path Cert:\LocalMachine\Root | Where-Object { $_.Thumbprint -eq "AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" } | Select-Object -First 1

# Check you have the correct Root CA certificate:
$RootCACert

# If it matches, export in CER (DER) format
Export-Certificate -Cert $RootCACert -FilePath "C:\Temp\RootCA-DER.cer" -Type CERT

# Finally, convert from CER (DER) to Base-64 CER (and store it in $applianceRootcert)
certutil -encode "C:\Temp\RootCA-DER.cer" $applianceRootcert

## Alternative method (If CA is setup and responds)
# certutil -ca.cert $applianceRootCert

Weitere Informationen finden Sie unter Active Directory-Zertifikatdienste.

Hinweis

Das Stammzertifikat ist erforderlich. Verwenden Sie das explizite Stammzertifikat, kein Zwischenzertifikat. Die Bereitstellung schlägt fehl, wenn die vollständige Vertrauenskette für die Zertifikate des Eingangsendpunkts fehlt.

Abrufen von Zertifikatinformationen für die Identitätsintegration

Um Ihre Identitätsintegration zu sichern, übergeben Sie die folgenden beiden Parameter:

  • LdapsCertChainInfo
  • OidcCertChainInfo

Diese Überprüfungen bestätigen, dass die Zertifikate und Die Kette für diese Endpunkte nicht geändert oder manipuliert werden.

Verwenden Sie eine Hilfsmethode in OperationsModule, um diese Parameter aufzufüllen.

Hier ist ein Beispiel für das Auffüllen der erforderlichen Parameter:

Import-Module "$applianceConfigBasePath\OperationsModule\Azure.Local.DisconnectedOperations.psd1" -Force
$oidcCertChain = Get-CertificateChainFromEndpoint -requestUri 'https://adfs.azurestack.local/adfs'
$ldapsCertChain = Get-CertificateChainFromEndpoint -requestUri 'https://dc01.azurestack.local'

Hier ist ein Beispiel für die Ausgabe von Get-CertificateChainFromEndpoint

# Returns: System.Security.Cryptography.X509Certificates.X509Certificate2[]
>> Get-CertificateChainFromEndpoint
>>
Thumbprint                                Subject
----------                                -------
TESTING580E20618EA15357FC1028622518DDC4D  CN=www.website.com, O=Contoso Corporation, L=Redmond, S=WA, C=US
TESTINGDAA2345B48E507320B695D386080E5B25  CN=www.website.com, O=Contoso Corporation, L=Redmond, S=WA, C=US
TESTING9BFD666761B268073FE06D1CC8D4F82A4  CN=www.website.com, O=Contoso Corporation, L=Redmond, S=WA, C=US

Anhang

Überprüfen der CRL mithilfe des PowerShell-Skripts

  • Kopieren Sie das folgende Skript in eine Datei, und nennen Sie es ValidateCRL.ps1
  • Aufrufen des Skripts mithilfe von .\ValidateCRL.ps1 -domainFQDN 'cloud.contoso.com'
# Powershell script for validation of certificates

param (
[Parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [string] $domainFQDN = "cloud.contoso.com"
)


$portalURI = "https://portal.$domainFQDN"
$armURI = "https://armmanagement.$domainFQDN/metadata/endpoints?api-version=2022-09-01"


Add-Type -AssemblyName System.Net.Http


foreach ($uri in @($portalURI, $armURI)) {
    Write-Host "`n============================================" -ForegroundColor Cyan
    Write-Host "Testing: $uri" -ForegroundColor Cyan
    Write-Host "============================================" -ForegroundColor Cyan


    # --- Test 1: CRL check ENABLED (matches your failing code) ---
    Write-Host "`n[CRL CHECK = TRUE]" -ForegroundColor Yellow
    try {
        $handler = [System.Net.Http.HttpClientHandler]::new()
        $handler.CheckCertificateRevocationList = $true
        $client = [System.Net.Http.HttpClient]::new($handler)
        $task = $client.GetAsync($uri)
        $response = $task.GetAwaiter().GetResult()
        Write-Host "  Status: $([int]$response.StatusCode) ($($response.StatusCode))" -ForegroundColor Green
    }
    catch {
        Write-Host "  FAILED:" -ForegroundColor Red
        $ex = $_.Exception
        $depth = 0
        while ($ex) {
            $indent = "  " + ("  " * $depth)
            Write-Host "${indent}[$($ex.GetType().FullName)]" -ForegroundColor Red
            Write-Host "${indent}Message: $($ex.Message)" -ForegroundColor Red
            Write-Host "${indent}HResult: 0x$($ex.HResult.ToString('X8'))" -ForegroundColor DarkYellow
            $ex = $ex.InnerException
            $depth++
        }
    }
    finally {
        if ($client) { $client.Dispose() }
        if ($handler) { $handler.Dispose() }
    }


    # --- Test 2: CRL check DISABLED (matches your passing PowerShell test) ---
    Write-Host "`n[CRL CHECK = FALSE]" -ForegroundColor Yellow
    try {
        $handler2 = [System.Net.Http.HttpClientHandler]::new()
        $handler2.CheckCertificateRevocationList = $false
        $client2 = [System.Net.Http.HttpClient]::new($handler2)
        $task2 = $client2.GetAsync($uri)
        $response2 = $task2.GetAwaiter().GetResult()
        Write-Host "  Status: $([int]$response2.StatusCode) ($($response2.StatusCode))" -ForegroundColor Green
    }
    catch {
        Write-Host "  FAILED:" -ForegroundColor Red
        $ex2 = $_.Exception
        $depth2 = 0
        while ($ex2) {
            $indent2 = "  " + ("  " * $depth2)
            Write-Host "${indent2}[$($ex2.GetType().FullName)]" -ForegroundColor Red
            Write-Host "${indent2}Message: $($ex2.Message)" -ForegroundColor Red
            $ex2 = $ex2.InnerException
            $depth2++
        }
    }
    finally {
        if ($client2) { $client2.Dispose() }
        if ($handler2) { $handler2.Dispose() }
    }
}



Erstellen von Zertifikaten skriptbasiert

Wenn Sie die Zertifikatgenerierung lieber steuern möchten, finden Sie hier ein Beispiel, das Sie ändern können, um CSRs zu erstellen und Zertifikate auszustellen.

$fqdn = "autonomous.cloud.private" 
$caName = "<CA Computer Name>\<CA Name>" # Replace with your CA server and CA name (Run certutil -config - -ping to find the names)

$extCertFilePath = "C:\AzureLocalDisconnectedOperations\Certs\IngressEndpointsCerts"
# Making sure to create this directory if it does not exist
[void](New-Item -ItemType Directory -path $extCertFilePath -force)

$certPassword = Read-Host -AsSecureString -Message 'CertPass' -Force  
# Alternative
# $certPassword = "REPLACEME"|ConvertTo-SecureString -AsPlainText -Force
# Make sure the certificate list matches the table. Refer to the "Ingress endpoint certificate requirements" section for details.
$AzLCerts = @(    
  "*.edgeacr.$fqdn"      
  "*.vault.$fqdn"
  "*.queue.$fqdn"    
  "*.table.$fqdn"
  "*.blob.$fqdn" 
  "*.servicebus.$fqdn"   
  "data.policy.$fqdn"
  "arckubernetesconfig.$fqdn"
  "agentserviceapi.$fqdn"
  "his.$fqdn"
  "guestnotificationservice.$fqdn"
  "metricsingestiongateway.monitoring.$fqdn"
  "amcs.monitoring.$fqdn"
  "dp.appliances.$fqdn"
  "armmanagement.$fqdn"
  "adminmanagement.$fqdn"
  "management.$fqdn"
  "frontend.appliances.$fqdn"
  "graph.$fqdn"
  "dp.aszrp.$fqdn"
  "portal.$fqdn"
  "hosting.$fqdn"    
  "catalogapi.$fqdn"    
  "login.$fqdn"    
  # Multi-San could be added with comma seperated list x.$fqdn,y.$fqdn    
)

$AzLCerts | ForEach-Object {
    # Check if this is a multi SAN certificate
    if ($_.Contains(',')) {
        $certSubject = "CN=$($_.Split(',')[0])"
        $dns = $_.Replace(',', '&DNS=').Replace(' ', '')
        $filePrefix = $_.Split(',')[0].Replace('*.', '')
    }
    else {
        $certSubject = "CN=$_"
        $dns = $certSubject.Split('=')[1]
        $filePrefix = $dns.Replace('*.', '')
    }
    $certFilePath = "$extCertFilePath\INF"
    New-Item -ItemType Directory -Path $certFilePath -Force | Out-Null
    Remove-Item "$certFilePath\$filePrefix.*" -Force -ErrorAction SilentlyContinue
    $csrPath = Join-Path -Path $certFilePath -ChildPath "$filePrefix.csr"
    $infPath = Join-Path -Path $certFilePath -ChildPath "$filePrefix.inf"

    # Create the INF file for the CSR
    @"
[NewRequest]
Subject = "$certSubject"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
KeyUsage = 0xa0
HashAlgorithm = sha256

[Extensions]
2.5.29.17 = "{text}"
_continue_ = "DNS=$dns"
"@ | Out-File -FilePath $infPath

    # Generate the CSR
    certreq -new $infPath $csrPath
    # Define parameters to submit the CSR
    $certPath = Join-Path $certFilePath -ChildPath "$filePrefix.cer"

    # Submit the CSR to the CA
    certreq -submit -attrib "CertificateTemplate:WebServer" -config $caName $csrPath $certPath
    Write-Verbose "Certificate request submitted. Certificate saved to $certPath" -Verbose

    # Accept the certificate and install it.
    $certReqOutput = certreq.exe -accept $certPath

    # Parse the thumbprint and export the certificate
    $match = $certReqOutput -match 'Thumbprint:\s*([a-fA-F0-9]+)'
    if ($null -ne $match) {
        $thumbprint = (($match[0]).Split(':')[1]).Trim()
        Write-Verbose "Thumbprint: $thumbprint" -Verbose
    }
    else {
        Write-Verbose "Thumbprint not found" -Verbose
        #return;
    }

    # Export the certificate to a PFX file
    $cert = Get-Item -Path "Cert:\LocalMachine\My\$thumbprint"
    $cert | Export-PfxCertificate -FilePath "$extCertFilePath\$filePrefix.pfx" -Password $certPassword -Force
    Write-Verbose "Certificate for $certSubject and private key exported to $extCertFilePath" -Verbose
}
# Management certs alternative method
$caName = "mycaserver.contoso.com\Contoso-RootCA" # Replace with your CA server and CA name (Run certutil -config - -ping to find the names)

# For more info on how to find your CA: https://learn.microsoft.com/en-us/troubleshoot/windows-server/certificates-and-public-key-infrastructure-pki/find-name-enterprise-root-ca-server 
$certPassword = Read-Host -AsSecureString -Message 'ManagementCertPass' -Force 
# Alternative
# $certPassword = "REPLACEME"|ConvertTo-SecureString -AsPlainText -Force

$managementendpointPath = "C:\AzureLocalDisconnectedOperations\Certs\ManagementEndpointsCerts"
[void](New-Item -ItemType Directory -path $managementendpointPath -force)
$managementEndpointIPAddress = '192.168.100.25'
$fileNames = @('ManagementEndpointSsl', 'ManagementEndpointClientAuth')
$subjects = @($managementEndpointIPAddress,'ManagementEndpointClientAuth')  

$subjects|Foreach-Object {
    $subject=$_    
    $filename = $fileNames[$subjects.IndexOf($_)] 
    $infFilename = "$($managementendpointPath)\$($filename).inf"
    $csrPath = "$($managementendpointPath)\$($filename).csr"
    $certPath = "$($managementendpointPath)\$($filename).cer"
    $pfxPath = "$($managementendpointPath)\$($filename).pfx"
@"
[NewRequest]
Subject = "CN=$subject"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
KeyUsage = 0xa0
HashAlgorithm = sha256

[Extensions]
2.5.29.17 = "{text}"
_continue_ = "DNS=$subject"
"@ | Out-File -FilePath $infFilename

    # Generate the CSR
    certreq -new $infFilename $csrPath

    # Submit the CSR to the CA
    certreq -submit -attrib "CertificateTemplate:WebServer" -config $caName $csrPath $certPath
    Write-Verbose "Certificate request submitted. Certificate saved to $certPath" -Verbose

    # Accept the certificate and install it.
    $certReqOutput = certreq.exe -accept $certPath

    # Parse the thumbprint and export the certificate
    $match = $certReqOutput -match 'Thumbprint:\s*([a-fA-F0-9]+)'
    if ($null -ne $match) {
        $thumbprint = (($match[0]).Split(':')[1]).Trim()
        Write-Verbose "Thumbprint: $thumbprint" -Verbose
    }
    else {
        Write-Verbose "Thumbprint not found" -Verbose
        #return;
    }

    # Export the certificate to a PFX file
    $cert = Get-Item -Path "Cert:\LocalMachine\My\$thumbprint"
    $cert | Export-PfxCertificate -FilePath $pfxPath -Password $certPassword -Force
    Write-Verbose "Certificate for $subject and private key exported to $certPath" -Verbose
}

Dieses Feature ist nur in Azure Local 2602 oder höher verfügbar.