20250305 Graph API 를 사용한 EntraID 사용자 MFA 등록 현황 확인
Graph API를 통해 Powershell 에서 원하는 고객사의 Entra 사용자 및 MFA 등록 현황 리스트를 추출합니다.
단 , 외부 사용자 초대로 생성한 사용자의 경우 ( #EXT# 계정 ) MFA 등록 현황 추출이 불가능합니다.
해당 사용자의 경우 직접 Azure Portal 에서 확인이 필요합니다.
1. App Registrations 에 Graph API 등록
1-1. Entra ID 블레이드에서 App Registrations 에서 새 등록 을 통해 애플리케이션을 생성합니다.
1-2. 생성한 App 에서 API 사용 권한 으로 이동해 Microsoft.Graph 에 대해서 권한 추가를 통해
1. Directroy.Read.All 2. UserAuthenticationMethod.Read.All
해당 애플리케이션 사용 권한 추가
1-3. 추가한 권한에 대해 관리자 동의 확인을 부여
1-4. 인증서 및 암호 로 이동해 새 클라이언트 암호 생성 후 생성된 클라이언트 암호 값
을 복사합니다.
2. PowerShell 에서 Graph API 를 통한 리스트 추출
2-1. 아래 스크립트에서 ID 및 Secret 값을 변경한 후 Powershell 에서 동작시켜 Microsoft Graph API 접근에
필요한 엑세스 토큰 발급을 진행합니다.
$tenantId = "테넌트 ID 값 붙여넣기"
$clientId = "생성한 애플리케이션의 ID 붙여넣기"
$clientSecret = "복사한 클라이언트 암호 값 붙여넣기"
$tokenBody = @{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $clientId
Client_Secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $tokenBody
$accessToken = $tokenResponse.access_token
2-2. 아래 스크립트를 Powershell 에서 동작시켜 사용자 목록을 가져옵니다.
$headers = @{
Authorization = "Bearer $accessToken"
}
$users = @()
$nextLink = "https://graph.microsoft.com/v1.0/users"
do {
try {
$response = Invoke-RestMethod -Uri $nextLink -Headers $headers
if ($response -ne $null -and $response.value -ne $null) {
$users += $response.value
}
if ($response.'@odata.nextLink' -ne $null) {
$nextLink = $response.'@odata.nextLink'
} else {
$nextLink = $null
}
}
catch {
Write-Output "Failed to get users page"
Write-Output "Error Details: $($_.Exception.Message)"
}
} while ($nextLink -ne $null)
2-3. 아래 스크립트를 Powershell 에서 동작시켜 사용자 목록을 기반으로 인증 방법을 조회하고
해당 결과를 JSON 형식으로 저장합니다.
$results = @()
foreach ($user in $users) {
Start-Sleep -Milliseconds 500.
try {
$authMethods = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/users/$($user.userPrincipalName)/authentication/methods" -Headers $headers
if ($authMethods -ne $null -and $authMethods.value.Count -eq 0) {
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = "None"
Detail = "No authentication methods found"
}
} elseif ($authMethods -ne $null) {
foreach ($method in $authMethods.value) {
$authMethodType = $method."@odata.type"
if ($authMethodType -eq "#microsoft.graph.phoneAuthenticationMethod") {
$phoneNumber = if ($method.phoneNumber -ne $null) { $method.phoneNumber } else { "N/A" }
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = "Phone Number"
Detail = "Primary mobile: $phoneNumber"
}
}
elseif ($authMethodType -eq "#microsoft.graph.emailAuthenticationMethod") {
$email = if ($method.emailAddress -ne $null) { $method.emailAddress } else { "N/A" }
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = "Email"
Detail = $email
}
}
elseif ($authMethodType -eq "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod") {
$deviceDisplayName = if ($method.displayName -ne $null) { $method.displayName } else { "N/A" }
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = "Microsoft Authenticator"
Detail = $deviceDisplayName
}
}
else {
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = $authMethodType
Detail = "Additional details not available"
}
}
}
}
}
catch {
Write-Output "Failed to get authentication methods for user: $($user.userPrincipalName)"
Write-Output "Error Details: $($_.Exception.Message)"
$results += [PSCustomObject]@{
UserPrincipalName = $user.userPrincipalName
AuthenticationMethod = "Error"
Detail = "Failed to retrieve authentication methods"
}
}
}
$jsonResults = $results | ConvertTo-Json -Depth 10
Write-Output $jsonResults
2-4. 아래 스크립트를 Powershell 에서 동작시켜 데이터를 사용자별로 그룹화하고 CSV 파일로 내보냅니다.
저장 경로는 Powershell 스크립트를 동작 중인 현재 작업 디렉터리에 저장됩니다.
$userAuthData = @{}
foreach ($result in $results) {
$userPrincipalName = $result.UserPrincipalName
if ($userAuthData.ContainsKey($userPrincipalName)) {
$userAuthData[$userPrincipalName] += $result
} else {
$userAuthData[$userPrincipalName] = @($result)
}
}
$flattenedResults = @()
foreach ($user in $userAuthData.Keys) {
$methods = $userAuthData[$user]
$flattenedEntry = [PSCustomObject]@{
UserPrincipalName = $user
PhoneNumber = "N/A"
Email = "N/A"
Authenticator = "N/A"
}
foreach ($method in $methods) {
if ($method.AuthenticationMethod -eq "Phone Number") {
$flattenedEntry.PhoneNumber = $method.Detail
} elseif ($method.AuthenticationMethod -eq "Email") {
$flattenedEntry.Email = $method.Detail
} elseif ($method.AuthenticationMethod -eq "Microsoft Authenticator") {
$flattenedEntry.Authenticator = $method.Detail
}
}
$flattenedResults += $flattenedEntry
}
$csvFilePath = "UserAuthenticationMethodsFlattened.csv"
$flattenedResults | Export-Csv -Path $csvFilePath -NoTypeInformation
Write-Output "User authentication methods saved to $csvFilePath"
[ 추출 결과 ]