如何使用服务主体获取Azure用户的MFA详细信息
可行方案
方案1:使用Microsoft Graph PowerShell模块(官方推荐)
MSOL模块已进入废弃周期,微软官方推荐使用Microsoft Graph PowerShell实现所有Azure AD相关操作,该模块原生支持服务主体非交互登录,也可以直接获取用户MFA的全部详细信息。
前置配置
先给你使用的服务主体分配以下Microsoft Graph应用权限,并完成租户管理员同意授权:
RoleManagement.Read.Directory:读取目录内所有管理员角色及成员信息User.Read.All:读取所有用户基础属性UserAuthenticationMethod.Read.All:读取所有用户的认证方法(含MFA相关配置)
改写后的完整脚本
# 服务主体登录配置 $clientId = "替换为你的服务主体客户端(应用)ID" $tenantId = "替换为你的租户ID" $clientSecret = ConvertTo-SecureString "替换为你的服务主体客户端密钥" -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret) # 服务主体登录Graph Connect-MgGraph -Credential $credential -TenantId $tenantId -Scopes "https://graph.microsoft.com/.default" # 输出文件路径 $output_file_location = "c:\temp\azure_admins_mfa_status_"+$(get-date -f yyyy-MM-dd-HH-mm-ss)+".csv" # 要查询的管理员角色列表,与原脚本保持一致 $admin_roles = "Company Administrator","Billing Administrator","Conditional Access Administrator","Exchange Service administrator","Helpdesk administrator","Password administrator","Security administrator","Sharepoint Service administrator" function Get-MFAStatus { foreach ($roleName in $admin_roles) { Write-Host "正在处理角色:$roleName" # 获取对应角色对象 $role = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'" -ErrorAction SilentlyContinue if (-not $role) { Write-Host "未找到角色:$roleName,跳过" continue } # 获取角色成员 $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id foreach ($member in $members) { # 仅处理用户类型的成员,跳过服务主体、组等其他类型 if ($member.AdditionalProperties.'@odata.type' -ne '#microsoft.graph.user') { continue } $userId = $member.Id Write-Host "正在查询用户:$($member.AdditionalProperties.userPrincipalName)" # 获取用户MFA相关配置,属性与原MSOL接口完全对齐 $user = Get-MgUser -UserId $userId -Property DisplayName,UserPrincipalName,StrongAuthenticationRequirements,StrongAuthenticationMethods # 提取MFA相关字段 $mfaState = $user.StrongAuthenticationRequirements.State ?? "Disabled" $mfaMethods = $user.StrongAuthenticationMethods.MethodType -join "," $defaultMfaMethod = ($user.StrongAuthenticationMethods | Where-Object IsDefault -eq $true).MethodType # 构造输出对象 $outputObj = [PSCustomObject]@{ DisplayName = $user.DisplayName 'E-mail' = $user.UserPrincipalName Role = $roleName 'MFA-Requirements' = $mfaState 'MFA-Methods' = $mfaMethods 'MFA-MethodsDefault' = $defaultMfaMethod } $outputObj | Export-Csv -Path $output_file_location -Append -NoTypeInformation -Encoding UTF8 } } } Get-MFAStatus # 断开Graph连接 Disconnect-MgGraph
如果你的服务主体使用证书认证而非密钥,只需要将登录部分替换为Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint "你的证书指纹"即可。
方案2:使用MSOL模块的服务主体登录方式
你提到的Connect-MsolService实际支持服务主体非交互登录,只是相关参数没有广泛宣传,无需用户交互的登录方式如下:
$clientId = "替换为服务主体客户端ID" $tenantId = "替换为租户ID" $clientSecret = ConvertTo-SecureString "替换为服务主体客户端密钥" -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret) Connect-MsolService -Credential $credential -TenantId $tenantId
登录完成后可以直接运行你原来的脚本,无需改动其他逻辑。该方案仅作为临时过渡使用,MSOL模块将于2024年8月31日正式停用,后续微软不会再提供维护支持。
内容的提问来源于stack exchange,提问作者Ashish Gupta
相关产品推荐
相关产品推荐

