matching branch rayhayes-semperis:Semperis-3.0.3 that was closed#14516
matching branch rayhayes-semperis:Semperis-3.0.3 that was closed#14516omid-av wants to merge 1 commit into
Conversation
@microsoft-github-policy-service agree company="Semperis" |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds/updates the Semperis Directory Services Protector solution assets to align workbook queries/time-scoping with the new AMA-based data tables and bumps the solution version to 3.0.3.
Changes:
- Added a
build.ps1entry point for solution packaging. - Updated multiple workbooks/metadata and the parser to query
SecurityEvents/Eventsinstead ofCommonSecurityLog/SecurityEvent. - Updated the Quickview dashboard to include a Time Range parameter and apply it to queries.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Solutions/Semperis Directory Services Protector/build.ps1 | Adds a build script entry point for creating the solution package. |
| Solutions/Semperis Directory Services Protector/Workbooks/workbooksMetadata.json | Updates workbook data type dependency to the new table name. |
| Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPSecurityIndicators.json | Switches workbook unions from CommonSecurityLog to SecurityEvents and reformats some JSON arrays. |
| Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPQuickviewDashboard.json | Adds Time Range parameter/time context, migrates queries to new tables, and adds fallback resource IDs. |
| Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPNotifications.json | Updates notifications workbook to query new tables. |
| Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPADChanges.json | Updates AD changes workbook query table to SecurityEvents. |
| Solutions/Semperis Directory Services Protector/ReleaseNotes.md | Adds release notes entry for version 3.0.3. |
| Solutions/Semperis Directory Services Protector/Parsers/dsp_parser.yaml | Updates parser function query to use SecurityEvents. |
| Solutions/Semperis Directory Services Protector/Data/Solution_Semperis.json | Bumps solution version from 3.0.2 to 3.0.3. |
| @@ -0,0 +1 @@ | |||
| ../../Tools/Create-Azure-Sentinel-Solution/V3/createSolutionV3.ps1 No newline at end of file | |||
| "logoFileName": "Semperis.svg", | ||
| "description": "View change data related to the Semperis DSP system.", | ||
| "dataTypesDependencies": [ "CommonSecurityLog" ], | ||
| "dataTypesDependencies": [ "SecurityEvents" ], |
| "query": "let day_names =dynamic([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);\nlet averageData = view() { Events \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > datetime(2000-01-01)\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Average Daily Change\"\n| order by Day asc};\nlet weeklyData = view() { Events \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > startofweek(now())\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Daily Change\"\n| order by Day asc };\nunion withsource=TableName averageData,weeklyData\n| order by Day asc, SortData asc\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\n| render barchart with (kind=unstacked)\n\n", | ||
| "size": 0, | ||
| "title": "Weekly Active Directory Change Count", | ||
| "timeContextFromParameter": "TimeRange", |
| "content": { | ||
| "version": "KqlItem/1.0", | ||
| "query": "let day_names =dynamic([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);\nlet averageData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > datetime(2000-01-01)\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Average Daily Change\"\n| order by Day asc};\nlet weeklyData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > startofweek(now())\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Daily Change\"\n| order by Day asc };\nunion withsource=TableName averageData,weeklyData\n| order by Day asc, SortData asc\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\n| render barchart with (kind=unstacked)\n\n", | ||
| "query": "let day_names =dynamic([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);\nlet averageData = view() { Events \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > datetime(2000-01-01)\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Average Daily Change\"\n| order by Day asc};\nlet weeklyData = view() { Events \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > startofweek(now())\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Daily Change\"\n| order by Day asc };\nunion withsource=TableName averageData,weeklyData\n| order by Day asc, SortData asc\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\n| render barchart with (kind=unstacked)\n\n", |
| "fallbackResourceIds": [ | ||
| "/subscriptions/20d762c7-7b9b-41b2-ab45-62d7fa96ddbe/resourcegroups/Semperis-Testing-RG" | ||
| ], |
| FunctionAlias: dsp_parser | ||
| FunctionQuery: | | ||
| SecurityEvent | ||
| SecurityEvents |
Change(s):
Reason for Change(s):
Version Updated:
Testing Completed: