基于证书认证的PowerShell连接Entra/Azure及API调用实现
基于证书认证的Azure PowerShell连接与API调用实现指南
我可以通过
Connect-AzAccount轻松连接租户,并使用PowerShell模块获取所需信息(如执行$vms = Get-AzVM),但这并非我的目标。我已在租户中创建了应用注册及用于认证的证书,希望脚本通过该证书认证实现与上述相同的调用。
你尝试的认证脚本
$tenantID = "aGUID" $applicationID = "anotherGUID" $resourceGroup = "aGroup" $subscriptionID = "Azure subscription 1" # Connect to Entra ID with Certificate $certThumbPrint = "acertGUID" $certPass = ConvertTo-SecureString -String "somepassword" -Force -AsPlainText #$cert = Get-Item -Path Cert:\CurrentUser\My\$certThumbPrint # Import the certificate #$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\temp\cert.pfx", $certPass, "Exportable,PersistKeySet") # Get the Azure AD application $azureAdApplication = Get-AzADApplication -ApplicationId $applicationID -TenantId $tenantID # Get the certificate associated with the application $cert = Get-AzADAppCredential -ApplicationId $applicationID -TenantId $tenantID | Where-Object { $_.Type -eq "AsymmetricX509Cert" -and $_.Usage -eq "Verify" } # Authenticate using the certificate $token = Get-AzAccessToken -ResourceUrl "https://management.azure.com" -TenantId $tenantID -CertificateThumbprint $certThumbPrint -ApplicationId $applicationID -Credential $cert # Authenticate to Azure AD using the certificate #$token = Get-AzAccessToken -ResourceUrl "https://management.azure.com" -TenantId $tenantID -ClientId $applicationID -CertificateThumbprint $cert.Thumbprint $token = Get-AzAccessToken -ResourceUrl "https://management.azure.com" -TenantId $tenantID -ServicePrincipalId $applicationID -CertificateThumbprint $certThumbPrint # Set the Azure context Set-AzContext -AadAccessToken $token.Token -SubscriptionId $subscriptionID # Get a list of VMs $vms = Get-AzVM # Display VM information foreach ($vm in $vms) { Write-Host "VM Name: $($vm.Name), Resource Group: $($vm.ResourceGroupName)" # Add more details as needed }
你创建应用注册的脚本
Connect-AzAccount # Create a Certificate and Put it in my Certificate Store $cert = New-SelfSignedCertificate -CertStoreLocation "cert:\CurrentUser\My" -Subject $applicationName -KeySpec KeyExchange $keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData()) # Register a new Application in Azure Tenant $application = New-AzADApplication -DisplayName $applicationName $objectId = $application.Id $applicationId = $application.AppId Start-Sleep -Seconds 2 # Add this new certificate to the application New-AzADAppCredential -ApplicationId $applicationId -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore # Assign API Permissions ## Graph API (Read) Add-AzADAppPermission -ObjectId $objectId -ApiId "00000003-0000-0000-c000-000000000000" -PermissionId "5f8c59db-677d-491f-a6b8-5f174b11ec1d" # Export the certificate to a PFX file $cert | Export-PfxCertificate -FilePath $certFilePath -Password (ConvertTo-SecureString -String $certPassword -Force -AsPlainText) Write-Host "Certificate Created and placed in: $($certFilePath)" # Need to convert ByteArray to Base64 to store it in a Normal Azure Table $certBytes = [System.IO.File]::ReadAllBytes($certFilePath) $certBase64 = [System.Convert]::ToBase64String($certBytes) # Get the Domain the the Account $tenantDetails = Get-AzTenant Insert-Row -AZStorageTable "AppCertsTest" -PartitionKey $companyName -RowKey $applicationId -TenantID $tenantId -Domain $tenantDetails.DefaultDomain -CertThumbPrint $cert.Thumbprint -CertBytes $certBase64 Write-Host "Tenant Saved in Azure"
核心修正与正确实现步骤
1. 补全应用注册的权限配置
原创建脚本仅添加了Graph API权限,无法满足Get-AzVM这类Azure资源管理操作的需求,必须补充订阅级资源权限:
# 为应用注册分配Reader角色到目标订阅(可根据需求替换为Contributor等角色) New-AzRoleAssignment -ApplicationId $applicationId -RoleDefinitionName "Reader" -Scope "/subscriptions/$subscriptionID"
2. 简化认证流程(官方推荐方式)
无需手动获取AccessToken再设置Context,直接使用Connect-AzAccount的服务主体参数完成认证,这是最稳定可靠的方式:
$tenantID = "aGUID" $applicationID = "anotherGUID" $subscriptionID = "Azure subscription 1" $certThumbPrint = "acertGUID" # 使用证书认证连接Azure服务主体 Connect-AzAccount -ServicePrincipal -Tenant $tenantID -ApplicationId $applicationID -CertificateThumbprint $certThumbPrint # 设置默认订阅(多订阅场景下可选) Set-AzContext -Subscription $subscriptionID # 执行资源操作 $vms = Get-AzVM foreach ($vm in $vms) { Write-Host "VM Name: $($vm.Name), Resource Group: $($vm.ResourceGroupName)" }
3. 证书导入的正确方式(若证书不在本地存储)
如果需要从PFX文件导入证书到本地库,确保导入时保留私钥:
$certPath = "C:\temp\cert.pfx" $certPass = ConvertTo-SecureString -String "somepassword" -Force -AsPlainText # 导入证书到当前用户的个人存储区(包含私钥) Import-PfxCertificate -FilePath $certPath -CertStoreLocation Cert:\CurrentUser\My -Password $certPass
关键注意事项
- 证书必须包含私钥,且存储在本地机器的
CurrentUser\My或LocalMachine\My证书库中,否则无法完成签名认证。 - 应用注册的所有权限(Graph API和资源角色)都需要管理员同意才能生效。
- 避免冗余的认证步骤,官方推荐的
Connect-AzAccount -ServicePrincipal方式已封装了token获取和context设置逻辑,比手动处理更稳定。
内容的提问来源于stack exchange,提问作者Bigbear
相关产品推荐
相关产品推荐

