<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hirotomo Taguchi</title>
    <description>The latest articles on DEV Community by Hirotomo Taguchi (@hirotomotaguchi).</description>
    <link>https://dev.to/hirotomotaguchi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3705922%2F4af663e5-3713-4c21-9ea2-2eb0ef673fb7.jpg</url>
      <title>DEV Community: Hirotomo Taguchi</title>
      <link>https://dev.to/hirotomotaguchi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hirotomotaguchi"/>
    <language>en</language>
    <item>
      <title>Extending EDR Logs with Microsoft Defender for Endpoint Custom Data Collection</title>
      <dc:creator>Hirotomo Taguchi</dc:creator>
      <pubDate>Mon, 12 Jan 2026 09:25:36 +0000</pubDate>
      <link>https://dev.to/hirotomotaguchi/extending-edr-logs-with-microsoft-defender-for-endpoint-custom-data-collection-2on6</link>
      <guid>https://dev.to/hirotomotaguchi/extending-edr-logs-with-microsoft-defender-for-endpoint-custom-data-collection-2on6</guid>
      <description>&lt;p&gt;EDR solutions like Microsoft Defender for Endpoint (MDE) analyze behavior across multiple monitoring points in a system, but when it comes to log "storage," they typically filter and save only what appears "important." Without this filtering, log volumes would become unmanageable. While this approach is rational from bandwidth and storage cost perspectives, it may not fully address organization-specific monitoring requirements. Recently, MDE introduced a Custom Data Collection feature in preview that enables capturing logs that weren't previously collected. This article provides a brief overview.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This article was written based on information as of January 6, 2026.&lt;/li&gt;
&lt;li&gt;Some information in this article relates to prerelease products that may be substantially modified before general availability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Custom Data Collection?
&lt;/h2&gt;

&lt;p&gt;Simply put, it's a feature that lets you "specify and record events that MDE would normally discard." Typically, MDE observes massive amounts of events across various system layers—kernel drivers, AMSI, and more—but storing everything in the cloud isn't feasible. Microsoft selects and formats only events deemed "likely important" for storage. This mechanism is similar across most EDR solutions.&lt;/p&gt;

&lt;p&gt;While this filtering works well for general threats, it may discard necessary events when monitoring organization-specific application behavior. Additionally, "Living off the Land" attacks that abuse legitimate tools exploit blind spots in standard configurations. Custom Data Collection addresses these scenarios where events are "generally noise but signal in our environment."&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;License requirement&lt;/strong&gt;: MDE P2 or M365 E5 is mandatory. P1 is not supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Sentinel integration is required&lt;/strong&gt;: Collected data is sent directly to Sentinel's Log Analytics workspace, not the standard Defender portal. Since forced integration is coming in June 2026 anyway, this may not be a major concern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collection limits&lt;/strong&gt;: Maximum 25,000 events per rule per device per 24 hours. Loose filters can quickly hit this limit and stop collection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OS support&lt;/strong&gt;: Windows 10/11 and Windows Server 2019/2022 only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported Event Tables and Schemas
&lt;/h2&gt;

&lt;p&gt;Custom Data Collection doesn't indiscriminately collect all system events. Currently, five specific categories are supported, each mapping to a unique table in Sentinel.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table Name&lt;/th&gt;
&lt;th&gt;Corresponding Standard Table&lt;/th&gt;
&lt;th&gt;Collection Content&lt;/th&gt;
&lt;th&gt;Primary Use Cases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DeviceCustomProcessEvents&lt;/td&gt;
&lt;td&gt;DeviceProcessEvents&lt;/td&gt;
&lt;td&gt;Process creation, termination, parent-child relationships&lt;/td&gt;
&lt;td&gt;Capturing legitimate process behavior and short-lived processes filtered by standard collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeviceCustomNetworkEvents&lt;/td&gt;
&lt;td&gt;DeviceNetworkEvents&lt;/td&gt;
&lt;td&gt;TCP/UDP connections, IPs, ports, protocols&lt;/td&gt;
&lt;td&gt;Detailed audit logs of failed connections and internal communications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeviceCustomFileEvents&lt;/td&gt;
&lt;td&gt;DeviceFileEvents&lt;/td&gt;
&lt;td&gt;File creation, modification, deletion, access&lt;/td&gt;
&lt;td&gt;Monitoring access to sensitive files, capturing temporary file traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeviceCustomImageLoadEvents&lt;/td&gt;
&lt;td&gt;DeviceImageLoadEvents&lt;/td&gt;
&lt;td&gt;DLL/executable memory loads&lt;/td&gt;
&lt;td&gt;Detecting DLL sideloading and hijacking attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeviceCustomScriptEvents&lt;/td&gt;
&lt;td&gt;None (unique feature)&lt;/td&gt;
&lt;td&gt;Script execution and process details&lt;/td&gt;
&lt;td&gt;Script auditing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;DeviceCustomScriptEvents&lt;/strong&gt; deserves special attention. This table has no corresponding equivalent in the standard Advanced Hunting schema and represents a powerful capability unique to Custom Data Collection. While Advanced Hunting's DeviceProcessEvents captures command-line arguments for process launches, and MDE saves some scripts (filtered by high threat scores or alert associations) visible in alert screens as shown below, not all script executions are recorded. Scripts deemed benign or not triggering detections tend to be dropped to save storage capacity. (Note)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9nn1ta1ubu0439iubby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9nn1ta1ubu0439iubby.png" alt="Alert Screen Example" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;:::note alert&lt;br&gt;
Note: To my understanding, executed script information is analyzed by MDE and viewable only when Defender raises an alert, and is not saved as Advanced Hunting logs. However, I couldn't find official documentation directly supporting this understanding. If anyone knows of such documentation or recognizes this as incorrect, I'd appreciate kind corrections.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;By utilizing the DeviceCustomScriptEvents table, you can explicitly preserve audit trails for specific interpreters and script files. This is presumed to leverage mechanisms like AMSI (Antimalware Scan Interface) to obtain decoded script content, offering the powerful advantage of viewing executed scripts, as described below.&lt;/p&gt;
&lt;h2&gt;
  
  
  Verification: Visualizing PowerShell Obfuscation
&lt;/h2&gt;

&lt;p&gt;Let's simulate a common attacker technique and compare how it appears in the standard "DeviceProcessEvents" versus "Custom Data Collection (DeviceCustomScriptEvents)." The scenario involves "PowerShell Base64 obfuscation (EncodedCommand)," which attackers use to evade detection.&lt;/p&gt;
&lt;h3&gt;
  
  
  Background and Challenge
&lt;/h3&gt;

&lt;p&gt;Attackers attempt to hide their commands to evade security monitoring. One popular method is Base64 encoding using PowerShell's &lt;code&gt;-EncodedCommand&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;:::alert&lt;br&gt;
This is a simplified demo. Real attacks use far more complex obfuscation.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;Standard MDE logs (DeviceProcessEvents) record the fact that a process launched, but the arguments (command line) appear as the attacker-concealed "meaningless alphanumeric string." While Defender analyzes the decoded version in the backend&lt;sup id="fnref2"&gt;2&lt;/sup&gt; and preserves evidence as alerts when deemed dangerous, events that don't trigger alerts are discarded, leaving only the obfuscated version.&lt;/p&gt;

&lt;p&gt;:::alert&lt;br&gt;
As repeatedly stated, backend decoding and MDE analysis occur. The issue is whether it's preserved as Advanced Hunting logs.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;DeviceCustomScriptEvents enables explicitly preserving audit trails for specific interpreters and script files. This presumably references AMSI buffers internally, offering the powerful advantage of viewing deobfuscated code, as described below.&lt;/p&gt;
&lt;h3&gt;
  
  
  Demo Scenario
&lt;/h3&gt;

&lt;p&gt;Let's execute the following PowerShell command and compare log appearances. This scenario displays a harmless message simulating "Mimikatz execution," with the command concealed via Base64. While not particularly attack-like, it's clear for demonstration purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command before obfuscation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Just a message display command&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;powershell.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write-Host '【DEMO】Critical Alert: Mimikatz Execution Detected!' -ForegroundColor Red; Start-Sleep -Seconds 10"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it appears in Defender portal (before obfuscation):&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9o7i7ocha23kwv6wp26o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9o7i7ocha23kwv6wp26o.png" alt="Unobfuscated Command" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test command to execute (obfuscated):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Command to hide (payload)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$OriginalCommand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write-Host '【DEMO】Critical Alert: Mimikatz Execution Detected!' -ForegroundColor Red; Start-Sleep -Seconds 10"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Convert command to Base64 (obfuscation)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$Bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Text.Encoding&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Unicode.GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$OriginalCommand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$EncodedCommand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Convert&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Execute in obfuscated state (this is the attack command logged)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Executing command: powershell.exe -EncodedCommand &lt;/span&gt;&lt;span class="nv"&gt;$EncodedCommand&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ForegroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Yellow&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;powershell.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-EncodedCommand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$EncodedCommand&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Standard Log (DeviceProcessEvents) Appearance:&lt;/strong&gt;&lt;br&gt;
In existing process monitoring logs, it's recorded as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzowgitxt21fr82pmw04m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzowgitxt21fr82pmw04m.png" alt="DeviceProcessEvents View" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shows &lt;code&gt;powershell.exe -EncodedCommand VwByAGkAdABlAC0ASABvAHMAdAAg...&lt;/code&gt;, making content auditing impossible. Note that DeviceProcessEvents only records new process launches, so commands within the encoding PowerShell session ($Bytes assignment, Base64 conversion, etc.) aren't recorded. These are in-process operations not involving process launches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Data Collection Configuration&lt;sup id="fnref3"&gt;3&lt;/sup&gt;
&lt;/h3&gt;

&lt;p&gt;As prerequisite setup, integrate Sentinel with Defender portal.&lt;/p&gt;

&lt;p&gt;Then configure collection conditions via [Defender Portal] &amp;gt; [Settings] &amp;gt; [Endpoints] &amp;gt; [Custom Data Collection] and save. For this verification, I set very broad log collection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsusocyamiqbspxykqs8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsusocyamiqbspxykqs8.png" alt="Configuration Screenshot" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Data Collection (DeviceCustomScriptEvents) Appearance
&lt;/h3&gt;

&lt;p&gt;After enabling, logs showed the script immediately before execution recorded in Advanced Hunting. Interestingly, in-session commands not recorded in DeviceProcessEvents ($Bytes assignment, Base64 conversion, etc.) were recorded in DeviceCustomScriptEvents. This is because DeviceCustomScriptEvents captures entire code executed within PowerShell sessions through script execution monitoring mechanisms like AMSI, rather than process launch events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2ilpemkh1lgjvkgjcd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2ilpemkh1lgjvkgjcd0.png" alt="DeviceCustomScriptEvents View" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Collecting All Logs = Fast Track to Bankruptcy
&lt;/h2&gt;

&lt;p&gt;Custom Data Collection can skyrocket costs if used carelessly. Unlike flat-rate Advanced Hunting, Sentinel log ingestion is pay-as-you-go, making "collect everything" thinking dangerous. (Limits prevent full collection anyway...) Additionally, don't underestimate the volume of logs that weren't previously saved—Advanced Hunting already handles massive log volumes. Use wisely and plan accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distinction from Azure Monitor Agent (AMA)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TBD&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other Use Cases
&lt;/h2&gt;

&lt;p&gt;While this article focused on PowerShell deobfuscation, DeviceCustomScriptEvents appears powerful for diverse scenarios. However, validation of effective scenarios including costs remains incomplete, so I'll update progressively or write separate posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Microsoft Defender for Endpoint's Custom Data Collection feature powerfully illuminates previously "black box" areas. While requiring balance with costs (Sentinel log ingestion volume), those interested should consider starting small with limited scope—critical assets or administrative endpoints—as a pilot.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/defender-endpoint/custom-data-collection" rel="noopener noreferrer"&gt;Custom data collection in Microsoft Defender for Endpoint (preview)&lt;/a&gt;&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal" rel="noopener noreferrer"&gt;Antimalware Scan Interface (AMSI)&lt;/a&gt;&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/defender-endpoint/create-custom-data-collection-rules" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/defender-endpoint/create-custom-data-collection-rules&lt;/a&gt;&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>microsoftdefender</category>
      <category>microsoftsecurity</category>
      <category>microsoft365defender</category>
    </item>
  </channel>
</rss>
