Monitoring with PowerShell Chapter 3: Monitoring user creation

We all know that bad actors often create accounts for repeat access when they gain access to your network. To make sure that we are aware of these situations we user PowerShell monitoring.

For security measures we monitor 3 types of user creation:

  • All created domain users,
  • All users added privileged groups(e.g. Domain Admins)
  • All created local users.
  • All (Temporary) users created that contain specific keywords.
Temporary users Monitoring:

The temporary users monitoring set is only used on active directory users, not local users. as we’re already monitoring all local user creation this would be redudant.

$ArrayOfNames = @("test", "tmp","skykick","mig", "migwiz","temp","-admin","supervisor")

foreach($name in $ArrayOfNames){
$filter =  'Name -like "*'+ $($name) + '*"'
$Users = Get-ADUser -Filter $filter
if($users -ne $null){
foreach($user in $users){
$TemporaryUser += "$($ has been found, created at $($user.whencreated)`n"
if(!$TemporaryUser){$Userlist = "No Temporary Accounts Found" }
Created Domain Users

For domain users, we alert on all users created in the last 24 hours. after 24 hours this monitoring set goes back to a healthy state.

$When = ((Get-Date).AddDays(-1)).Date
$GetUsers = Get-ADUser -Filter {whenCreated -ge $When} -Properties whenCreated

foreach($user in $GetUsers){
$userchanges += "$($ has been created at $($user.whencreated) `n"

if($UserChanges -eq $Null) { $UserChanges = "No Changes Detected"}
All created local users

Local users do not have a creation date, that makes it a little more difficult to monitor. To solve this we create a file with the results of get-localuser, We update that file every 24 hours. Then from there on, we compare the file to the most recent results of the output of get-localuser. We are alerted if the compare finds newer content, Meaning a user has been created or removed in the local user database.

$Outputfile = "C:\Windows\temp\LocalUsers.txt"
$Localusers = Get-LocalUser | Select-Object *
Test-Path $Outputfile | %{if($_ -eq $false){new-item $Outputfile} }
$OutPutFileContents = Get-Content $Outputfile | ConvertFrom-Json

If((get-item $Outputfile).LastWriteTime -lt (Get-Date).AddDays((-1))){    $Localusers | ConvertTo-Json |out-file $Outputfile  }

$Compare = Compare-Object -DifferenceObject $ -ReferenceObject $

if(!$Compare) { $Compare = "Healthy"}
Privileged Group Changes

We monitor the privileged groups by using Ashley McGlone’s script to get the changes. You can find that full script here.

Function Get-PrivilegedGroupChanges {            
        $Server = "localhost",            
        $Hour = 24            
        $ProtectedGroups = Get-ADGroup -Filter 'AdminCount -eq 1' -Server $Server            
        $Members = @()            
        ForEach ($Group in $ProtectedGroups) {            
            $Members += Get-ADReplicationAttributeMetadata -Server $Server `
                -Object $Group.DistinguishedName -ShowAllLinkedValues |            
             Where-Object {$_.IsLinkValue} |            
             Select-Object @{name='GroupDN';expression={$Group.DistinguishedName}}, `
                @{name='GroupName';expression={$Group.Name}}, *            
        $Members |            
            Where-Object {$_.LastOriginatingChangeTime -gt (Get-Date).AddHours(-1 * $Hour)}            
    $ListOfChanges = Get-PrivilegedGroupChanges
    if($ListOfChanges -eq $Null) 
    $GroupChanges = "No Changes Detected"
    else {
    foreach($item in $ListOfChanges){
    $GroupChanges += "Group $($ListOfChanges.GroupName) has been changed - $($listofchanges.AttributeValue) has been added or removed"
    if(!$groupChanges) { $GroupChanges = "No Changes Detected"}

4 thoughts on “Monitoring with PowerShell Chapter 3: Monitoring user creation

  1. Paolo Maladosa

    Hi Kelvin,
    I was at last DattoCon in Paris and really appreciated your speech about your partnership with DattoRmm. I’m testing these scripts on my DattoRmm and I’m having some little issues in monitoring new domain users added. It seems like the script only aware the first new user created in the last 24 hours, but doesn’t mention any of the users I’ve created later… I’m pretty sure I’m wrong with some part of the script…

      1. Paolo Maladosa

        Hi Kelvin,
        yes i did and added it to a monitoring policy, but it gives me only the first user i add…. and i’ve changed nothing in the script, of course…

  2. Matt Yordy

    Hi – these scripts are amazing – thank you. I have had enormous success with the first two, but I’m struggling with the “All created local users” script. I keep getting a null (empty) output file at C:\Windows\temp\LocalUsers.txt. I have tried the “Get-LocalUser | Select-Object *” command manually and it lists local user accounts, so somehow the results of this command aren’t being written to C:\Windows\temp\LocalUsers.txt. Suggestions?


Leave a Reply

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.