IntuneのBitLocker回復キー有無リスト2（参加／登録、メールアドレス、ユーザー名）

前回に続き、「参加／登録」「メールアドレス」、「ユーザー名」列を追加。

１．まず[Azure Portal](https://portal.azure.com/#home)でアプリを登録
![bitappreg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/360a896a-ccb5-d985-1aca-7773630581bc.png)
![bitappreg2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/89318d72-0f38-5b7e-8364-dbf527abbcc4.png)
２．アクセス権を設定
![bitappperm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/db9c8fa9-6698-a6c5-0e4c-f7ef2243e497.png)
![bitappperm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/a2f8d453-f680-e6a1-7cac-515ffbea2e7d.png)
３．管理者の承認
![bitapppermAdmin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/775a0808-7590-9197-004f-ab3c70190a26.png)
４．シークレットを作成
![bitappsecret.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24018/3863f2ad-0b5c-16a9-6e45-b1906a2bcb8a.png)
５．おソース

```posh:GetBitLockerRecoverKeys.ps1
$AccountName = "username@onmicrosoft.com"
$AccountPassword = "XXXXXXXXXXXXX"
$ClientId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX"
$ClientSecret = "XXXXXXXXXXXXXXXXXXXXXX"
$TenantID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX"
$GraphUri = "https://graph.microsoft.com"
$GraphVersion = "beta"

Add-Type -AssemblyName System.Web
$ClientSecret = [System.Web.HttpUtility]::UrlEncode($ClientSecret)

# Authentication url
$AzureResourceURI = "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token"

# Construct the Body for the POST
$Body = "grant_type=password"`
 + "&username=" + $Accountname `
 + "&client_id=" + $ClientId `
 + "&client_secret=" + $ClientSecret`
 + "&password=" + $AccountPassword `
 + "&scope=https://graph.microsoft.com/.default"

# The result should contain a token for use with Graph
$Response = Invoke-WebRequest -Uri $AzureResourceURI -Method POST -Body $Body -UseBasicParsing
$ResponseJSON = $Response | ConvertFrom-Json

# Add the token to headers for the Graph request
$Headers = @{
Authorization = "Bearer " + $ResponseJSON.access_token
}

$Body = @{
   grant_type    = "password"
   scope         = "https://graph.microsoft.com/.default"
   client_id     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX"
   client_secret = "XXXXXXXXXXXXXXXXXXXXXX"
   username      = "username@onmicrosoft.com"
   password      = "XXXXXXXXXXXXX"
}

$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID
/oauth2/v2.0/token" -Method POST -Body $Body

$token = $ConnectGraph.access_token

$headr = @{
Authorization = "Bearer $($token)"
'ocp-client-name' = "My Friendly Client"
'ocp-client-version' = "1.2"
}

$GrapGroupUrl = 'https://graph.microsoft.com/beta/bitlocker/recoveryKeys'

$bitlockerkeys = @()
$bitlockerkeysuri = Invoke-RestMethod -Headers $headr -Uri $GrapGroupUrl -Method Get
$bitlockerkeys += $bitlockerkeysuri.value
while ($bitlockerkeysuri.'@odata.nextLink') {
	$NextBatchRequest = $bitlockerkeysuri.'@odata.nextLink'
	$bitlockerkeysuri = Invoke-RestMethod -Uri $NextBatchRequest -Headers $headr -Method Get
	$bitlockerkeys += $bitlockerkeysuri.value
}

# Get all AAD devices and filter out Windows managed by Intune
$AllDevicesArr = @()
$Deviceuri = "$GraphUri/$GraphVersion/deviceManagement/managedDevices?`$filter=operatingSystem eq 'Windows' AND managementState eq 'managed'"
$Devices = Invoke-RestMethod -Uri $Deviceuri -Headers $Headers -Method Get
$AllDevicesArr += $Devices.value
while ($Devices.'@odata.nextLink') {
	$NextBatchRequest = $Devices.'@odata.nextLink'
	$Devices = Invoke-RestMethod -Uri $NextBatchRequest -Headers $Headers -Method Get
	$AllDevicesArr += $Devices.value
}
$Devices2 = $AllDevicesArr | Where-Object {$PSItem.managementType -eq 'MDM'}

# For every managed device check if there is a recovery key in AAD
$Results = @()
try {
	foreach ($device in $Devices2) {
		if (($bitlockerkeys | Where-Object { $PSItem.deviceId -eq $device.azureADDeviceId } | Measure-Object).Count -gt 0) {

				$Results += [PSCustomObject]@{
				    DeviceName       = $device.deviceName
				    joinType         = $device.joinType
				    isEncrypted      = $device.isEncrypted
				    userPrincipalName = $device.userPrincipalName
				    userDisplayName  = $device.userDisplayName
					RecoveryKeyInAAD = $true
					AdditionalInfo   = "$(($bitlockerkeys | Where-Object { $PSItem.deviceId -eq $device.azureADDeviceId } | Measure-Object).Count) keys found"
				}
				
		} else {

				$Results += [PSCustomObject]@{
				    DeviceName       = $device.deviceName
				    joinType         = $device.joinType
				    isEncrypted      = $device.isEncrypted
				    userPrincipalName = $device.userPrincipalName
				    userDisplayName  = $device.userDisplayName
					RecoveryKeyInAAD = $false
					AdditionalInfo   = ''
				}

		}
	}
} catch {
	Write-Error $device
	Write-Error $_
	break
}

$filename = Get-Date -Format "yyyy-MMdd-HHmmss"
[string]$csvFile = "BitLockerRecoverKeysExists_" + $filename + ".csv"
[string]$csvPath = Join-Path "C:\Temp" $csvFile
$Results | select DeviceName,DeviceId,RecoveryKeyInAAD,AdditionalInfo | Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation
invoke-item $csvPath
```

■ネタ元
Verify Azure AD Bitlocker Keys with Microsoft Graph - Maciej Horbacz
https://universecitiz3n.tech/powershell/Graph-Bitlocker/

azure active directory - "Failed to authorize caller, the caller wasn't owner of the device or one of the admin roles." microsoft-graph - Stack Overflow
https://stackoverflow.com/questions/64905676/failed-to-authorize-caller-the-caller-wasnt-owner-of-the-device-or-one-of-the

Intune – Query Azure AD Bitlocker Keys using Graph API – Azure Cloud & AI Domain Blog
https://azurecloudai.blog/2020/11/24/intune-query-azure-ad-bitlocker-keys-using-graph-api/