I am currently working on some automation around Windows Defender, so started to look at the Windows Defender Advanced Threat Protection query API.
Note that this API is still in preview. I wrote two functions for this.
Connect-WindowsATP is used to get an access token. Note that you will need to first register the API in Azure Directory so that you get an Application ID that you have to include at the top of the script.
Get-WinATPData uses the access token to retrieve the data from the API
You will also need the AzureAD PowerShell module installed. The script checks for it’s presence.
Function Connect-WindowsATP { <# .Synopsis Connect-WindowsATP .DESCRIPTION Connect-WindowsATP retrieves an access token to connect to the Defender ATP API .PARAMETER Credential Specifies a user name for the credential, such as foo@corp.org If you omit this parameter, you are prompted for a user name and a password. .EXAMPLE Connect-WindowsATP The above command prompts for user credentials and will then return the access token. .EXMPLE $cr = Get-Credential Connect-WindowsATP -Credential $cr The above command uses the $cr variable as credential input and returns the Access Token. .NOTES # Useful resources i found related to connecting to the Microsoft Graph API # https://www.michev.info/Blog/Post/1771/hacking-your-way-around-modern-authentication-and-the-powershell-modules-for-office-365 # https://www.michev.info/Blog/Post/1771/hacking-your-way-around-modern-authentication-and-the-powershell-modules-for-office-365 # http://www.powershell.no/azure,graph,api/2017/10/30/unattended-ms-graph-api-authentication.html # https://blog.kloud.com.au/2017/05/22/a-quick-start-guide-to-leveraging-the-azure-graph-api-with-powershell-and-oauth-2-0/ # https://docs.microsoft.com/en-us/intune/intune-graph-apis # http://duffney.io/AddCredentialsToPowerShellFunctions .VERSION 1.0, 09.01.2018, alex verboon #> [CmdletBinding()] Param( # Credentials to connect to Microsoft graph i.e. foo@corp.org [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin{ ## !!! ADD YOUR CLIENT ID HERE !!!! ## $client_id = "<CLIENT ID>" # The Azure AD Application ID for Defender ATP Preview # Check if AzureAD PowerShell Module is installed $AadModule = Get-Module -Name "AzureAD" -ListAvailable if ($AadModule -eq $null) { write-host write-host "AzureAD Powershell module not installed..." -f Red write-host "Install by running 'Install-Module AzureAD' from an elevated PowerShell prompt" -f Yellow write-host "Script can't continue..." -f Red write-host Throw } # Getting path to ActiveDirectory Assemblies # If the module count is greater than 1 find the latest version if ($AadModule.count -gt 1) { $Latest_Version = ($AadModule | select version | Sort-Object)[-1] $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" #$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" } else { $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" #$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" } # Load Microsoft.IdentityModel.Clients.ActiveDirectory DLL Add-Type -Path "$adal" # not needed here, but leave the code in anyway. # $cache = [Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache]::DefaultShared # $cache.ReadItems() | select DisplayableId, Authority, ClientId, Resource # $cacheToken = $cache.ReadItems() | Select-Object -ExpandProperty AccessToken } Process{ $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList 'https://login.microsoftonline.com/common/oauth2/token' if($Credential -ne [System.Management.Automation.PSCredential]::Empty) { Write-Verbose "Credentials already provided" } Else { Write-Verbose "No credentials, so prompt user" $Credential = Get-Credential } $AADcredential = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential" -ArgumentList $Credential.UserName,$Credential.Password $authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext,"https://graph.microsoft.com",$client_Id,$AADcredential) $AccessToken = $authResult.Result.AccessToken } End{ If([string]::IsNullOrEmpty($AccessToken)) { write-host "Unable to retrieve Access Token" -f Red } Else { $AccessToken } } }
Function Get-WinATPData { <# .Synopsis Get-WinATPData .DESCRIPTION Get-WinATPData retrieves data from the Windows Defender ATP query APIs. This is just an experimental function to become familiar with retrieving Windows Defender ATP data through the query API. Note! at present the API is in preview mode only: https://graph.microsoft.com/testwdatppreview .EXAMPLE $AToken = Connect-WindowsATP Get-WinATPData -AccessToken $AToken -ATPSource Machine The command first retrrieves an access token and then queries Machine information from Defender ATP .EXAMPLE $AToken = Connect-WindowsATP Get-WinATPData -AccessToken $AToken -ATPSource Alerts The command first retrrieves an access token and then queries Alert information from Defender ATP .EXAMPLE $AToken = Connect-WindowsATP Get-WinATPData -AccessToken $AToken -ATPSource User -UserID Johndoe The command first retrrieves an access token and then queries user information from Defender ATP .NOTES MS docs reference: https://docs.microsoft.com/en-us/windows/threat-protection/windows-defender-atp/supported-apis-windows-defender-advanced-threat-protection version 1.0, 09.01.2018, alex verboon #> [CmdletBinding()] Param( # Access Token [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [string]$AccessToken, # ATP Data Source [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateSet("Machine","User","Alerts")] [string]$ATPSource) # Dynamic Parameters DynamicParam{ If ($ATPSource -eq "User") { $IDAttribute = New-Object System.Management.Automation.ParameterAttribute $IDAttribute.Mandatory = $true #create an attributecollection object for the attributes we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection.Add($IDAttribute) #add our paramater specifying the attribute collection $IDParam = New-Object System.Management.Automation.RuntimeDefinedParameter('UserID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('UserID', $IDParam) return $paramDictionary } } Begin{ If ($PSBoundParameters["AccessToken"]) { Write-Verbose "Access Token was provided" $Authorization = [pscustomobject]@{ access_token = "$accessToken" } } Else { # should not happen since require validate the parameter and to be not empty Throw } Switch ($ATPSource) { "Machine" {$atpuri = "https://graph.microsoft.com/testwdatppreview/machines"} "User" {$atpuri = ('https://graph.microsoft.com/testwdatppreview/users/USERID').Replace("USERID","$($IDParam.value)")} "Alerts" {$atpuri = "https://graph.microsoft.com/testwdatppreview/alerts"} } } Process{ Write-Verbose "ATP DataSource: $ATPSource" Write-Verbose "ATP URI: $atpuri" # Retrieve the data Try{ $ATPData = Invoke-RestMethod -Headers @{Authorization =("Bearer "+ $Authorization.access_token)} -Uri $atpUri } Catch{ Write-host "StatusCode:" $_.Exception.Response.StatusCode.value__ Write-host "StatusDescription:" $_.Exception.Response.StatusDescription } } End{ Switch ($ATPSource) { "Machine" {$result = $ATPData.value} "User" {$result = $ATPData} "Alerts" {$result = $ATPData.value} } $result } }
Have fun querying the Windows Defender ATP query API
Thanks for writing this Alex. Do you have an updated one, I don’t think the AzureAD module is still a thing – so it fails to run and fails to download those modules.
Hi, yes, take a look at my PSMDATP PowerShell module
https://github.com/alexverboon/PSMDATP