Copy ############################################################
# Example Azure Automation Runbook for exporting data from #
# MS Graph and sending it to an Azure storage account #
############################################################
# Variables
$ProgressPreference = 'SilentlyContinue'
$ResourceGroup = "<my-resource-group>" # Reource group that hosts the storage account
$StorageAccount = "<my-storage-account>" # Storage account name
$Container = "<my-container>" # Container name
$TempFolder = "$env:Temp" # Temp location to save the exported data
$CSVFileName = "Devices.csv" # Name of the exported data file
#############
# FUNCTIONS #
#############
# function to invoke a web request to MS Graph with error handling
Function script:Invoke-LocalGraphRequest {
Param ($URL,$Headers,$Method,$Body,$ContentType)
try {
If ($Method -eq "Post")
{
$WebRequest = Invoke-WebRequest -Uri $URL -Method $Method -Headers $Headers -Body $Body -ContentType $ContentType -UseBasicParsing
}
else
{
$WebRequest = Invoke-WebRequest -Uri $URL -Method $Method -Headers $Headers -UseBasicParsing
}
}
catch {
$WebRequest = $_.Exception.Response
}
Return $WebRequest
}
# function to get managed Windows device data from MS Graph
Function Get-DeviceData {
$URL = "https://graph.microsoft.com/beta/deviceManagement/manageddevices?`$filter=startsWith(operatingSystem,'Windows')&`$select=deviceName,Id,lastSyncDateTime,managementAgent,managementState,osVersion,skuFamily,deviceEnrollmentType,emailAddress,model,manufacturer,serialNumber,userDisplayName,joinType"
$headers = @{'Authorization'="Bearer " + $accessToken}
$GraphRequest = Invoke-LocalGraphRequest -URL $URL -Headers $headers -Method GET
If ($GraphRequest.StatusCode -ne 200)
{
Return $GraphRequest
}
$JsonResponse = $GraphRequest.Content | ConvertFrom-Json
$DeviceData = $JsonResponse.value
If ($JsonResponse.'@odata.nextLink')
{
do {
$URL = $JsonResponse.'@odata.nextLink'
$GraphRequest = Invoke-LocalGraphRequest -URL $URL -Headers $headers -Method GET
If ($GraphRequest.StatusCode -ne 200)
{
Return $GraphRequest
}
$JsonResponse = $GraphRequest.Content | ConvertFrom-Json
$DeviceData += $JsonResponse.value
} until ($null -eq $JsonResponse.'@odata.nextLink')
}
Return $DeviceData
}
####################
## AUTHENTICATION ##
####################
## Get MS Graph access token
# Managed Identity
$url = $env:IDENTITY_ENDPOINT
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER)
$headers.Add("Metadata", "True")
$body = @{resource='https://graph.microsoft.com/' }
$script:accessToken = (Invoke-RestMethod $url -Method 'POST' -Headers $headers -ContentType 'application/x-www-form-urlencoded' -Body $body ).access_token
## Connect to Azure AD
# Mmanaged Identity
$null = Connect-AzAccount -Identity
#########################
## THUNDERBIRDS ARE GO ##
#########################
$Devices = Get-DeviceData
$Devices | Export-Csv -Path $TempFolder\$CSVFileName -NoTypeInformation -Force
$StorageAccount = Get-AzStorageAccount -Name $StorageAccount -ResourceGroupName $ResourceGroup
try {
$null = Set-AzStorageBlobContent -File $TempFolder\$CSVFileName -Container $Container -Blob $CSVFileName -Context $StorageAccount.Context -Force -ErrorAction Stop
}
catch {
Write-Error -Exception $_ -Message "Failed to upload $CSVFileName to blob storage"
}