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.
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.
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.
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.
$EmailParameters = @{ EmailFrom = "notifications@domain.com" EmailTo = "przemyslaw.klys@domain.com, admin@domain.com" EmailCC = "" EmailBCC = "" EmailReplyTo = "" EmailServer = "smtp.office365.com" EmailServerPassword = "YourPassword" EmailServerPasswordAsSecure = $false EmailServerPasswordFromFile = $false 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' Inline = $false } 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 = $false # attaches Excel to email with all events, required ImportExcel 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 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-<currentdate>.<extension>" FilePatternDateFormat = "yyyy-MM-dd-HH_mm_ss" RemoveDuplicates = $true # AsSql = @{ Use = $true SqlServer = 'EVOWIN' SqlDatabase = 'SSAE18' SqlTable = 'dbo.[Events]' # Left side is data in PSWinReporting. Right Side is ColumnName in SQL # Changing makes sense only for right side... SqlTableCreate = $true SqlTableAlterIfNeeded = $false # if table mapping is defined doesn't do anything SqlCheckBeforeInsert = 'EventRecordID', 'DomainController' # Based on column name SqlTableMapping = [ordered] @{ 'Event ID' = 'EventID,[int]' 'Who' = 'EventWho' 'When' = 'EventWhen,[datetime]' 'Record ID' = 'EventRecordID,[bigint]' 'Domain Controller' = 'DomainController' 'Action' = 'Action' 'Group Name' = 'GroupName' 'User Affected' = 'UserAffected' 'Member Name' = 'MemberName' 'Computer Lockout On' = 'ComputerLockoutOn' 'Reported By' = 'ReportedBy' 'SamAccountName' = 'SamAccountName' 'Display Name' = 'DisplayName' 'UserPrincipalName' = 'UserPrincipalName' 'Home Directory' = 'HomeDirectory' 'Home Path' = 'HomePath' 'Script Path' = 'ScriptPath' 'Profile Path' = 'ProfilePath' 'User Workstation' = 'UserWorkstation' 'Password Last Set' = 'PasswordLastSet,[datetime]' 'Account Expires' = 'AccountExpires,[datetime]' 'Primary Group Id' = 'PrimaryGroupId' 'Allowed To Delegate To' = 'AllowedToDelegateTo' 'Old Uac Value' = 'OldUacValue' 'New Uac Value' = 'NewUacValue' 'User Account Control' = 'UserAccountControl' 'User Parameters' = 'UserParameters' 'Sid History' = 'SidHistory' 'Logon Hours' = 'LogonHours' 'OperationType' = 'OperationType' 'Message' = 'Message' 'Backup Path' = 'BackupPath' 'Log Type' = 'LogType' 'AddedWhen' = 'EventAdded,[datetime],null' # ColumnsToTrack when it was added to database and by who / not part of event 'AddedWho' = 'EventAddedWho' # ColumnsToTrack when it was added to database and by who / not part of event 'Gathered From' = 'GatheredFrom' 'Gathered LogName' = 'GatheredLogName' } } DisplayConsole = @{ ShowTime = $true LogFile = "$Env:USERPROFILE\Desktop\PSWinReporting-Manual.log" TimeFormat = "yyyy-MM-dd HH:mm:ss" } Debug = @{ DisplayTemplateHTML = $false Verbose = $false } } $ReportTimes = @{ # Report Per Hour PastHour = $false # 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 = $true # if $true skips Automatic/OnlyPDC/DC for reading logs. However it uses Automatic to deliver size of logs so keep Automatic to $true ForwardServer = $ENV:COMPUTERNAME ForwardEventLog = 'ForwardedEvents' UseDirectScan = $true Automatic = $true OnlyPDC = $false DC = '' } ArchiveProcessing = @{ Use = $false Directories = [ordered] @{ Use = $false MyEvents = 'E:\EventLogs' # #MyOtherEvent = 'C:\MyEvent1' } Files = [ordered] @{ Use = $false #File1 = 'E:\EventLogs\Archive-Security-2018-09-14-22-13-07-710.evtx' } } EventBased = @{ UserChanges = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4720, 4738 LogName = 'Security' IgnoreWords = @{} } UserStatus = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4722, 4725, 4767, 4723, 4724, 4726 LogName = 'Security' IgnoreWords = @{} ExportToSql = @{ Use = $true SqlServer = 'EVOWIN' SqlDatabase = 'SSAE18' SqlTable = 'dbo.[EventsUserStatus]' # Left side is data in PSWinReporting. Right Side is ColumnName in SQL # Changing makes sense only for right side... SqlTableCreate = $true SqlTableAlterIfNeeded = $false # if table mapping is defined doesn't do anything SqlCheckBeforeInsert = 'EventRecordID', 'DomainController' # Based on column name SqlTableMapping = [ordered] @{ 'Event ID' = 'EventID,[int]' 'Who' = 'EventWho' 'When' = 'EventWhen,[datetime]' 'Record ID' = 'EventRecordID,[bigint]' 'Domain Controller' = 'DomainController' 'Action' = 'Action' 'Group Name' = 'GroupName' 'User Affected' = 'UserAffected' 'Member Name' = 'MemberName' 'Computer Lockout On' = 'ComputerLockoutOn' 'Reported By' = 'ReportedBy' 'SamAccountName' = 'SamAccountName' 'Display Name' = 'DisplayName' 'UserPrincipalName' = 'UserPrincipalName' 'Home Directory' = 'HomeDirectory' 'Home Path' = 'HomePath' 'Script Path' = 'ScriptPath' 'Profile Path' = 'ProfilePath' 'User Workstation' = 'UserWorkstation' 'Password Last Set' = 'PasswordLastSet,[datetime]' 'Account Expires' = 'AccountExpires,[datetime]' 'Primary Group Id' = 'PrimaryGroupId' 'Allowed To Delegate To' = 'AllowedToDelegateTo' 'Old Uac Value' = 'OldUacValue' 'New Uac Value' = 'NewUacValue' 'User Account Control' = 'UserAccountControl' 'User Parameters' = 'UserParameters' 'Sid History' = 'SidHistory' 'Logon Hours' = 'LogonHours' 'OperationType' = 'OperationType' 'Message' = 'Message' 'Backup Path' = 'BackupPath' 'Log Type' = 'LogType' 'AddedWhen' = 'EventAdded,[datetime],null' # ColumnsToTrack when it was added to database and by who / not part of event 'AddedWho' = 'EventAddedWho' # ColumnsToTrack when it was added to database and by who / not part of event # 'Gathered From' = 'GatheredFrom' # 'Gathered LogName' = 'GatheredLogName' } } } UserLockouts = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4740 LogName = 'Security' IgnoreWords = @{} } UserLogon = @{ Enabled = $false EnabledSqlGlobal = $true Events = 4624 LogName = 'Security' IgnoreWords = @{} } GroupMembershipChanges = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4728, 4729, 4732, 4733, 4756, 4757, 4761, 4762 LogName = 'Security' IgnoreWords = @{} } GroupCreateDelete = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4727, 4730, 4731, 4734, 4759, 4760, 4754, 4758 LogName = 'Security' IgnoreWords = @{} } GroupPolicyChanges = @{ Enabled = $false EnabledSqlGlobal = $true Events = 5136, 5137, 5141 LogName = 'Security' IgnoreWords = @{} } LogsClearedSecurity = @{ Enabled = $true EnabledSqlGlobal = $true Events = 1102 LogName = 'Security' IgnoreWords = @{} ExportToSql = @{ Use = $false SqlServer = 'EVO1' SqlDatabase = 'SSAE18' SqlTable = 'dbo.[EventsLogsClearedSecurity]' SqlTableCreate = $true SqlTableAlterIfNeeded = $false # if table mapping is defined doesn't do anything SqlCheckBeforeInsert = 'EventRecordID', 'DomainController' # Based on column nameg } } LogsClearedOther = @{ Enabled = $true EnabledSqlGlobal = $true Events = 104 LogName = 'System' # Source: EventLog, Task: 'Log clear' IgnoreWords = @{} } EventsReboots = @{ Enabled = $false EnabledSqlGlobal = $true Events = 1001, 1018, 1, 12, 13, 42, 41, 109, 1, 6005, 6006, 6008, 6013 LogName = 'System' IgnoreWords = @{} } ComputerCreatedChanged = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4741, 4742 # created, changed LogName = 'Security' IgnoreWords = @{} } ComputerDeleted = @{ Enabled = $true EnabledSqlGlobal = $true Events = 4743 # deleted LogName = 'Security' IgnoreWords = @{} } } Custom = @{ EventLogSize = @{ Enabled = $true EnabledSqlGlobal = $false Logs = 'Security', 'Application', 'System' SortBy = '' } ServersData = @{ Enabled = $true EnabledSqlGlobal = $false } FilesData = @{ Enabled = $true } } } } Import-Module PSWinReporting -Force ### Starts Module (Requires config above) $startADReportingSplat = @{ ReportDefinitions = $ReportDefinitions ReportTimes = $ReportTimes FormattingParameters = $FormattingParameters ReportOptions = $ReportOptions EmailParameters = $EmailParameters } Start-ADReporting @startADReportingSplat