DEV Community

Clear Path Security Ltd
Clear Path Security Ltd

Posted on Originally published at clearpathsecurity.co.uk

Baselining and detecting anomalous PowerShell with script block logging

Originally published on the ClearPath Security site: https://clearpathsecurity.co.uk/baselining-and-detecting-anomalous-powershell-with-script-block-logging/

PowerShell is one of the most useful administrative tools in Windows environments, which is exactly why it deserves dedicated detection coverage. It is used for software deployment, identity and endpoint administration, cloud management, and routine automation. It is also frequently abused because it can run in memory, invoke native Windows components, and blend into normal administrator activity.

For UK SMEs, the goal is not to treat every PowerShell invocation as suspicious. The aim is to understand what normal looks like in your environment, collect enough telemetry to spot meaningful deviations, and turn that into detections that are useful to a small security team. If you already have basic logging in place, logging and monitoring basics for small teams is a sensible companion topic. This article focuses on the next step: building a baseline for PowerShell and using script block logging to identify anomalous behaviour.

Key takeaways

  • Script block logging is most useful when combined with process, identity, and network telemetry rather than used in isolation.
  • Build a baseline around trusted hosts, users, parent processes, and script locations so that detections focus on meaningful deviations.
  • Prioritise high-signal patterns such as encoded commands, unusual execution paths, and suspicious parent-child relationships.
  • Tune detections using frequency, rarity, and context to reduce noise without suppressing genuine abuse.
  • Review and validate PowerShell detections regularly because legitimate automation and administration patterns change over time.

Why PowerShell deserves dedicated detection coverage

PowerShell is not just another command shell. It exposes access to Windows Management Instrumentation, the registry, Active Directory, scheduled tasks, services, and network functions. In legitimate use, that makes it efficient for administrators. In malicious use, it gives an operator a flexible way to enumerate systems, stage payloads, disable controls, or move laterally.

That dual use matters because many defensive tools see only fragments of the activity. Process creation logs may show powershell.exe, but not the full script. Network logs may show a connection, but not the command that initiated it. Script block logging fills part of that gap by recording the content PowerShell interprets after de-obfuscation.

In practice, PowerShell detections work best when they are part of a wider Windows telemetry strategy. Process telemetry, Windows Security logs, Sysmon, and network data all add context. If you are already using endpoint controls to reduce attack surface, reducing attack surface using system hardening techniques can help you decide which PowerShell features should be restricted or monitored more closely.

What script block logging captures and what it does not

Script block logging records the content of PowerShell script blocks, typically through Event ID 4104 in the Microsoft-Windows-PowerShell operational log. The value is that it captures the script after PowerShell has parsed it, which can expose decoded or expanded content that would otherwise be hidden by simple command-line obfuscation.

That makes it useful for detecting suspicious strings, unusual function calls, encoded content, and common tradecraft such as download cradles or reflective loading patterns. It is especially helpful when an attacker uses short, heavily obfuscated commands that would be hard to triage from process creation alone.

However, script block logging is not complete visibility. It does not guarantee that every malicious action will be logged, and it does not tell you intent. It also depends on the relevant logging being enabled, the event reaching your collection point, and the script being executed through PowerShell in a way that produces useful content. Some activity may occur through other interpreters, native binaries, WMI, scheduled tasks, or remote management channels. For that reason, detections should correlate PowerShell events with broader telemetry rather than relying on a single log source.

There is also a practical distinction between content and context. A script block may look unusual in isolation, but be perfectly normal for a deployment tool or a management script. That is why baselining is essential.

Building a useful baseline for normal PowerShell activity

A baseline is not a static allowlist. It is a working understanding of what normal PowerShell activity looks like across your estate, so that you can identify outliers. Start by identifying the systems, users, and tools that legitimately generate PowerShell at scale.

For most SMEs, those will include endpoint management platforms, patching tools, software deployment agents, backup agents, and a small set of privileged administrators. Record which hosts generate PowerShell, which accounts run it, which parent processes launch it, and which command patterns recur. This gives you a practical view of expected behaviour.

Separate routine automation from interactive use. A scheduled task that runs a signed script from a known path every night is very different from an administrator opening an interactive shell on a finance workstation at 11pm. The first may be normal. The second may still be legitimate, but it deserves context.

When building the baseline, focus on a few dimensions:

  • Trusted hosts, such as jump servers, management servers, and endpoint management consoles.
  • Trusted users and groups, especially privileged accounts and service accounts.
  • Trusted parent processes, such as management agents or approved automation runners.
  • Trusted script locations, for example signed scripts in controlled repositories.
  • Expected frequency, such as daily patching windows or weekly maintenance jobs.

It is also useful to compare PowerShell usage by device class. A domain controller, a management server, and a user laptop should not look the same. If they do, that may indicate over-permissive administration or a lack of role separation. For a broader view of how PowerShell abuse fits into attacker behaviour, detecting fileless malware and living-off-the-land attacks provides useful context.

Telemetry sources to combine with script block logging

Script block logging is strongest when combined with other Windows telemetry. At minimum, pair it with PowerShell operational logs, Windows Security logs, and Sysmon if you can support it operationally.

PowerShell operational logs help you see engine lifecycle events and script block content. Windows Security logs provide logon events, privilege use, and process creation if configured appropriately. Sysmon adds richer process creation, network connections, image loads, and command-line detail. Together, they let you answer not just what script ran, but who ran it, from where, and what it touched next.

Useful correlations include:

  • Event ID 4104 with process creation events to identify the parent process and command line.
  • PowerShell activity followed by outbound network connections to unfamiliar destinations.
  • PowerShell launched from office applications, archive utilities, or script hosts that are unusual for the user.
  • PowerShell activity on servers that should rarely need interactive administration.

Sysmon is particularly valuable where you need process ancestry and network context. If you are tuning that layer as well, detecting living-off-the-land binaries with Sysmon process events is a good reference point for building process-based detections that complement PowerShell telemetry.

Patterns that often indicate suspicious PowerShell behaviour

There is no single malicious PowerShell signature that works everywhere, but there are recurring patterns that deserve attention. The most common include encoded commands, heavy obfuscation, unusual execution switches, and scripts that retrieve or execute content from remote sources.

Encoded commands are often used to hide the real content from casual inspection. Obfuscation may involve string concatenation, variable indirection, alias abuse, or deliberate formatting changes. Suspicious command-line switches include -EncodedCommand, -ExecutionPolicy Bypass, and combinations that suppress profile loading or hide the window. None of these are proof of malicious intent on their own, but they are strong indicators when they appear on endpoints that should not need them.

Download cradles are another common pattern. These are commands that fetch content from the network and execute it immediately, often using native web request functions. In-memory execution, reflective loading, and script injection techniques may leave little on disk, which is why script block content and process context matter. Attackers also frequently use PowerShell as a staging mechanism before moving to other tools, so the PowerShell event may be only the first observable step.

Look for unusual combinations rather than isolated strings. For example, a script block that uses web requests, base64 decoding, and process injection APIs is far more concerning than a simple administrative query. Similarly, PowerShell running from a user profile path, temporary directory, or email attachment location is more suspicious than a signed script from a controlled deployment share.

Practical detection logic for small security teams

Small teams need detections that are high signal and maintainable. Start with a small number of rules that are easy to explain and triage. Good candidates include rare parameter usage, suspicious parent-child relationships, unusual execution paths, and scripts that contain known risky behaviours.

A practical rule set might include:

  • PowerShell with -EncodedCommand or equivalent encoded content.
  • PowerShell launched by office applications, browser processes, archive tools, or scripting hosts that are not normally used for administration.
  • PowerShell executed from user-writable directories such as %AppData%, %Temp%, or downloads folders.
  • PowerShell script blocks containing web download functions, reflection, AMSI tampering indicators, or suspicious process creation.
  • PowerShell activity on servers or workstations outside approved maintenance windows.

Use allowlists carefully. They are useful for reducing noise from known deployment tools, but they can also hide abuse if they are too broad. Prefer scoped allowlists based on signed binaries, known service accounts, specific management servers, and controlled script paths. Avoid blanket exclusions for entire command patterns unless you have strong evidence that they are safe in your environment.

When possible, score detections by context rather than treating them as binary. A rare command on a privileged account, from an unusual host, outside business hours, should rank higher than the same command from a known management server during a patch window. That approach is often easier to operationalise than trying to write one perfect rule.

How to tune detections without losing coverage

Tuning is where many PowerShell detections either become useful or get switched off. The main challenge is reducing false positives from legitimate administration, software deployment, and automation frameworks without creating blind spots.

Start by measuring frequency and rarity. Which commands appear every day, and which appear only once a month? Which hosts generate the most script block events, and do those hosts align with your expected management architecture? Which accounts are responsible for the majority of activity? These questions help you identify the normal operating envelope.

Then add context. A script block that looks suspicious on a user laptop may be routine on a patching server. A command that is normal for a service account may be unusual for an interactive administrator. Time of day, source host, parent process, and user group membership all matter.

Be careful not to over-tune around a single tool. If you suppress every event from one deployment platform, you may miss abuse through that platform, especially if an attacker compromises the management plane. A better approach is to validate the platform’s normal command patterns and then alert on deviations from those patterns.

For teams that want to improve detection quality systematically, the same principles used in broader detection engineering apply here: define the behaviour, measure the noise, tune by context, and review regularly. If you are already working on credential misuse detection, detecting credential theft and misuse patterns is a useful adjacent reference because PowerShell abuse often overlaps with account compromise.

Threat hunting questions to ask in PowerShell logs

Hunting is where script block logging becomes especially valuable. Rather than waiting for a rule to fire, use the logs to ask structured questions about behaviour.

Useful hunting questions include:

  • Which hosts generate the most PowerShell script blocks, and do those hosts match their intended role?
  • Which users run PowerShell interactively, and is that consistent with their job function?
  • Which script blocks contain web requests, encoded content, or suspicious string manipulation?
  • Which parent processes launch PowerShell most often, and are any unexpected?
  • Which scripts run outside normal maintenance windows or from unusual paths?

Hunting is also a good way to validate your baseline. If a host suddenly starts producing far more PowerShell activity than usual, that may indicate a new automation job, but it may also indicate an attacker using the host as an execution point. The key is to compare current behaviour with the established pattern, not with an abstract idea of what is normal.

Operationalising detections in Microsoft Sentinel or a SIEM

In a SIEM, the main task is to make PowerShell events searchable, normalised, and easy to correlate. In Microsoft Sentinel, that usually means ensuring the relevant Windows logs are ingested into a workspace, then building analytics rules and hunting queries around Event ID 4104 and related process telemetry.

Normalisation matters because PowerShell content is often messy. Script blocks can be multiline, contain escaped characters, or be split across events. If your SIEM supports parsing or custom fields, extract the command content, host, account, parent process, and execution time into searchable fields. That makes it much easier to write detections and triage alerts.

A practical workflow is:

  1. Ingest PowerShell operational logs and process telemetry from your endpoints and servers.
  2. Build one or two high-signal analytics rules for obvious suspicious patterns.
  3. Create hunting queries for rare commands, unusual hosts, and off-hours activity.
  4. Review alerts weekly to identify recurring false positives and new legitimate use cases.
  5. Promote validated hunts into scheduled detections where they add value.

If you are designing the broader pipeline rather than just the rule content, centralised security visibility explained for SMEs can help frame how PowerShell telemetry fits into a wider visibility model.

Validation, tuning, and continuous improvement

Detections should be tested against known-good administrative activity and safe simulations. You do not need to recreate real attacker behaviour to validate whether your logging and rules are working. Instead, use benign scripts that exercise the same telemetry paths, such as encoded commands in a lab, remote administration from approved hosts, or scheduled automation from service accounts.

Check three things during validation. First, does the event arrive in your SIEM with the fields you need? Second, does the rule trigger on the behaviour you expect? Third, can an analyst triage the alert quickly using the available context? If the answer to any of those is no, the detection is not yet operationally ready.

Measure alert quality over time. Track false positives, time to triage, and the proportion of alerts that lead to useful investigation. If a rule is noisy but occasionally valuable, tune it rather than removing it immediately. If it is consistently noisy and low value, retire it and replace it with a more contextual rule.

Continuous improvement is especially important in PowerShell monitoring because legitimate usage changes. New management tools, new automation scripts, and new cloud integrations can all alter the baseline. Review your detections after major changes to endpoint management, identity administration, or software deployment.

Implementation checklist for UK SMEs

If you are starting from scratch, a phased approach is usually the most practical.

Phase one is logging enablement. Turn on PowerShell script block logging on the systems that matter most, especially privileged workstations, servers, and management hosts. Make sure logs are forwarded centrally and retained long enough for investigation. If storage is limited, prioritise high-value assets rather than trying to capture everything at once.

Phase two is baseline creation. Identify trusted hosts, users, and tools. Document the common parent processes, command patterns, and maintenance windows. Use that baseline to define what should be normal, and where exceptions need review.

Phase three is detection. Start with a handful of high-signal rules for encoded commands, suspicious parent processes, unusual paths, and risky script content. Keep the rules understandable so that they can be maintained by a small team.

Phase four is review and improvement. Revisit the baseline monthly, tune alerts based on real activity, and add new detections when you see repeatable patterns. If you want support designing that operating model, the service most aligned to this work is our Speak to a consultant option, which can help you shape practical logging and detection improvements without overengineering the solution.

For UK SMEs, the most effective PowerShell monitoring programmes are usually the ones that are focused, well-instrumented, and reviewed regularly. You do not need perfect coverage on day one. You need enough visibility to spot meaningful deviations, enough context to triage them, and enough discipline to keep improving the baseline as your environment changes.

Frequently asked questions

Is script block logging enough on its own to detect malicious PowerShell?

No. It is a strong source of content visibility, but it works best when combined with process creation, logon, and network telemetry so you can see who ran the script, from where, and what happened next.

What is the difference between script block logging and PowerShell transcription?

Script block logging records the script content that PowerShell interprets, which is useful for seeing decoded or expanded commands. Transcription records the interactive session output and input as a text transcript, which can be useful for context but does not replace script block logging.

Top comments (0)