Check a Device Setting with a PowerShell Script in Atlas Reach

Step-by-step: write a PowerShell script that prints a device setting, store the result in a device custom field, and more.

Before you begin

  • Atlas Reach agents enrolled and approved on the devices you want to check (see Install the Atlas Reach Agent on Windows)
  • An Atlas administrator account, to create checks on the Checks tab of Atlas Reach
  • Access to Scripts in the sidebar, to add the script to your Scripts library (the Scripts feature is included from the Starter plan)

How it works

You do not need two checks, one to collect the value and one to judge it. A single script check does three things on every run:

  1. Runs your script from the Scripts library on the device, on the interval you choose.
  2. Saves what the script printed to the device custom field you name, so you can always see the current value on the device.
  3. Compares that same value with your expected value. The check passes only when the script exits with code 0 and the comparison holds; otherwise it fails and raises an alert.

Storing the value and judging it are independent options. You can judge the output without storing it, or store it without judging it (see Populate Custom Fields from Script Output). This article uses both.

Step 1: Write a script that prints only the value

Whatever the script writes to standard output is what gets stored and compared, so print the value and nothing else: no headings, banners or progress text. Exit with code 0 whenever the script ran correctly, even if the value is the wrong one, because a non-zero exit code fails the check before the value is looked at. For the SMBv1 example, the whole script is the one line (Get-SmbServerConfiguration).EnableSMB1Protocol, which prints True when the SMBv1 server protocol is enabled and False when it is off, followed by exit 0:

  • Use Write-Output, or simply let the value fall out of the pipeline as the SMBv1 line does. Avoid Write-Host for anything other than the value.
  • Decide what the script should print when the setting is missing, for example when a registry value has never been set. Printing a clear word such as NotSet is easier to read in the field than an empty value.
  • Keep it quick. A script check is stopped after 60 seconds, and the script can be up to 64 KB.
# Prints True when the SMBv1 server protocol is enabled, False when it is off
(Get-SmbServerConfiguration).EnableSMB1Protocol
exit 0

Step 2: Add the script to your Scripts library

Go to Scripts in the sidebar (under Workspace) and add a new script. Set its language to PowerShell, give it a name such as Check SMBv1 status, paste the script from Step 1 ((Get-SmbServerConfiguration).EnableSMB1Protocol, then exit 0 on its own line) and save it.

  • The check refers to the script by its library ID, a number. To find it, open the script's actions menu and use Run via Atlas Reach…: the page that opens has the ID at the end of its address, after runScript=. For example, /admin/atlas-reach?runScript=42 means the ID is 42. Nothing runs until you choose devices and confirm, so you can simply leave that page.

Step 3: Create the script check

Open Atlas Reach (Atlas Operations → Reach in the sidebar), go to the Checks tab and click New check. Fill in the editor:

  1. Name: something that says what a pass means, for example SMBv1 disabled. If the field below does not exist yet, Atlas uses this name as its label.
  2. Type: Script.
  3. Severity: how serious a failure is, for example warning or error.
  4. Target: the script's library ID from Step 2, for example 42.
  5. Store output in field: the key of the device custom field to save the value in, for example smb1_enabled. Keys use lower-case letters, numbers and underscores, start with a letter, and can be up to 64 characters. You do not need to create the field first.
  6. Pass only when the output: choose equals, then type the value you want in Expected value. For SMBv1, type False.
  7. Interval (seconds): how often the script runs. The default is 300 (5 minutes); anything from 30 to 86,400 (once a day) is allowed. A setting that rarely changes does not need a short interval.
  8. Cooldown between alerts (seconds): how long Atlas waits before alerting again for a device that is still failing. The default is 900 (15 minutes).
  9. Scope: Tenant (every device), one Host pool, or one Device. Leave Enabled on and click Save.

Text comparisons ignore upper and lower case and any spaces or blank lines around the output, so False, false and "False " all match False.

Step 4: Confirm it is working

Each agent picks up the new check automatically and runs it on its next interval. Once it has run:

  • The Check policies table on the Checks tab shows your check with its condition in the Threshold column, for example output equals "False".
  • Open any device from the Devices tab and go to its Notes & fields tab. Under Custom fields, the SMBv1 disabled field shows what the script printed on that device: False on a compliant device, True on one that needs fixing.
  • The Device check status table, and the device's own Checks tab, show which devices are failing. A failing device carries a detail such as Output "True" — expected to equal "False", so you can see the reported value and the expected value side by side.
  • Each device that starts failing raises one Atlas Reach check failed alert, and one Atlas Reach check recovered alert when it is fixed. Both follow the channels you set up on Settings → Notifications.

Choosing a comparison

Pass only when the output offers these comparisons. Pick the one that matches how the value is written:

  • equals / does not equal: the whole value must (or must not) match the expected text. Leave Expected value blank to test for empty output.
  • contains / does not contain: the expected text must (or must not) appear anywhere in the output. Useful for longer values such as a list of installed features.
  • matches (regex): the output must match a regular expression, for example ^1\.2[0-9]\. for any 1.20 to 1.29 version. Patterns with nested repetition such as (a+)+, backreferences, lookarounds or very large repeat counts are not accepted.
  • is greater than / is at least / is less than / is at most: the output is read as a number and compared with yours. Output that is not a number fails the check.
  • Don't check the output (exit code only): the original behaviour. Exit code 0 passes and anything else fails.

The expected value can be up to 256 characters. The stored field value is capped at 500 characters; longer output is cut off.

More examples

The same three steps cover many settings. A few that work well, each with the script's one line and the comparison to choose:

  • BitLocker on the system drive: (Get-BitLockerVolume -MountPoint $env:SystemDrive).ProtectionStatus. Check that it equals On.
  • Days since the last restart: [int]((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).TotalDays. Check that it is at most 14.
  • BIOS version: (Get-CimInstance Win32_BIOS).SMBIOSBIOSVersion. Check that it equals the version you have standardised on, or matches a pattern for a range.
  • A registry value: (Get-ItemProperty 'HKLM:\SOFTWARE\Contoso' -Name Ring -ErrorAction SilentlyContinue).Ring. Check that it equals Production.
  • Windows Defender real-time protection: (Get-MpComputerStatus).RealTimeProtectionEnabled. Check that it equals True.

Fix it automatically (optional)

To have Atlas correct the setting rather than only alert on it, add a remediation rule on the same check. In the Automated remediation panel at the bottom of the Checks tab, click New rule, pick this check, choose When the check fails, and give it a script that sets the value back, for example Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force. The next run of the check stores the corrected value and the check recovers. Start the rule in Dry run to see how often it would fire. Remediation only runs when script running is turned on for your deployment; see Monitoring Checks and Automated Remediation.

Troubleshooting

  • The check shows an error with This agent did not return the script's output: the device runs an older agent that cannot send output back. Let the agent update itself, or force an update from the Agent updates tab.
  • The check fails but the field shows the right value: the script exited with a non-zero code. Make sure it ends with exit 0 and that no command before it throws an error.
  • Output (empty) in the failure detail: the script printed nothing, often because the setting does not exist on that device. Have the script print a clear word such as NotSet in that case.
  • Output is not a number with a numeric comparison: the script printed text or extra lines. Print only the number.
  • The field never fills in and the check never runs: the script is missing from the library, empty, or in a language the agent cannot run. Check the Target ID and the script's language.
  • The field on Notes & fields keeps changing back after you edit it by hand: the check overwrites it on every run. Use a separate field for values you want to type in yourself.
  • Nobody was notified: the check's severity is below the Alert notification policy minimum on the Checks tab, or the Atlas Reach category is off in Settings → Notifications.

Next steps