Created
October 30, 2019 12:24
-
-
Save AlexAsplund/8876454d9c25668942a012c158fcef1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
# User = ClientId Pass = Secret | |
[parameter(Mandatory)] | |
[PSCredential]$Credential, | |
[parameter(Mandatory)] | |
$TenantName | |
[parameter(Mandatory)] | |
$GelfServer | |
) | |
Import-Module PSGELF | |
<# | |
.SYNOPSIS | |
Gets a graph access token | |
.DESCRIPTION | |
Gets a graph access token with client credentials. | |
You need to create a new app in azure AD and supply it [pscredential]$ClientCredential. | |
Username = application id | |
Password = Application key/client secret | |
.EXAMPLE | |
PS C:\> Get-MyAADAccessToken -ClientCredential $Credential -TenantName contoso.onmicrosoft.com | |
Explanation of what the example does | |
#> | |
Function Get-MyAADAccessToken { | |
param( | |
# application secrets. Username = application id, password = client secret | |
[parameter(Mandatory)] | |
[PSCredential]$ClientCredential, | |
# Name of your tenant. ie contoso.onmicrosoft.com | |
[parameter(Mandatory)] | |
[string]$TenantName | |
) | |
Add-Type -AssemblyName System.Web | |
# Decode securestring | |
$SecureString = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($ClientCredential.password) | |
$Password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($SecureString) | |
[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($SecureString) | |
$BodyList = @( | |
"client_id=$([System.Web.HttpUtility]::UrlEncode($ClientCredential.UserName))" | |
"scope=https%3A%2F%2Fgraph.microsoft.com%2F.default" | |
"client_secret=$([System.Web.HttpUtility]::UrlEncode($Password))", | |
"grant_type=client_credentials" | |
) | |
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" | |
$PostSplat = @{ | |
ContentType = 'application/x-www-form-urlencoded' | |
Method = 'POST' | |
Body = ($BodyList -join '&') | |
Uri = $Url | |
} | |
$Request = Invoke-RestMethod @PostSplat | |
return $Request | |
} | |
Function Get-UnixTimeStamp($Date){ | |
(New-TimeSpan -Start (Get-Date "01/01/1970") -End ($Date)).TotalSeconds | |
} | |
Function Flatten-Object { # https://powersnippets.com/flatten-object/ | |
[CmdletBinding()]Param ( # Version 02.00.16, by iRon | |
[Parameter(ValueFromPipeLine = $True)][Object[]]$Objects, | |
[String]$Separator = ".", [ValidateSet("", 0, 1)]$Base = 1, [Int]$Depth = 5, [Int]$Uncut = 1, | |
[String[]]$ToString = ([String], [DateTime], [TimeSpan], [Version], [Enum]), [String[]]$Path = @() | |
) | |
$PipeLine = $Input | ForEach {$_}; If ($PipeLine) {$Objects = $PipeLine} | |
If (@(Get-PSCallStack)[1].Command -eq $MyInvocation.MyCommand.Name -or @(Get-PSCallStack)[1].Command -eq "<position>") { | |
$Object = @($Objects)[0]; $Iterate = New-Object System.Collections.Specialized.OrderedDictionary | |
If ($ToString | Where {$Object -is $_}) {$Object = $Object.ToString()} | |
ElseIf ($Depth) {$Depth-- | |
If ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IDictionaryEnumerator[\W]") { | |
$Iterate = $Object | |
} ElseIf ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IEnumerator[\W]") { | |
$Object.GetEnumerator() | ForEach -Begin {$i = $Base} {$Iterate.($i) = $_; $i += 1} | |
} Else { | |
$Names = If ($Uncut) {$Uncut--} Else {$Object.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames} | |
If (!$Names) {$Names = $Object.PSObject.Properties | Where {$_.IsGettable} | Select -Expand Name} | |
If ($Names) {$Names | ForEach {$Iterate.$_ = $Object.$_}} | |
} | |
} | |
If (@($Iterate.Keys).Count) { | |
$Iterate.Keys | ForEach { | |
Flatten-Object @(,$Iterate.$_) $Separator $Base $Depth $Uncut $ToString ($Path + $_) | |
} | |
} Else {$Property.(($Path | Where {$_}) -Join $Separator) = $Object} | |
} ElseIf ($Objects -ne $Null) { | |
@($Objects) | ForEach -Begin {$Output = @(); $Names = @()} { | |
New-Variable -Force -Option AllScope -Name Property -Value (New-Object System.Collections.Specialized.OrderedDictionary) | |
Flatten-Object @(,$_) $Separator $Base $Depth $Uncut $ToString $Path | |
$Output += New-Object PSObject -Property $Property | |
$Names += $Output[-1].PSObject.Properties | Select -Expand Name | |
} | |
$Output | Select ([String[]]($Names | Select -Unique)) | |
} | |
} | |
$AccessToken = (Get-MyAADAccessToken -TenantName $TenantName -ClientCredential $Credential).access_token | |
$Header = @{ | |
Authorization = 'Bearer '+$AccessToken | |
} | |
if(!(Test-Path $PSScriptRoot\LastActivity.txt)){ | |
$FromDate = (get-date -Hour 0 -minute 0 -Second 0 -Millisecond 0 -format "yyyy-MM-dd") | |
} | |
else{ | |
$FromDate = Cat $PSScriptRoot\lastactivity.txt -Encoding UTF8 | |
if([string]::IsNullOrEmpty($FromDate)){ | |
$FromDate = (get-date -Hour 0 -minute 0 -Second 0 -Millisecond 0 -format "yyyy-MM-dd") | |
} | |
} | |
$Events = @() | |
$Request = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/security/alerts?`$filter=eventDateTime ge $FromDate" -Headers $Header | |
$Events += $Request.value | |
while($Request.'@odata.nextLink' -ne $null){ | |
$Request = Invoke-RestMethod -Uri $Request.'@odata.nextLink' -Headers $Header | |
Write-Output $Request.'@odata.nextLink' | |
$Events += $Request.Value | |
$More = $Request.'@odata.nextLink' -ne $null | |
} | |
$n = 0 | |
$c = ($Events | measure).Count | |
foreach($Event in $Events){ | |
$NewEvent = [PSCustomObject]@{ | |
Message = $Event.Title + "|" +$Event.description | |
json = $Event | flatten-object | ConvertTo-Json -Depth 20 | |
Type = "AzureAlerts" | |
host = 'AzureAlerts' | |
} | |
$NewEvent | Send-PSGelfTCPFromObject -GelfServer GelfServer -Port 12201 | |
$n;$n++ | |
} | |
Write-Output "Sent $(($Events | Measure).Count) events" | |
$LastEvent = $Events.eventDateTime | ? {![string]::IsNullOrEmpty($_)} | sort | select -last 1 | |
if(![string]::IsNullOrEmpty($LastEvent)){ | |
$LastEvent | Out-File -Encoding utf8 -FilePath $PSScriptRoot\lastactivity.txt | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment