此脚本使用 OpenSSL 自动生成和签名传输层安全性 (TLS) 证书。 它使用 TLS 检查图形 API 创建证书签名请求(CSR)。 该脚本使用 OpenSSL 创建自签名根证书颁发机构,对 CSR 进行签名,并将证书和链上传到 TLS 检查设置。
先决条件
- 安装适用于 Windows 或 Linux 的 OpenSSL。
 
注释
虽然其他工具可能可用于证书管理,但本文中的此示例代码使用 OpenSSL。 OpenSSL 与许多 Linux 发行版(如 Ubuntu)捆绑在一起。
生成和签名 TLS 证书
# This script requires the following:
#    - PowerShell 5.1 (x64) or later
#    - Module: Microsoft.Graph.Beta
#
# Before you begin:
#    
# - Make sure you're running PowerShell as an administrator
# - Make sure you run: Install-Module Microsoft.Graph.Beta -AllowClobber -Force
# Ensure Microsoft.Graph.Beta module is available
# Import Module
Import-Module Microsoft.Graph.Beta.NetworkAccess
# Connect to Microsoft Graph (handles token for you)
Connect-MgGraph -Scopes "NetworkAccess.ReadWrite.All" -NoWelcome
# Modify the following with your own settings before running the script:
# Parameters of the certificate sign request (letters and numbers only and within 12 characters).
    $name = "TLSiDemoCA"
    $commonName = "Contoso TLS Demo"
    $organizationName = "Contoso"
# Replace with your openSSLpath
    $openSSLPath = "C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
# Self-signed CA file names
$rootKey = "TlsDemorootCA.key"
$rootCert = "TlsDemorootCAcert.pem"
$subject = "/C=US/ST=Washington/L=Redmond/O=Contoso/CN=Contoso"
$signedCert = "signedcertificate.pem"
#: Check if External Certificate Authority Certificates already exists
try {
    $response = Get-MgBetaNetworkAccessTlExternalCertificateAuthorityCertificate
    if ($response.Count -gt 0) {
        Write-Host "A certificate for TLS inspection already exists."
	    exit 1
    } 
}
catch {
    Write-Error "The Graph SDK call failed: $($_.Exception.Message)"
}
# Create the certificate signing request (CSR)
$paramscsr = @{
	"@odata.type" = "#microsoft.graph.networkaccess.externalCertificateAuthorityCertificate"
	name = $name
	commonName =  $commonName
	organizationName = $organizationName
}
$createResponse = $null
try {
  $createResponse = New-MgBetaNetworkAccessTlExternalCertificateAuthorityCertificate -BodyParameter $paramscsr -ErrorAction Stop
} 
catch {
    Write-Error "Failed to create certificate signing request: $($_.Exception.Message)"
    Exit 1	
}
# Save CSR to file
$csr = $createResponse.CertificateSigningRequest
$csrPath = "$name.csr"
Set-Content -Path $csrPath -Value $csr
Write-Host "CSR saved to $csrPath"
# Save the certificate ID to upload later:
$externalCertificateAuthorityCertificateId = $createResponse.Id
# Create openssl.cnf with predefined profiles
$opensslCnfContent = @"
[ rootCA_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ interCA_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:1
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ signedCA_ext ]
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = serverAuth
[ server_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
"@
$opensslCnfPath = "openssl.cnf"
# Write content to openssl.cnf file
Set-Content -Path $opensslCnfPath -Value $opensslCnfContent -Encoding ASCII
# Generate Root CA private key and certificate. Note: You need to install the Root CA certificate in the trusted certificate store of testing users' devices.
Write-Host "Generating Root CA key and certificate..."
& $openSSLPath req -x509 -new -nodes -newkey rsa:4096 -keyout $rootKey -sha256 -days 370 -out $rootCert -subj $subject -config $opensslCnfPath -extensions rootCA_ext
# Sign CSR using Root CA
if (Test-Path $csrPath) {
    Write-Host "Signing CSR file $csrPath..."
    & $openSSLPath x509 -req -in $csrPath -CA $rootCert -CAkey $rootKey -CAcreateserial -out $signedCert -days 370 -sha256 -extfile $opensslCnfPath -extensions signedCA_ext
    Write-Host "Successfully saved signed certificate to $signedCert"
} else {
    Write-Host "CSR file '$csrPath' not found. Please generate it first."
}
# Read certificate and chain
$paramsupload = @{
certificate = Get-Content -Path $SignedCert -Raw
chain       = Get-Content -Path $RootCert -Raw
}
# Upload the signed certificate and its chain to Microsoft Graph using the SDK cmdlet.
# -ExternalCertificateAuthorityCertificateId: The unique ID of the certificate request previously created.
# -BodyParameter: A hashtable containing the PEM-encoded certificate and chain as required by the API.
try {Update-MgBetaNetworkAccessTlExternalCertificateAuthorityCertificate -ExternalCertificateAuthorityCertificateId $externalCertificateAuthorityCertificateId -BodyParameter $paramsupload
-ErrorAction Stop} catch {
Write-Error "Failed to upload certificate and chain: $($_.Exception.Message)"
exit 1
}
Write-Host "Certificate is uploaded successfully via Microsoft Graph SDK."