From b190081ca6c06e675a05e46c48bc311ad5ed5a86 Mon Sep 17 00:00:00 2001 From: Pouyan Khabazi Date: Thu, 19 Nov 2020 20:00:46 +0100 Subject: [PATCH] !Deploy Release Version 0.6.15 (#141) * Release '0.6.2' (#31) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * cleaning up * Release Update Incident function (#37) * init release update incident function * cleaning up * updating * updating incident function * code cleanup * Cleaning up and ready for release * updating final docs folder * Release Feature playbook configuration (#33) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * init release for playbook * cleaning up * finishing playbook * adding get alert rule action function * releasing get logic app function * release new- az sen alert action and some codue update * init release playbook function * uppdated gitignore * init release remove azsentinel action rule * fixed compare issue * Merge branch 'development' of github.com:wortell/AZSentinel into feature/playbook * updating pester test result * updating readme * updating readme * updated docs and pester test results * restoring version * Fix/smallconflicts (#40) * updating docs * updating examples * updating pipeline * fixing Subscribtion parameter for playbook (#43) * fixing Subscribtion parameter for playbook (#45) * Fix- get-Azsentinalhuntingrule - Cannot validate argument on parameter "Property" (#50) * fix huntng rule * fixing hunting rule issue * Fix - new-azsentinelalertrule playbook property (#49) * fixing the if statement * fixing the if statement * Feature - get all incidents (#51) * updating get incident * updating get incident function and docs * updating powershell-yaml * updating importmodule error * workaround * removing powershell-yaml depending * fixing logicapp sas token (#52) * Add support for day time periods (#61) * Add missing dot to yml file extension (#59) The Import-AZSentinelAlertRule function is not able to import yml files due to missing dot in the file extension. * adding support for resource provider in set-azsentinel (#69) * New function for enabling and disabling Alert rules (#71) * init release enable and disable function * adding empty test files * updating return message * New feature change the displayName of an alert (#68) * Release Rename Alert rule function * updating rename function * Handle nextLink for Playbooks (#78) When retrieving playbooks not all are being returned. Code copied from Issue #35 Retrieving all incidents. * adding support for alert aggregation (#65) * adding support for alert aggregation, classes created * updaing classes * updated the class and created first rule wih no error * update class and made import function backwards compatible * small changes * tested with import method * updating new function * checking working code, starting cleanup * updating documentation * updating docs and cleaning up * updating build errors * change pester version * updating pester version * Update groupingConfiguration.ps1 (#87) * Fix bug that causes loss of certain incident properties, add option to set incident description (#91) * Feature - Adding support for all alert rule types (#90) * init release * updating docs Co-authored-by: Khabazi * New Functionality to get alert rule templates provided by Microsoft (#94) Co-authored-by: Antonio Ramirez * Update/get az sentinel alert rule templates (#95) * udating Get-AzSentinelAlertRuleTemplates * updated Co-authored-by: Khabazi * Feature/add az sentinel incident comment (#96) * udating Get-AzSentinelAlertRuleTemplates * updated * fixing playbook issue * Add-AzSentinelIncidentComment * release Co-authored-by: Khabazi * fixing class error (#99) * updating example files, ncluding multi rule yaml file (#104) * Fix - Get-AzSentinelAlertRuleAction doesn't return playbookName (#102) * fixing return issue * fixing playbook issue * init release Get-AzSentinelDataConnector function (#103) * Fix - get-azsentinelhuntingrule updated get and remove function (#106) * fixing hunitng rule get and remove issue * cleaning up * updating filters * Add filtering by lastModified (#107) * updating AggregationKind class and enum (#111) * Release of Import-AzSentinelDataConnector function (#116) * extra check for Import-AzSentinelDataConnector * fixing class issue (#118) * New function: Export-AzSentinel (#121) * init code * Release Export-AzSentinel and some small fixes/updates * fixing SeveritiesFilter issue for MicrosoftSecurityIncidentCreation (#122) * updating Get-AzSentinelAlertRule function and docs (#125) * modified token expiration logic (#135) Co-authored-by: John Crouch * fixing small issues (#136) * Fixing issue when switching from subscription (#140) * !Deploy Release version 0.6.14 (#137) * Release '0.6.2' (#31) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * cleaning up * Release Update Incident function (#37) * init release update incident function * cleaning up * updating * updating incident function * code cleanup * Cleaning up and ready for release * updating final docs folder * Release Feature playbook configuration (#33) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * init release for playbook * cleaning up * finishing playbook * adding get alert rule action function * releasing get logic app function * release new- az sen alert action and some codue update * init release playbook function * uppdated gitignore * init release remove azsentinel action rule * fixed compare issue * Merge branch 'development' of github.com:wortell/AZSentinel into feature/playbook * updating pester test result * updating readme * updating readme * updated docs and pester test results * restoring version * Fix/smallconflicts (#40) * updating docs * updating examples * updating pipeline * fixing Subscribtion parameter for playbook (#43) * fixing Subscribtion parameter for playbook (#45) * Fix- get-Azsentinalhuntingrule - Cannot validate argument on parameter "Property" (#50) * fix huntng rule * fixing hunting rule issue * Fix - new-azsentinelalertrule playbook property (#49) * fixing the if statement * fixing the if statement * Feature - get all incidents (#51) * updating get incident * updating get incident function and docs * updating powershell-yaml * updating importmodule error * workaround * removing powershell-yaml depending * fixing logicapp sas token (#52) * Add support for day time periods (#61) * Add missing dot to yml file extension (#59) The Import-AZSentinelAlertRule function is not able to import yml files due to missing dot in the file extension. * adding support for resource provider in set-azsentinel (#69) * New function for enabling and disabling Alert rules (#71) * init release enable and disable function * adding empty test files * updating return message * New feature change the displayName of an alert (#68) * Release Rename Alert rule function * updating rename function * Handle nextLink for Playbooks (#78) When retrieving playbooks not all are being returned. Code copied from Issue #35 Retrieving all incidents. * adding support for alert aggregation (#65) * adding support for alert aggregation, classes created * updaing classes * updated the class and created first rule wih no error * update class and made import function backwards compatible * small changes * tested with import method * updating new function * checking working code, starting cleanup * updating documentation * updating docs and cleaning up * updating build errors * change pester version * updating pester version * Update groupingConfiguration.ps1 (#87) * Fix bug that causes loss of certain incident properties, add option to set incident description (#91) * Feature - Adding support for all alert rule types (#90) * init release * updating docs Co-authored-by: Khabazi * New Functionality to get alert rule templates provided by Microsoft (#94) Co-authored-by: Antonio Ramirez * Update/get az sentinel alert rule templates (#95) * udating Get-AzSentinelAlertRuleTemplates * updated Co-authored-by: Khabazi * Feature/add az sentinel incident comment (#96) * udating Get-AzSentinelAlertRuleTemplates * updated * fixing playbook issue * Add-AzSentinelIncidentComment * release Co-authored-by: Khabazi * fixing class error (#99) * updating example files, ncluding multi rule yaml file (#104) * Fix - Get-AzSentinelAlertRuleAction doesn't return playbookName (#102) * fixing return issue * fixing playbook issue * init release Get-AzSentinelDataConnector function (#103) * Fix - get-azsentinelhuntingrule updated get and remove function (#106) * fixing hunitng rule get and remove issue * cleaning up * updating filters * Add filtering by lastModified (#107) * updating AggregationKind class and enum (#111) * Release of Import-AzSentinelDataConnector function (#116) * extra check for Import-AzSentinelDataConnector * fixing class issue (#118) * New function: Export-AzSentinel (#121) * init code * Release Export-AzSentinel and some small fixes/updates * fixing SeveritiesFilter issue for MicrosoftSecurityIncidentCreation (#122) * updating Get-AzSentinelAlertRule function and docs (#125) * modified token expiration logic (#135) Co-authored-by: John Crouch * fixing small issues (#136) Co-authored-by: pemontto <939704+pemontto@users.noreply.github.com> Co-authored-by: NVolcz Co-authored-by: stehod <34159548+stehod@users.noreply.github.com> Co-authored-by: ThijsLecomte <42153270+ThijsLecomte@users.noreply.github.com> Co-authored-by: Jonathan Holtmann Co-authored-by: Khabazi Co-authored-by: ramirezversion <34833071+ramirezversion@users.noreply.github.com> Co-authored-by: Antonio Ramirez Co-authored-by: John Crouch <50185606+john-crouch@users.noreply.github.com> Co-authored-by: John Crouch * fixing issue when switching from subscription * fixing subscription precheck issue * restore Co-authored-by: pemontto <939704+pemontto@users.noreply.github.com> Co-authored-by: NVolcz Co-authored-by: stehod <34159548+stehod@users.noreply.github.com> Co-authored-by: ThijsLecomte <42153270+ThijsLecomte@users.noreply.github.com> Co-authored-by: Jonathan Holtmann Co-authored-by: Khabazi Co-authored-by: ramirezversion <34833071+ramirezversion@users.noreply.github.com> Co-authored-by: Antonio Ramirez Co-authored-by: John Crouch <50185606+john-crouch@users.noreply.github.com> Co-authored-by: John Crouch * Fixing issue with Fusion rules (#143) * MSSP Playbook (#142) * !Deploy Release version 0.6.14 (#137) * Release '0.6.2' (#31) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * cleaning up * Release Update Incident function (#37) * init release update incident function * cleaning up * updating * updating incident function * code cleanup * Cleaning up and ready for release * updating final docs folder * Release Feature playbook configuration (#33) * updating get alert and hunting rule function * updated error handling * Create Get-PlayBook.ps1 * init release for playbook * cleaning up * finishing playbook * adding get alert rule action function * releasing get logic app function * release new- az sen alert action and some codue update * init release playbook function * uppdated gitignore * init release remove azsentinel action rule * fixed compare issue * Merge branch 'development' of github.com:wortell/AZSentinel into feature/playbook * updating pester test result * updating readme * updating readme * updated docs and pester test results * restoring version * Fix/smallconflicts (#40) * updating docs * updating examples * updating pipeline * fixing Subscribtion parameter for playbook (#43) * fixing Subscribtion parameter for playbook (#45) * Fix- get-Azsentinalhuntingrule - Cannot validate argument on parameter "Property" (#50) * fix huntng rule * fixing hunting rule issue * Fix - new-azsentinelalertrule playbook property (#49) * fixing the if statement * fixing the if statement * Feature - get all incidents (#51) * updating get incident * updating get incident function and docs * updating powershell-yaml * updating importmodule error * workaround * removing powershell-yaml depending * fixing logicapp sas token (#52) * Add support for day time periods (#61) * Add missing dot to yml file extension (#59) The Import-AZSentinelAlertRule function is not able to import yml files due to missing dot in the file extension. * adding support for resource provider in set-azsentinel (#69) * New function for enabling and disabling Alert rules (#71) * init release enable and disable function * adding empty test files * updating return message * New feature change the displayName of an alert (#68) * Release Rename Alert rule function * updating rename function * Handle nextLink for Playbooks (#78) When retrieving playbooks not all are being returned. Code copied from Issue #35 Retrieving all incidents. * adding support for alert aggregation (#65) * adding support for alert aggregation, classes created * updaing classes * updated the class and created first rule wih no error * update class and made import function backwards compatible * small changes * tested with import method * updating new function * checking working code, starting cleanup * updating documentation * updating docs and cleaning up * updating build errors * change pester version * updating pester version * Update groupingConfiguration.ps1 (#87) * Fix bug that causes loss of certain incident properties, add option to set incident description (#91) * Feature - Adding support for all alert rule types (#90) * init release * updating docs Co-authored-by: Khabazi * New Functionality to get alert rule templates provided by Microsoft (#94) Co-authored-by: Antonio Ramirez * Update/get az sentinel alert rule templates (#95) * udating Get-AzSentinelAlertRuleTemplates * updated Co-authored-by: Khabazi * Feature/add az sentinel incident comment (#96) * udating Get-AzSentinelAlertRuleTemplates * updated * fixing playbook issue * Add-AzSentinelIncidentComment * release Co-authored-by: Khabazi * fixing class error (#99) * updating example files, ncluding multi rule yaml file (#104) * Fix - Get-AzSentinelAlertRuleAction doesn't return playbookName (#102) * fixing return issue * fixing playbook issue * init release Get-AzSentinelDataConnector function (#103) * Fix - get-azsentinelhuntingrule updated get and remove function (#106) * fixing hunitng rule get and remove issue * cleaning up * updating filters * Add filtering by lastModified (#107) * updating AggregationKind class and enum (#111) * Release of Import-AzSentinelDataConnector function (#116) * extra check for Import-AzSentinelDataConnector * fixing class issue (#118) * New function: Export-AzSentinel (#121) * init code * Release Export-AzSentinel and some small fixes/updates * fixing SeveritiesFilter issue for MicrosoftSecurityIncidentCreation (#122) * updating Get-AzSentinelAlertRule function and docs (#125) * modified token expiration logic (#135) Co-authored-by: John Crouch * fixing small issues (#136) Co-authored-by: pemontto <939704+pemontto@users.noreply.github.com> Co-authored-by: NVolcz Co-authored-by: stehod <34159548+stehod@users.noreply.github.com> Co-authored-by: ThijsLecomte <42153270+ThijsLecomte@users.noreply.github.com> Co-authored-by: Jonathan Holtmann Co-authored-by: Khabazi Co-authored-by: ramirezversion <34833071+ramirezversion@users.noreply.github.com> Co-authored-by: Antonio Ramirez Co-authored-by: John Crouch <50185606+john-crouch@users.noreply.github.com> Co-authored-by: John Crouch * init test * ready for release Co-authored-by: pemontto <939704+pemontto@users.noreply.github.com> Co-authored-by: NVolcz Co-authored-by: stehod <34159548+stehod@users.noreply.github.com> Co-authored-by: ThijsLecomte <42153270+ThijsLecomte@users.noreply.github.com> Co-authored-by: Jonathan Holtmann Co-authored-by: Khabazi Co-authored-by: ramirezversion <34833071+ramirezversion@users.noreply.github.com> Co-authored-by: Antonio Ramirez Co-authored-by: John Crouch <50185606+john-crouch@users.noreply.github.com> Co-authored-by: John Crouch Co-authored-by: pemontto <939704+pemontto@users.noreply.github.com> Co-authored-by: NVolcz Co-authored-by: stehod <34159548+stehod@users.noreply.github.com> Co-authored-by: ThijsLecomte <42153270+ThijsLecomte@users.noreply.github.com> Co-authored-by: Jonathan Holtmann Co-authored-by: Khabazi Co-authored-by: ramirezversion <34833071+ramirezversion@users.noreply.github.com> Co-authored-by: Antonio Ramirez Co-authored-by: John Crouch <50185606+john-crouch@users.noreply.github.com> Co-authored-by: John Crouch --- AzSentinel/Classes/AlertRule.ps1 | 2 +- AzSentinel/Classes/ScheduledAlertProp.ps1 | 6 ++- AzSentinel/Private/Get-AuthToken.ps1 | 31 ++++++------- AzSentinel/Private/Get-AzSentinelPlayBook.ps1 | 15 +++++-- AzSentinel/Private/precheck.ps1 | 28 +++++++----- .../Public/Get-AzSentinelAlertRuleAction.ps1 | 4 +- .../Public/Import-AzSentinelAlertRule.ps1 | 12 ++--- .../Public/New-AzSentinelAlertRuleAction.ps1 | 19 ++++---- README.md | 44 +++++++++---------- examples/AlertRules.json | 4 +- 10 files changed, 89 insertions(+), 76 deletions(-) diff --git a/AzSentinel/Classes/AlertRule.ps1 b/AzSentinel/Classes/AlertRule.ps1 index 1677ea7..0be892e 100644 --- a/AzSentinel/Classes/AlertRule.ps1 +++ b/AzSentinel/Classes/AlertRule.ps1 @@ -1,5 +1,5 @@ class AlertRule { - [guid] $Name + [string] $Name [string] $Etag diff --git a/AzSentinel/Classes/ScheduledAlertProp.ps1 b/AzSentinel/Classes/ScheduledAlertProp.ps1 index 28eb100..c5f4176 100644 --- a/AzSentinel/Classes/ScheduledAlertProp.ps1 +++ b/AzSentinel/Classes/ScheduledAlertProp.ps1 @@ -92,7 +92,11 @@ class ScheduledAlertProp { } $this.SuppressionEnabled = if ($suppressionEnabled) { $suppressionEnabled } else { $false } $this.Tactics = $Tactics - $this.PlaybookName = $PlaybookName + $this.PlaybookName = if ($PlaybookName.Split('/').count -gt 1){ + $PlaybookName.Split('/')[-1] + } else { + $PlaybookName + } $this.IncidentConfiguration = $IncidentConfiguration $this.eventGroupingSettings = @{ aggregationKind = if ($aggregationKind) { $aggregationKind } else { "SingleAlert" } diff --git a/AzSentinel/Private/Get-AuthToken.ps1 b/AzSentinel/Private/Get-AuthToken.ps1 index cc8d395..a809b36 100644 --- a/AzSentinel/Private/Get-AuthToken.ps1 +++ b/AzSentinel/Private/Get-AuthToken.ps1 @@ -13,24 +13,21 @@ function Get-AuthToken { [CmdletBinding()] param ( - ) - try { - $azContext = Get-AzContext - - if ($null -ne $azContext) { - Write-Verbose -Message "Using Subscription: $($azContext.Subscription.Name) from tenant $($azContext.Tenant.Id)" - - $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile - $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient]::new($azProfile) - $script:accessToken = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId) - $script:subscriptionId = $azContext.Subscription.Id - $script:tenantId = $azContext.Tenant.Id - } else { - throw 'No subscription available, Please use Connect-AzAccount to login and select the right subscription' - } - } catch { - $PSCmdlet.ThrowTerminatingError($_) + $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile + + Write-Verbose -Message "Using Subscription: $($azProfile.DefaultContext.Subscription.Name) from tenant $($azProfile.DefaultContext.Tenant.Id)" + + $script:subscriptionId = $azProfile.DefaultContext.Subscription.Id + $script:tenantId = $azProfile.DefaultContext.Tenant.Id + + $profileClient = [Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient]::new($azProfile) + $script:accessToken = $profileClient.AcquireAccessToken($script:tenantId) + + $script:authHeader = @{ + 'Content-Type' = 'application/json' + Authorization = 'Bearer ' + $script:accessToken.AccessToken } + } diff --git a/AzSentinel/Private/Get-AzSentinelPlayBook.ps1 b/AzSentinel/Private/Get-AzSentinelPlayBook.ps1 index 2e2cbb2..7332bc7 100644 --- a/AzSentinel/Private/Get-AzSentinelPlayBook.ps1 +++ b/AzSentinel/Private/Get-AzSentinelPlayBook.ps1 @@ -20,9 +20,9 @@ function Get-AzSentinelPlayBook { param ( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] - [string] $SubscriptionId, + [string]$SubscriptionId, - [Parameter(Mandatory)] + [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Name ) @@ -35,7 +35,11 @@ function Get-AzSentinelPlayBook { $triggerName = 'When_a_response_to_an_Azure_Sentinel_alert_is_triggered' - if ($SubscriptionId) { + if ($Name.Split('/').count -gt 1) { + $uri = "https://management.azure.com/subscriptions/$($Name.Split('/')[2])/providers/Microsoft.Logic/workflows?api-version=2016-06-01" + $Name = $Name.Split('/')[-1] + } + elseif ($SubscriptionId) { Write-Verbose "Getting LogicApp from Subscription $($subscriptionId)" $uri = "https://management.azure.com/subscriptions/$($subscriptionId)/providers/Microsoft.Logic/workflows?api-version=2016-06-01" } @@ -51,12 +55,15 @@ function Get-AzSentinelPlayBook { try { $logicappRaw = (Invoke-RestMethod -Uri $uri -Method Get -Headers $script:authHeader) $logicapp = $logicappRaw.value + while ($logicappRaw.nextLink) { $logicappRaw = (Invoke-RestMethod -Uri $($logicappRaw.nextLink) -Headers $script:authHeader -Method Get) $logicapp += $logicappRaw.value } + $playBook = $logicapp | Where-Object { $_.name -eq $Name } - if ($playBook){ + + if ($playBook) { $uri1 = "https://management.azure.com$($playBook.id)/triggers/$($triggerName)/listCallbackUrl?api-version=2016-06-01" try { $playbookTrigger = (Invoke-RestMethod -Uri $uri1 -Method Post -Headers $script:authHeader) diff --git a/AzSentinel/Private/precheck.ps1 b/AzSentinel/Private/precheck.ps1 index 19b89f7..847442b 100644 --- a/AzSentinel/Private/precheck.ps1 +++ b/AzSentinel/Private/precheck.ps1 @@ -2,7 +2,7 @@ #requires -version 6.2 function precheck { - <# + <# .SYNOPSIS PreCheck .DESCRIPTION @@ -14,16 +14,22 @@ function precheck { NAME: precheck #> - if ($null -eq $script:accessToken) { - Get-AuthToken - } - elseif ($script:accessToken.ExpiresOn.DateTime - [datetime]::UtcNow.AddMinutes(-5) -le 0) { - # if token expires within 5 minutes, request a new one - Get-AuthToken - } + $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile - $script:authHeader = @{ - 'Content-Type' = 'application/json' - Authorization = 'Bearer ' + $script:accessToken.AccessToken + if ($azProfile.Contexts.Count -ne 0) { + if ($null -eq $script:accessToken ) { + Get-AuthToken + } + elseif ($script:accessToken.ExpiresOn.DateTime - [datetime]::UtcNow.AddMinutes(-5) -le 0) { + # if token expires within 5 minutes, request a new one + Get-AuthToken + } + + # Set the subscription from AzContext + $script:subscriptionId = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext.Subscription.Id + } + else { + Write-Error 'No subscription available, Please use Connect-AzAccount to login and select the right subscription' + break } } diff --git a/AzSentinel/Public/Get-AzSentinelAlertRuleAction.ps1 b/AzSentinel/Public/Get-AzSentinelAlertRuleAction.ps1 index 75cc743..fffbf15 100644 --- a/AzSentinel/Public/Get-AzSentinelAlertRuleAction.ps1 +++ b/AzSentinel/Public/Get-AzSentinelAlertRuleAction.ps1 @@ -25,11 +25,11 @@ function Get-AzSentinelAlertRuleAction { [Parameter(Mandatory = $false, ParameterSetName = "Sub")] [ValidateNotNullOrEmpty()] - [string] $SubscriptionId, + [string]$SubscriptionId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] - [string] $WorkspaceName, + [string]$WorkspaceName, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] diff --git a/AzSentinel/Public/Import-AzSentinelAlertRule.ps1 b/AzSentinel/Public/Import-AzSentinelAlertRule.ps1 index 22ad279..2fcf59a 100644 --- a/AzSentinel/Public/Import-AzSentinelAlertRule.ps1 +++ b/AzSentinel/Public/Import-AzSentinelAlertRule.ps1 @@ -135,7 +135,7 @@ function Import-AzSentinelAlertRule { $guid = (New-Guid).Guid - $content = $allRulesContent | Where-Object displayName -eq $item.displayName + $content = $allRulesContent | Where-Object {$_.kind -eq 'Scheduled' -and $_.displayName -eq $item.displayName} Write-Verbose -Message "Get rule $($item.description)" @@ -204,11 +204,11 @@ function Import-AzSentinelAlertRule { $result = Invoke-webrequest -Uri $uri -Method Put -Headers $script:authHeader -Body ($body | Select-Object * -ExcludeProperty Properties.PlaybookName | ConvertTo-Json -Depth 10 -EnumsAsStrings) if (($compareResult | Where-Object PropertyName -eq "playbookName").DiffValue) { - $PlaybookResult = New-AzSentinelAlertRuleAction @arguments -PlayBookName ($body.Properties.playbookName) -RuleId $($body.Name) + $PlaybookResult = New-AzSentinelAlertRuleAction @arguments -PlayBookName ($item.playbookName) -RuleId $($body.Name) $body.Properties | Add-Member -NotePropertyName PlaybookStatus -NotePropertyValue $PlaybookResult -Force } elseif (($compareResult | Where-Object PropertyName -eq "playbookName").RefValue) { - $PlaybookResult = Remove-AzSentinelAlertRuleAction @arguments -RuleId $($body.Name) -Confirm:$false + $PlaybookResult = Remove-AzSentinelAlertRuleAction @arguments -RuleId $body.Name -Confirm:$false $body.Properties | Add-Member -NotePropertyName PlaybookStatus -NotePropertyValue $PlaybookResult -Force } else { @@ -261,7 +261,7 @@ function Import-AzSentinelAlertRule { $guid = (New-Guid).Guid - $content = $allRulesContent | Where-Object displayName -eq $item.displayName + $content = $allRulesContent | Where-Object {$_.kind -eq 'Fusion' -and $_.displayName -eq $item.displayName} Write-Verbose -Message "Get rule $($item.description)" @@ -314,7 +314,7 @@ function Import-AzSentinelAlertRule { $guid = (New-Guid).Guid - $content = $allRulesContent | Where-Object displayName -eq $item.displayName + $content = $allRulesContent | Where-Object {$_.kind -eq 'MLBehaviorAnalytics' -and $_.displayName -eq $item.displayName} Write-Verbose -Message "Get rule $($item.description)" @@ -368,7 +368,7 @@ function Import-AzSentinelAlertRule { $guid = (New-Guid).Guid - $content = $allRulesContent | Where-Object displayName -eq $item.displayName + $content = $allRulesContent | Where-Object {$_.kind -eq 'MicrosoftSecurityIncidentCreation' -and $_.displayName -eq $item.displayName} Write-Verbose -Message "Get rule $($item.description)" $content = Get-AzSentinelAlertRule @arguments -RuleName $($item.displayName) -ErrorAction SilentlyContinue diff --git a/AzSentinel/Public/New-AzSentinelAlertRuleAction.ps1 b/AzSentinel/Public/New-AzSentinelAlertRuleAction.ps1 index 40fc496..d73f04f 100644 --- a/AzSentinel/Public/New-AzSentinelAlertRuleAction.ps1 +++ b/AzSentinel/Public/New-AzSentinelAlertRuleAction.ps1 @@ -28,15 +28,15 @@ function New-AzSentinelAlertRuleAction { [Parameter(Mandatory = $false, ParameterSetName = "Sub")] [ValidateNotNullOrEmpty()] - [string] $SubscriptionId, + [string]$SubscriptionId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] - [string] $WorkspaceName, + [string]$WorkspaceName, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] - [string] $PlayBookName, + [string]$PlayBookName, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] @@ -73,6 +73,7 @@ function New-AzSentinelAlertRuleAction { $action = $null + if ($SubscriptionId) { $playBook = Get-AzSentinelPlayBook -SubscriptionId $SubscriptionId -Name $PlayBookName } @@ -82,8 +83,7 @@ function New-AzSentinelAlertRuleAction { $action = Get-AzSentinelAlertRuleAction @arguments -RuleId $alertId -ErrorAction SilentlyContinue - - if ($null -eq $action) { + if (($null -eq $action) -or ((($action.properties.logicAppResourceId).Split('/')[-1]) -ne $PlayBookName.Split('/')[-1])) { $guid = New-Guid $body = @{ @@ -98,6 +98,7 @@ function New-AzSentinelAlertRuleAction { } $uri = "$($Script:baseUri)/providers/Microsoft.SecurityInsights/alertRules/$($alertId)/actions/$($guid)?api-version=2019-01-01-preview" + try { $return = Invoke-WebRequest -Method Put -Uri $uri -Headers $Script:authHeader -Body ($body | ConvertTo-Json -Depth 10) Write-Verbose "Successfully created Action for Rule: $($RuleName) with Playbook $($PlayBookName) Status: $($return.StatusDescription)" @@ -105,16 +106,14 @@ function New-AzSentinelAlertRuleAction { } catch { Write-Error "Unable to create Action for Rule: $($RuleName) with Playbook $($PlayBookName) Error: $($_.Exception.Message)" + Write-Verbose $_ return $_.Exception.Message - Write-Verbose $_. } } elseif ((($action.properties.logicAppResourceId).Split('/')[-1]) -eq $PlayBookName) { - Write-Output "Alert Rule: $($alertId) has already playbook assigned: $(($action.properties.logicAppResourceId).Split('/')[-1])" - } - elseif ((($action.properties.logicAppResourceId).Split('/')[-1]) -ne $PlayBookName) { - Write-Output "Alert rule $($RuleName) assigned to a different playbook with name $(($action.properties.logicAppResourceId).Split('/')[-1])" + Write-Output "Alert Rule: $($alertId) is already assigned to playbook: $(($action.properties.logicAppResourceId).Split('/')[-1])" } + else { #nothing? } diff --git a/README.md b/README.md index 547c861..5f9e60a 100644 --- a/README.md +++ b/README.md @@ -99,28 +99,28 @@ To create a Azure Sentinel Rule, use the following JSON format. The following tables describe the values you need to set in the schema. -| Name | Type | Required | Allowed Values | Example | -| ---------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| displayName | string | true | * | DisplayName | -| description | string | true | * | Description | -| severity | string | true | Medium, High, Low, Informational | Medium | -| enabled | bool | true | true, false | true | -| query | string | true | special character need to be escaped by \ | SecurityEvent \| where EventID == \"4688\" \| where CommandLine contains \\"-noni -ep bypass $\\" | -| queryFrequency | string | true | Value must be between 5 minutes and 24 hours | 30M | -| queryPeriod | string | true | Value must be between 5 minutes and 14 days | 6H | -| triggerOperator | string | true | GreaterThan, FewerThan, EqualTo, NotEqualTo | GreaterThan | -| triggerThreshold | int | true | The value must be between 0 and 10000 | 5 | -| suppressionDuration | string | true | Value must be greater than 5 minutes | 1D | -| suppressionEnabled | bool | true | true, false | true | -| tactics | array | true | InitialAccess, Persistence,Execution,PrivilegeEscalation,DefenseEvasion,CredentialAccess,LateralMovement,Discovery,Collection,Exfiltration,CommandAndControl,Impact | true | -| playbookName | string | false | Enter the Logic App name that you want to configure as playbook trigger | LogicApp01 | -| aggregationKind | string | false | SingleAlert, AlertPerRow | SingleAlert | -| createIncident | bool | false | true, false | true | -| GroupingConfigurationEnabled | bool | false | true, false | true | -| reopenClosedIncident | bool | false | true, false | true | -| lookbackDuration | string | false | Value must be between 5 minutes and 24 hours. | PT6H | -| entitiesMatchingMethod | string | false | All, None, Custom | All | -| groupByEntities | string | false | Account, Ip, Host, Url | Account | +| Name | Type | Required | Allowed Values | Example | +| ---------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| displayName | string | true | * | DisplayName | +| description | string | true | * | Description | +| severity | string | true | Medium, High, Low, Informational | Medium | +| enabled | bool | true | true, false | true | +| query | string | true | special character need to be escaped by \ | SecurityEvent \| where EventID == \"4688\" \| where CommandLine contains \\"-noni -ep bypass $\\" | +| queryFrequency | string | true | Value must be between 5 minutes and 24 hours | 30M | +| queryPeriod | string | true | Value must be between 5 minutes and 14 days | 6H | +| triggerOperator | string | true | GreaterThan, FewerThan, EqualTo, NotEqualTo | GreaterThan | +| triggerThreshold | int | true | The value must be between 0 and 10000 | 5 | +| suppressionDuration | string | true | Value must be greater than 5 minutes | 1D | +| suppressionEnabled | bool | true | true, false | true | +| tactics | array | true | InitialAccess, Persistence,Execution,PrivilegeEscalation,DefenseEvasion,CredentialAccess,LateralMovement,Discovery,Collection,Exfiltration,CommandAndControl,Impact | true | +| playbookName | string | false | Enter the Logic App name or Resource ID | LogicApp01 / /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUPNAME/providers/Microsoft.Logic/workflows/playbook02 | +| aggregationKind | string | false | SingleAlert, AlertPerRow | SingleAlert | +| createIncident | bool | false | true, false | true | +| GroupingConfigurationEnabled | bool | false | true, false | true | +| reopenClosedIncident | bool | false | true, false | true | +| lookbackDuration | string | false | Value must be between 5 minutes and 24 hours. | PT6H | +| entitiesMatchingMethod | string | false | All, None, Custom | All | +| groupByEntities | string | false | Account, Ip, Host, Url | Account | ### Fusion rule diff --git a/examples/AlertRules.json b/examples/AlertRules.json index 5f60bb2..297f94c 100644 --- a/examples/AlertRules.json +++ b/examples/AlertRules.json @@ -17,7 +17,7 @@ "LateralMovement", "Collection" ], - "playbookName": "Playbook01", + "playbookName": "playbook01", "aggregationKind": "SingleAlert", "createIncident": true, "groupingConfiguration": { @@ -50,7 +50,7 @@ "LateralMovement", "Collection" ], - "playbookName": "Playbook01" + "playbookName": "/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUPNAME/providers/Microsoft.Logic/workflows/playbook02" } ], "Fusion": [