Monitoring with PowerShell: AD KRBTGT & making your own canaries

I decided this time I’m gonna be combining two small blogs, because they’re both pretty small and easy. Both are somewhat security oriented. The first part of the blog we will tackle monitoring the KRBTGT password. This needs to be reset on a regular schedule to ensure bad actors can’t abuse it.

The second part we’ll focus on creating our own ‘Canary’ files. These files can be used for a lot of things but the most common is to detect if ransomware has touched them in someway or the other. So, lets get started!

Monitoring KRBTGT Password age

So it’s actually straight forward to monitor the KRBTGT account, as it’s just a AD account. We’ll monitor this by grabbing the PasswordLastSet Attributes from the Active Directory. If you want to automatically resolve this, I’d strongly suggest to look at the script in this Github.

$Days = (Get-Date).AddDays(-31)
$Account = Get-AdUser krbtgt -property passwordlastset
$Setdate = if($Account.PasswordLastSet -gt $Days){ "Healthy - Password set date $($Account.Passwordlastset)" } else {" Unhealthy - Password set date $($Account.Passwordlastset)" }

You can change the amount of days to what you are comfortable with. I believe the documentation doesn’t have a strong suggestion in how much you should, but as this is a completely automated solution we perform this on a monthly basis.

Creating and monitoring file canaries

So, canaries are files that you place on strategic locations on a machine to check if the files aren’t being touched, corrupted, or encrypted in any way. Primarily they are used to prevent a full encryption of a computer and minimize data loss and lateral movement.

So with this script, we create canaries in a couple of locations;

  • The My Documents folder of each user
  • The Desktop Folder of each user
  • The root of each drive on the machine

You’ll also be able to create them in locations you want by adding to the $CreateLocations variable. We create the files as hidden, so users should not see the file, the file name will be canaryfile.pdf, even though it’s just a simple text file.

So the script creates a file in each location, and immediately starts alerting on two properties; If the file has been edited in the past hour, and if the file contains the correct string. I’d advice to apply the monitoring to the device, wait an hour, and then actually start alerting on it or reacting.

$CreateLocations = @('AllDesktops', 'AllDocuments', 'AllDrives', 'C:\temp')
$FileContent = "This file is a special file created by your managed services provider. For more information contact the IT Support desk."

foreach ($Locations in $CreateLocations) {
    $AllLocations = switch ($Locations) {
        "AllDesktops" { (Get-ChildItem "C:\Users" -Recurse -Force -filter 'Desktop' -Depth 3).FullName }
        "AllDocuments" { (Get-ChildItem "C:\Users" -Recurse -Force -Filter 'Documents' -Depth 3).fullname }
        "AllDrives" { ([System.IO.DriveInfo]::getdrives() | Where-Object { $_.DriveType -eq 'Fixed' }).Name }
        default { $Locations }
  $CanaryStatus = foreach ($Location in $AllLocations) {
        if ((test-path "$Location\CanaryFile.pdf") -eq $false) {
            $File = New-Item $Location -Name "CanaryFile.pdf" -Value $FileContent
            $file.Attributes = 'hidden'
        else {
            $ExistingFile = get-item "$Location\CanaryFile.pdf" -Force
            if ($ExistingFile.LastWriteTime -gt (get-date).AddHours(-1)) { "$Location\CanaryFile.pdf is unhealthy. The LastWriteTime was $($ExistingFile.LastWriteTime)" }
            $ExistingFileContents = get-content $ExistingFile -Force
            if ($ExistingFileContents -ne $FileContent) { "$Location\CanaryFile.pdf is unhealthy. The contents do not match. This is a sign the file has most likely been encrypted" }
    $CanaryStatus = "Healthy"


If you feel confident enough about this, you could set up some self-healing like disabling network access, or shutting the device down before the machine is completely encrypted. And that’s it. As always, Happy PowerShelling!


  1. Nicolas July 7, 2020 at 1:36 pm


    Nice idea to catch modifications 🙂
    Just a very quick question, how do you schedule the canaries monitoring?

    In order to be able to save something it must react very quickly.

    It looks like the script is polling the status, have you tried an event driven solution?


    1. Kelvin Tegelaar July 7, 2020 at 1:56 pm

      most of my scripts are designed to run from an RRM system, that way the script is able to run every 30 seconds for example, and automatically shut of network access when the results are unexpected.

    2. N8 July 8, 2020 at 5:29 am

      New to PowerShell. I like the formatting/colors for the scripts. It makes it very readable to me. What are you using for that?

      1. Kelvin Tegelaar July 8, 2020 at 8:47 am

        For actual coding I am using VSCode. To Display it on my website I am using the SyntaxHighlighter Evolved plugin. Hope that helps!

  2. Andy July 7, 2020 at 5:22 pm

    So i think there may be a few errors, or at least some things im getting hung on.

    If i run the canary script as regular user, i get TONS of errors making and creating the files (it appears to be trying to access each users data individually and failing). If i run as admin, i fail, again on nearly all locations. (I suppose the default switch option of location is supposed to handle the “other locations” but again, no logic to test that it exists, is writeable, etc)

    There appears to be no logic or portion of the script that handles any locations other than the “AllDesktops, AllDocuments, AllDrives”. In fact i do not appear to have a c:\temp folder on my machine, and there is no code to create one, as a result that fails nearly every time.

    So i guess, to start, what context should the script be run in?

    1. Kelvin Tegelaar July 7, 2020 at 5:28 pm

      Most RMM systems run all scripts as SYSTEM, which helps with most of the errors you’re getting. We don’t create the folders but just try to find them. C:\Temp is an example folder you can replace with a folder you are sure is present, such as C:\Windows\Temp. 🙂

  3. D mehdi July 8, 2020 at 1:24 am

    verry interessing as idéa, i’m Expert system and Windows Dev, i want to convert your script as an application with agent and service. it will be interesting and help people.
    we dont need to change any things after all things will be automated.
    you can contact me if you are interested

  4. Sasa July 10, 2020 at 5:09 pm

    Creative way for canary file. I would add $file.LastWriteTime=$(get-date).AddHours(-1) so we don’t get notifications for new PCs when new files is created and monitor runs 30 seconds after the file is created. Also, if you want to make sure that hidden files are not enabled, you can disable it via HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced. (to show hidden items, set Hidden to 1 (to hide them, set it to 2))

    Thanks for sharing it

  5. Pingback: Monitoring with PowerShell: Host isolation - CyberDrain

  6. Pingback: Breaking Cyber Attack Chains With 5 Tools You Already Have Access To - ChannelE2E

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.