使用 PowerShell 导出 Office 365 用户的 MFA 状态
我真正怀念 Microsoft 365 管理中心的报告之一是每个用户的 MFA 状态的清晰概述。 MFA 是保护租户的一项非常重要的安全措施。为了确保我们的用户已配置 MFA,我们将使用 PowerShell 获取并导出 MFA 状态。
您还可以使用管理中心中的内置概述,但这确实非常耗时。另一方面,使用 PowerShell,我们可以轻松获取所有用户的 MFA 状态,并创建包含我们需要的所有详细信息的 Excel 列表。
我创建了一个脚本,可以执行以下几项操作来检查和报告用户的 MFA 状态:
- 列出所有用户的 MFA 状态
- 列出为每个用户配置的 MFA 类型
- 获取所有未启用 MFA 的用户
- 检查单个用户的MFA状态
- 检查是否强制执行 MFA
- 检查用户是否是管理员
- 仅获取许可和启用的用户
在文章末尾,您将找到完整的脚本。
笔记
我还基于 Microsoft Graph 创建了这个脚本。它将获得比该脚本更多的信息。请务必检查一下!
使用 PowerShell 获取 MFA 状态
借助 PowerShell,我们可以轻松获取所有 Office 365 用户的 MFA 状态。该脚本的基础是 Get-MsolUser cmdlet,它从 Azure Active Directory 获取用户。
Get-MsolUser 返回所有用户详细信息,包括参数 StrongAuthenticationMethods。此参数将列出用户正在使用的所有强身份验证方法。如果设置了这个参数,那么我们就知道用户正在使用MFA。
建议
将此脚本添加到您的 PowerShell 配置文件中,以便您可以轻松检查用户的 MFA 状态。在本文中阅读更多相关信息。
要求
您需要安装 MsolService 模块才能使用此脚本。运行脚本之前请确保您已连接。
Connect-MsolService获取所有用户及其 MFA 状态的列表
您只需运行不带任何参数的脚本即可获取所有用户及其 MFA 状态的列表。该脚本将检查用户是否是管理员,并列出用户设置的默认 MFA 类型。
如果您愿意,您可以将结果导出到屏幕上或导出到 CSV 文件。
# Make sure you are connected to MsolService
Get-MFAStatus.ps1 | FT
# Or if you want an excel file
Get-MFAStatus.ps1 | Export-CSV c:\temp\mfastatus.csv -noTypeInformation仅获取没有 MFA 的用户
如果您有一个大租户,那么您可能只想获得没有 MFA 的用户。您可以使用开关 withOutMFAOnly 来实现此目的。
Get-MFAStatus.ps1 -withOutMFAOnly检查管理员的 MFA 状态
毫无疑问,管理员应该启用 MFA。要快速检查所有管理员帐户的状态,您可以使用开关 adminsOnly
Get-MFAStatus.ps1 -adminsOnly检查选定用户的 MFA 状态
该脚本还允许您检查单个用户或多个用户的 MFA 状态。
Get-MFAStatus.ps1 -UserPrincipalName 'johndoe@contoso.com'
例如,如果您想检查单个部门的状态,则可以执行以下操作:
Get-MsolUser.ps1 -Department 'Finance' | ForEach-Object { Get-MFAStatus $_.UserPrincipalName }完整的脚本
您可以在下面找到完整的脚本,也可以从我的 Github 获取它。 (我建议使用 Github 以确保您拥有最新版本)。
建议
通过在 PowerShell 配置文件中添加对脚本的引用,快速获取用户的 MFA 状态。请阅读本文中的所有内容。
<#
Name: Get-MFAStatus
Author: R. Mens - LazyAdmin.nl
Version: 1.3
DateCreated: jan 2021
Purpose/Change: List all Configured MFA Types
Thanks to: Anthony Bartolo
#>
[CmdletBinding(DefaultParameterSetName="Default")]
param(
[Parameter(
Mandatory = $false,
ParameterSetName = "UserPrincipalName",
HelpMessage = "Enter a single UserPrincipalName or a comma separted list of UserPrincipalNames",
Position = 0
)]
[string[]]$UserPrincipalName,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $false,
ParameterSetName = "AdminsOnly"
)]
# Get only the users that are an admin
[switch]$adminsOnly = $false,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $false,
ParameterSetName = "AllUsers"
)]
# Set the Max results to return
[int]$MaxResults = 10000,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $false,
ParameterSetName = "Licenend"
)]
# Check only the MFA status of users that have license
[switch]$IsLicensed = $true,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
ParameterSetName = "withOutMFAOnly"
)]
# Get only the users that don't have MFA enabled
[switch]$withOutMFAOnly = $false,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $false
)]
# Check if a user is an admin. Set to $false to skip the check
[switch]$listAdmins = $true
)
# Connect to Msol
if ((Get-Module -ListAvailable -Name MSOnline) -eq $null)
{
Write-Host "MSOnline Module is required, do you want to install it?" -ForegroundColor Yellow
$install = Read-Host Do you want to install module? [Y] Yes [N] No
if($install -match "[yY]")
{
Write-Host "Installing MSOnline module" -ForegroundColor Cyan
Install-Module MSOnline -Repository PSGallery -AllowClobber -Force
}
else
{
Write-Error "Please install MSOnline module."
}
}
if ((Get-Module -ListAvailable -Name MSOnline) -ne $null)
{
if(-not (Get-MsolDomain -ErrorAction SilentlyContinue))
{
Connect-MsolService
}
}
else{
Write-Error "Please install Msol module."
}
# Get all licensed admins
$admins = $null
if (($listAdmins) -or ($adminsOnly)) {
$admins = Get-MsolRole | %{$role = $_.name; Get-MsolRoleMember -RoleObjectId $_.objectid} | Where-Object {$_.isLicensed -eq $true} | select @{Name="Role"; Expression = {$role}}, DisplayName, EmailAddress, ObjectId | Sort-Object -Property EmailAddress -Unique
}
# Check if a UserPrincipalName is given
# Get the MFA status for the given user(s) if they exist
if ($PSBoundParameters.ContainsKey('UserPrincipalName')) {
foreach ($user in $UserPrincipalName) {
try {
$MsolUser = Get-MsolUser -UserPrincipalName $user -ErrorAction Stop
$Method = ""
$MFAMethod = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
If (($MsolUser.StrongAuthenticationRequirements) -or ($MsolUser.StrongAuthenticationMethods)) {
Switch ($MFAMethod) {
"OneWaySMS" { $Method = "SMS token" }
"TwoWayVoiceMobile" { $Method = "Phone call verification" }
"PhoneAppOTP" { $Method = "Hardware token or authenticator app" }
"PhoneAppNotification" { $Method = "Authenticator app" }
}
}
[PSCustomObject]@{
DisplayName = $MsolUser.DisplayName
UserPrincipalName = $MsolUser.UserPrincipalName
isAdmin = if ($listAdmins -and $admins.EmailAddress -match $MsolUser.UserPrincipalName) {$true} else {"-"}
MFAEnabled = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
MFAType = $Method
MFAEnforced = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
}
}
catch {
[PSCustomObject]@{
DisplayName = " - Not found"
UserPrincipalName = $User
isAdmin = $null
MFAEnabled = $null
}
}
}
}
# Get only the admins and check their MFA Status
elseif ($adminsOnly) {
foreach ($admin in $admins) {
$MsolUser = Get-MsolUser -ObjectId $admin.ObjectId | Sort-Object UserPrincipalName -ErrorAction Stop
$MFAMethod = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
$Method = ""
If (($MsolUser.StrongAuthenticationRequirements) -or ($MsolUser.StrongAuthenticationMethods)) {
Switch ($MFAMethod) {
"OneWaySMS" { $Method = "SMS token" }
"TwoWayVoiceMobile" { $Method = "Phone call verification" }
"PhoneAppOTP" { $Method = "Hardware token or authenticator app" }
"PhoneAppNotification" { $Method = "Authenticator app" }
}
}
[PSCustomObject]@{
DisplayName = $MsolUser.DisplayName
UserPrincipalName = $MsolUser.UserPrincipalName
isAdmin = $true
"MFA Enabled" = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
"MFA Default Type"= $Method
"SMS token" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "OneWaySMS") {$true} else {"-"}
"Phone call verification" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "TwoWayVoiceMobile") {$true} else {"-"}
"Hardware token or authenticator app" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "PhoneAppOTP") {$true} else {"-"}
"Authenticator app" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "PhoneAppNotification") {$true} else {"-"}
MFAEnforced = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
}
}
}
# Get the MFA status from all the users
else {
$MsolUsers = Get-MsolUser -EnabledFilter EnabledOnly -MaxResults $MaxResults | Where-Object {$_.IsLicensed -eq $isLicensed} | Sort-Object UserPrincipalName
foreach ($MsolUser in $MsolUsers) {
$MFAMethod = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
$Method = ""
If (($MsolUser.StrongAuthenticationRequirements) -or ($MsolUser.StrongAuthenticationMethods)) {
Switch ($MFAMethod) {
"OneWaySMS" { $Method = "SMS token" }
"TwoWayVoiceMobile" { $Method = "Phone call verification" }
"PhoneAppOTP" { $Method = "Hardware token or authenticator app" }
"PhoneAppNotification" { $Method = "Authenticator app" }
}
}
if ($withOutMFAOnly) {
# List only the user that don't have MFA enabled
if (-not($MsolUser.StrongAuthenticationMethods)) {
[PSCustomObject]@{
DisplayName = $MsolUser.DisplayName
UserPrincipalName = $MsolUser.UserPrincipalName
isAdmin = if ($listAdmins -and ($admins.EmailAddress -match $MsolUser.UserPrincipalName)) {$true} else {"-"}
MFAEnabled = $false
MFAType = "-"
MFAEnforced = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
}
}
}else{
[PSCustomObject]@{
DisplayName = $MsolUser.DisplayName
UserPrincipalName = $MsolUser.UserPrincipalName
isAdmin = if ($listAdmins -and ($admins.EmailAddress -match $MsolUser.UserPrincipalName)) {$true} else {"-"}
"MFA Enabled" = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
"MFA Default Type"= $Method
"SMS token" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "OneWaySMS") {$true} else {"-"}
"Phone call verification" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "TwoWayVoiceMobile") {$true} else {"-"}
"Hardware token or authenticator app" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "PhoneAppOTP") {$true} else {"-"}
"Authenticator app" = if ($MsolUser.StrongAuthenticationMethods.MethodType -contains "PhoneAppNotification") {$true} else {"-"}
MFAEnforced = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
}
}
}
}
总结
启用 MFA 是保护租户的重要步骤之一。使用此 PowerShell 脚本,您可以轻松检查用户的 MFA 状态。
请务必查看本文以及其他 20 个 Office 365 安全提示。
如果您发现此脚本有用,请分享。如果您有任何疑问,请在下面发表评论。
您可能还喜欢以下 PowerShell 报告脚本之一:
- 邮箱权限报告
- 邮箱大小报告
- OneDrive 大小报告
