This PowerShell Module, which started as an event library (Get-EventsLibrary.ps1), has now grown up and became full fledged PowerShell Module. This module has multiple functionalities but one of the signature features of this module is ability to parse Security (mostly) logs on Domain Controllers. But that's not all. You can set up reporting on it and have emails delivered with summary of hourly, daily, weekly, monthly or quarterly changes. Changes that happen on your Active Directory Domain. Changes that your Service Desk agents, or other administrators do. And with new versions… well you can do a lot of stuff. Just read below. Make sure to go thru related articles as they have all the KNOW HOW which is quite useful if you want to get everything from this module.

Active Directory events it can track
  • Group create, delete, modify (Who / When / What)
  • Group membership changes (Who / When / What)
  • User changes (Who / When / What)
  • User created / deleted (Who / When)
  • User password changes (Who / When)
  • User lockouts (Who / When / Where)
  • Computer Created / Modified (Who / When / Where)
  • Computer Deleted (Who / When / Where)
  • Event Log Backup (Who / When)
  • Event Log Clear (Who / When)
New features
  • Support for Event Forwarding – monitoring one event log instead of scanning all domain controllers
  • Support for Microsoft Teams – Sending events as they happen to Microsoft Teams (only supported when forwarders are in use)
  • Support for Slack – Sending events as they happen to Slack (only supported when forwarders are in use)
  • Support for Microsoft SQL – Sending events directly to SQL (some people prefer it that way)
  • Support for backing up old archived logs (moves logs from Domain Controllers into chosen place)
  • Support for re-scanning logs from files – a way to recheck your logs for missing information
Note worthy features
Provides easy to use and free monitoring of Windows Events
Allows you to monitor who and when did changes to AD
Code uses Runspaces allowing you to run code in parallel
Much faster then Get-EventsLibrary.ps1
Can be run daily, weekly, monthly or on demand
Useful links
Code is published on GitHub
Issues should be reported on GitHub
Code is published as a module on PowerShellGallery
But what is it actually?

You can talk what you want … but what is it actually? Well… one picture is worth a lot of words.

Well… that's not much. I know it's empty… but if there are actions.. you actually get things displayed.

What else? How about sending to Slack?

PSWinReporting Send To Slack

What else? How about sending to Microsoft Teams?

What else? How about sending to MS SQL?

Related articles
Review of new features in PSWinReporting 1.7 – Lots of changes, review required. Microsoft Teams, Slack, SQL and forwarders support
Review of new features in PSWinReporting 1.0 – Lots of changes, review required.
Last version of Get-EventsLibrary.ps1 – This is actual code base for the old version. Just in case…
Blog post about version 0.8 – Updates from feedback. Last version before name change.
Blog post about version 0.7 – Updates from feedback.
Blog post about version 0.6 – Updates from feedback.
Blog post about initial version and the differences in monitoring approach
To Do
Support for forwarded events
Support for encrypting email password
Active Directory Diagnostics Reporting
File Server Events monitoring
Required prerequisites

Before you are able to use this script you need to do few manual steps. Since this script is published as module… it's quite easy to set this up. Just execute commands below and use the below configuration file…

Install-Module PSWinReporting
Install-Module PSWriteColor
Install-Module PSEventViewer
Install-Module PSWriteExcel
Install-Module PSSharedGoods

When you want to update this module… just use

Update-Module PSWinReporting
Update-Module PSWriteColor
Update-Module PSEventViewer
Update-Module PSWriteExcel
Update-Module PSSharedGoods

And if you want to use advanced functionality of this module (export to SQL, export to MS Teams, Slack) you need following modules

Install-Module PSTeams
Install-Module PSSlack # not my module - big thanks to psCookieMonster
Install-Module dbaTools # not my module - big thanks to whole DBATools community

When you want to update this module… just use

Update-Module PSTeams
Update-Module PSSlack # not my module - big thanks to psCookieMonster
Update-Module dbaTools # not my module - big thanks to whole DBATools community

While this module is PSWinReporting I've decided to split out some parts of Get-EventsLibrary.ps1 (former name) into separate functions/modules. That's why there are more modules to install. You can of course install everything manually from GitHub (as everything is published there) but it will be far easier to just use Install-Module.

How do I get this running?

Essentially to run this module you just have to put following code into file, change settings to fit your needs (Email Parameters, Branding, Report Options and Report Times) and run it. That's it! After you're happy with results just Schedule it and enjoy free Windows Active Directory monitoring. Of course remember to Install prerequisites.

You should also consider reading related articles above. They contain useful information, features description and some know how.

### Starts Module (Requires config above)
Clear-Host
Import-Module PSWinReporting #-Force
Import-Module PSSharedGoods #-Force

$EmailParameters = @{
    EmailFrom            = "notifications@domain.com"
    EmailTo              = "przemyslaw.klys@domain.com, admin@domain.com"
    EmailCC              = ""
    EmailBCC             = ""
    EmailReplyTo         = ""
    EmailServer          = "smtp.office365.com"
    EmailServerPassword  = "YourPassword"
    EmailServerPort      = "587"
    EmailServerLogin     = "notifications@domain.com"
    EmailServerEnableSSL = 1
    EmailEncoding        = "Unicode"
    EmailSubject         = "[Reporting] Event Changes for period <<DateFrom>> to <<DateTo>>"
    EmailPriority        = "Low" # Normal, High
}
$FormattingParameters = @{
    CompanyBranding        = @{
        Logo   = 'https://evotec.xyz/wp-content/uploads/2015/05/Logo-evotec-012.png'
        Width  = '200'
        Height = ''
        Link   = 'https://evotec.xyz'
    }
    FontFamily             = 'Calibri Light'
    FontSize               = '9pt'
    FontHeadingFamily      = 'Calibri Light'
    FontHeadingSize        = '12pt'

    FontTableHeadingFamily = 'Calibri Light'
    FontTableHeadingSize   = '9pt'

    FontTableDataFamily    = 'Calibri Light'
    FontTableDataSize      = '9pt'

    Colors                 = @{
        # case sensitive
        Red   = 'removed', 'deleted', 'locked out', 'lockouts', 'disabled', 'Domain Admins', 'was cleared'
        Blue  = 'changed', 'changes', 'change', 'reset'
        Green = 'added', 'enabled', 'unlocked', 'created'
    }
    Styles                 = @{
        # case sensitive
        B = 'status', 'Domain Admins', 'Enterprise Admins', 'Schema Admins', 'was cleared', 'lockouts' # BOLD
        I = '' # Italian
        U = 'status'# Underline
    }
    Links                  = @{

    }
}
$ReportOptions = @{
    JustTestPrerequisite  = $false # runs testing without actually running script

    AsExcel               = $true # attaches Excel to email with all events, required PSWriteExcel module
    AsCSV                 = $false # attaches CSV to email with all events,
    AsHTML                = $true # puts exported data into email directly with all events
    SendMail              = $false
    OpenAsFile            = $true # requires AsHTML set to $true
    KeepReports           = $true # keeps files after reports are sent (only if AssExcel/AsCSV are in use)
    KeepReportsPath       = 'C:\Support\Reports\ExportedEvents' # if empty, temp path is used
    FilePattern           = 'Evotec-ADMonitoredEvents-<currentdate>.<extension>'
    FilePatternDateFormat = 'yyyy-MM-dd-HH_mm_ss'

    DisplayConsole        = @{
        ShowTime   = $true
        LogFile    = ''
        TimeFormat = 'yyyy-MM-dd HH:mm:ss'
    }
    Debug                 = @{
        DisplayTemplateHTML = $false
        Verbose             = $false
    }
}
$ReportTimes = @{
    # Report Per Hour
    PastHour             = $true # if it's 23:22 it will report 22:00 till 23:00
    CurrentHour          = $false # if it's 23:22 it will report 23:00 till 00:00
    # Report Per Day
    PastDay              = $false # if it's 1.04.2018 it will report 31.03.2018 00:00:00 till 01.04.2018 00:00:00
    CurrentDay           = $false # if it's 1.04.2018 05:22 it will report 1.04.2018 00:00:00 till 01.04.2018 00:00:00
    # Report Per Week
    OnDay                = @{
        Enabled = $false
        Days    = 'Monday'#, 'Tuesday'
    }
    # Report Per Month
    PastMonth            = @{
        Enabled = $false # checks for 1st day of the month - won't run on any other day unless used force
        Force   = $false  # if true - runs always ...
    }
    CurrentMonth         = $true

    # Report Per Quarter
    PastQuarter          = @{
        Enabled = $false # checks for 1st day fo the quarter - won't run on any other day
        Force   = $false
    }
    CurrentQuarter       = $false
    # Report Custom
    CurrentDayMinusDayX  = @{
        Enabled = $false
        Days    = 7    # goes back X days and shows just 1 day
    }
    CurrentDayMinuxDaysX = @{
        Enabled = $false
        Days    = 3 # goes back X days and shows X number of days till Today
    }
    CustomDate           = @{
        Enabled  = $false
        DateFrom = get-date -Year 2018 -Month 03 -Day 19
        DateTo   = get-date -Year 2018 -Month 03 -Day 23
    }
    Everything           = $false
}
$ReportDefinitions = @{
    TimeToGenerate = $false

    ReportsAD      = @{
        Servers    = @{
            UseForwarders   = $false # if $true skips Automatic/OnlyPDC/DC for reading logs. However it uses Automatic to deliver size of logs so keep Automatic to $true
            ForwardServer   = 'EVO1'
            ForwardEventLog = 'ForwardedEvents'

            Automatic       = $true # will use all DCs for a forest
            OnlyPDC         = $false # will use PDC of current domain returned by Get-ADDomain
            DC              = ''
        }
        EventBased = @{
            UserChanges            = @{
                Enabled     = $true
                Events      = 4720, 4738
                LogName     = 'Security'
                IgnoreWords = ''
            }
            UserStatus             = @{
                Enabled     = $true
                Events      = 4722, 4725, 4767, 4723, 4724, 4726
                LogName     = 'Security'
                IgnoreWords = @{
                    'Domain Controller' = ''
                    'Action'            = ''
                    'User Affected'     = 'Win-*', '*AD1$*'
                    'Who'               = ''
                    'When'              = ''
                    'Event ID'          = ''
                    'Record ID'         = ''
                }
            }
            UserLockouts           = @{
                Enabled     = $true
                Events      = 4740
                LogName     = 'Security'
                IgnoreWords = ''
            }
            ComputerCreatedChanged = @{
                Enabled     = $true
                Events      = 4741, 4742 # created, changed
                LogName     = 'Security'
                IgnoreWords = ''
            }
            ComputerDeleted        = @{
                Enabled     = $true
                Events      = 4743 # deleted
                LogName     = 'Security'
                IgnoreWords = ''
            }
            UserLogon              = @{
                Enabled     = $false
                Events      = 4624
                LogName     = 'Security'
                IgnoreWords = ''
            }
            UserLogonKerberos      = @{
                Enabled     = $false
                Events      = 4768
                LogName     = 'Security'
                IgnoreWords = ''
            }
            GroupMembershipChanges = @{
                Enabled     = $true
                Events      = 4728, 4729, 4732, 4733, 4756, 4757, 4761, 4762
                LogName     = 'Security'
                IgnoreWords = @{
                    'Who' = '*ANONYMOUS*'
                }
            }
            GroupCreateDelete      = @{
                Enabled     = $true
                Events      = 4727, 4730, 4731, 4734, 4759, 4760, 4754, 4758
                LogName     = 'Security'
                IgnoreWords = @{
                    'Who' = '*ANONYMOUS*'
                }
            }
            GroupPolicyChanges     = @{
                Enabled     = $true
                Events      = 5136, 5137, 5141
                LogName     = 'Security'
                IgnoreWords = ''
            }
            LogsClearedSecurity    = @{
                Enabled     = $true
                Events      = 1102, 1105
                LogName     = 'Security'
                IgnoreWords = ''
            }
            LogsClearedOther       = @{
                Enabled     = $true
                Events      = 104
                LogName     = 'System'
                IgnoreWords = ''
            }
            EventsReboots          = @{
                Enabled     = $false
                Events      = 1001, 1018, 1, 12, 13, 42, 41, 109, 1, 6005, 6006, 6008, 6013
                LogName     = 'System'
                IgnoreWords = ''
            }
        }
        Custom     = @{
            EventLogSize = @{
                Enabled = $true
                Logs    = 'Security', 'Application', 'System'
                SortBy  = ''
            }
            ServersData  = @{
                Enabled = $true
            }
        }
    }
}

Start-ADReporting -EmailParameters $EmailParameters -FormattingParameters $FormattingParameters -ReportOptions $ReportOptions -ReportTimes $ReportTimes -ReportDefinitions $ReportDefinitions

This is a unique website which will require a more modern browser to work! Please upgrade today!