Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Build/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ if ($Compile.IsPresent) {

"`$PublicFunctions = '$($Public.BaseName -join "', '")'" | Add-Content .\Output\PSADHealth.psm1

#Let's add New-TaskRegistration.ps1 as part of Non-Module Scripts that get published with the module
Copy-Item -Path '.\Non-Module Scripts\*' -Filter '*.*' -Destination '.\Output\Non-Module Scripts' -Force

Remove-Item -Path .\PSADHealth -Recurse -Force
Rename-Item -Path .\Output -NewName 'PSADHealth'

Expand Down Expand Up @@ -111,4 +114,4 @@ if($Deploy.IsPresent) {
} Catch {
throw $_
}
}
}
42 changes: 27 additions & 15 deletions Non-Module Scripts/New-TaskRegistration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,46 @@ alternatively you could use the following, or one of many other options:
https://gallery.technet.microsoft.com/scriptcenter/Grant-Revoke-Query-user-26e259b0

This is not an endorsement of those modules, just inclduing for awareness.

Updated: 06/01/2020
Removed old commented out command lines for running as scripts
Fixed Get-ADLastBackup to Get-ADLastBackupDate as that is the function name
Change Test-ADObjectReplication from every 2 hours (12 new computer objects created and deleted daily) to daily (1 computer object daily)
Added Register-ScheduledJob commands for the rest of the functions:
Get-DCDiskSpace - hourly
Test-ADServices - hourly
Test-DCsOnline - hourly
Test-ExternalDNSServers - hourly
Test-SRVRecords - hourly
#>
#Create the EventLog Source here that will be used by all the other scripts, so they don't need to be run as administrator.
New-EventLog -LogName Application -Source "PSMonitor"

#Define the interval to repeat job
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely

#Get user credential so that the job has access to the network
$cred = Get-Credential -Credential DOMAIN\Serviceaccount
$cred = Get-Credential #-Credential DOMAIN\Serviceaccount

#Set job options
$opt = New-ScheduledJobOption -RunElevated -RequireNetwork

#Register-ScheduledJob -Name Test-InternalTimeSync -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADTimeSync.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADInternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADInternalTimeSync} -MaxResultCount 5 -scheduledjoboption $opt
#Register-ScheduledJob -Name Test-ExternalTimeSync -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADTimeSyncToExternalNTP.ps1" -MaxResultCount 5 -scheduledjoboption $opt
#Items scheduled to run Daily
#Define the interval to repeat job
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely
Register-ScheduledJob -name Test-ADInternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADInternalTimeSync } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADExternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADExternalTimeSync} -MaxResultCount 5 -scheduledjoboption $opt
#Register-ScheduledJob -Name Test-ADLastBackup -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADLastBackupDate.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Get-ADLastBackup -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Get-ADLastBackup} -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Get-ADLastBackupDate -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Get-ADLastBackupDate} -MaxResultCount 5 -scheduledjoboption $opt
#Shifting schedule half hour off
$trigger = New-JobTrigger -Once -At 6:30AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely
Register-ScheduledJob -name Test-ADObectReplication -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADObectReplication } -MaxResultCount 5 -scheduledjoboption $opt

#Items scheduled to run hourly
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 1) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADReplication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADReplication} -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Get-DCDiskSpace -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Get-DCDiskSpace } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-ADServices -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-ADServices } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-DCsOnline -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-DCsOnline } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-ExternalDNSServers -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-ExternalDNSServers } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-SRVRecords -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-SRVRecords } -MaxResultCount 5 -scheduledjoboption $opt

$trigger = New-JobTrigger -Once -At 6:30AM -RepetitionInterval (New-TimeSpan -Hours 2) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADObectReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADObjectReplication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADObectReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADObectReplication} -MaxResultCount 5 -scheduledjoboption $opt

#Items scheduled to run every two hours
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 2) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADSYSVOLReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-SYSVOL-Replication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-SYSVOLReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-SYSVOLReplication} -MaxResultCount 5 -scheduledjoboption $opt
40 changes: 20 additions & 20 deletions PSADHealth/Config/ADConfig.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"SMTPServer": "smtp.foobar.com",
"MailFrom": "ad_status_alert@foobar.com",
"MailTo": [
"ceo@foobar.com",
"supreme_it_leader@foobar.com"
],
"MaxDaysSinceBackup": "1",
"MaxIntTimeDrift": "45",
"MaxExtTimeDrift": "15",
"ExternalTimeSvr": "time.google.com",
"ExternalDNSServers": [
"208.67.222.222",
"208.67.220.220"
],
"FreeDiskThreshold": "70",
"MaxObjectReplCycles": "50",
"MaxSysvolReplCycles": "50",
"SupportArticle": "https://help.foobar.com/YourTroubleshootingArticles",
"SlackToken": "2343-woeij2-jwoeij223-b2334322"
}
"SMTPServer": "smtp.foobar.com",
"MailFrom": "ad_status_alert@foobar.com",
"MailTo": [
"ceo@foobar.com",
"supreme_it_leader@foobar.com"
],
"MaxDaysSinceBackup": "1",
"MaxIntTimeDrift": "45",
"MaxExtTimeDrift": "15",
"ExternalTimeSvr": "time.google.com",
"ExternalDNSServers": [
"208.67.222.222",
"208.67.220.220"
],
"FreeDiskThreshold": "70",
"MaxObjectReplCycles": "50",
"MaxSysvolReplCycles": "50",
"SupportArticle": "https://help.foobar.com/YourTroubleshootingArticles",
"SlackToken": "2343-woeij2-jwoeij223-b2334322"
}
52 changes: 32 additions & 20 deletions PSADHealth/Non-Module Scripts/New-TaskRegistration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

.NOTES
Author: Greg Onstot
Version: 0.3
Version Date: 04/14/2019
Version: 0.4
Version Date: 04/26/2019

The expectation is that you run these scripts on a separate Tier0 Tool server, to monitor your AD.
It must be a Tier0 systems as the service account monitoring AD should be in Domain Admin to perform a number of these tasks.
Expand All @@ -30,34 +30,46 @@ alternatively you could use the following, or one of many other options:
https://gallery.technet.microsoft.com/scriptcenter/Grant-Revoke-Query-user-26e259b0

This is not an endorsement of those modules, just inclduing for awareness.

Updated: 06/01/2020
Removed old commented out command lines for running as scripts
Fixed Get-ADLastBackup to Get-ADLastBackupDate as that is the function name
Change Test-ADObjectReplication from every 2 hours (12 new computer objects created and deleted daily) to daily (1 computer object daily)
Added Register-ScheduledJob commands for the rest of the functions:
Get-DCDiskSpace - hourly
Test-ADServices - hourly
Test-DCsOnline - hourly
Test-ExternalDNSServers - hourly
Test-SRVRecords - hourly
#>
#Create the EventLog Source here that will be used by all the other scripts, so they don't need to be run as administrator.
New-EventLog -LogName Application -Source "PSMonitor"

#Define the interval to repeat job
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely

#Get user credential so that the job has access to the network
$cred = Get-Credential -Credential DOMAIN\Serviceaccount
$cred = Get-Credential #-Credential DOMAIN\Serviceaccount

#Set job options
$opt = New-ScheduledJobOption -RunElevated -RequireNetwork

#Register-ScheduledJob -Name Test-InternalTimeSync -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADTimeSync.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADInternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADInternalTimeSync} -MaxResultCount 5 -scheduledjoboption $opt
#Register-ScheduledJob -Name Test-ExternalTimeSync -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADTimeSyncToExternalNTP.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADExternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADExternalTimeSync} -MaxResultCount 5 -scheduledjoboption $opt
#Register-ScheduledJob -Name Test-ADLastBackup -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADLastBackupDate.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Get-ADLastBackup -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Get-ADLastBackup} -MaxResultCount 5 -scheduledjoboption $opt
#Items scheduled to run Daily
#Define the interval to repeat job
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely
Register-ScheduledJob -name Test-ADInternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADInternalTimeSync } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADExternalTimeSync -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADExternalTimeSync } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Get-ADLastBackupDate -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Get-ADLastBackupDate } -MaxResultCount 5 -scheduledjoboption $opt
#Shifting schedule half hour off
$trigger = New-JobTrigger -Once -At 6:30AM -RepetitionInterval (New-TimeSpan -Hours 24) -RepeatIndefinitely
Register-ScheduledJob -name Test-ADObectReplication -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADObectReplication } -MaxResultCount 5 -scheduledjoboption $opt

#Items scheduled to run hourly
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 1) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADReplication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADReplication} -MaxResultCount 5 -scheduledjoboption $opt

$trigger = New-JobTrigger -Once -At 6:30AM -RepetitionInterval (New-TimeSpan -Hours 2) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADObectReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-ADObjectReplication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADObectReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADObectReplication} -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADReplication -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-ADReplication } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Get-DCDiskSpace -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Get-DCDiskSpace } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-ADServices -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-ADServices } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-DCsOnline -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-DCsOnline } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-ExternalDNSServers -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-ExternalDNSServers } -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -Name Test-SRVRecords -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth); Test-SRVRecords } -MaxResultCount 5 -scheduledjoboption $opt

#Items scheduled to run every two hours
$trigger = New-JobTrigger -Once -At 6:00AM -RepetitionInterval (New-TimeSpan -Hours 2) -RepeatIndefinitely
#Register-ScheduledJob -Name Test-ADSYSVOLReplication -Trigger $trigger -Credential $cred -FilePath "C:\Scripts\Test-SYSVOL-Replication.ps1" -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-ADSYSVOLReplication -Trigger $trigger -Credential $cred -ScriptBlock {(Import-Module -name PSADHealth) ; Test-ADSYSVOLReplication} -MaxResultCount 5 -scheduledjoboption $opt
Register-ScheduledJob -name Test-SYSVOLReplication -Trigger $trigger -Credential $cred -ScriptBlock { (Import-Module -name PSADHealth) ; Test-SYSVOLReplication } -MaxResultCount 5 -scheduledjoboption $opt
Binary file modified PSADHealth/PSADHealth.psd1
Binary file not shown.
15 changes: 15 additions & 0 deletions PSADHealth/PSADHealth.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
$Private = @(Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -Exclude *.tests.ps1 -ErrorAction SilentlyContinue)
$Public = @(Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Exclude *.tests.ps1 -ErrorAction SilentlyContinue)

ForEach ($import in @($Public + $Private)) {
Try {
. $import.FullName
}
Catch {
Write-Error -Message "Failed to import function $($import.FullName): $_"
}
}
foreach ($function in $Public) {
$func = $function.BaseName -replace 'Function-', ''
Export-ModuleMember -Function $func
}
46 changes: 38 additions & 8 deletions PSADHealth/Private/Send-AlertCleared.ps1
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
function Send-AlertCleared {
<#
.SYNOPSIS
Take InError as input and determines calling function to send email to notify that a formerly failing problem has cleared

.DESCRIPTION
Take InError as input and determines calling function to send email to notify that a formerly failing problem has cleared

.EXAMPLE
PS C:\> Send-AlertCleared -InError <TextBlock>
Loads configuration from the parent scope $Configuration and then sends an SMTP email with the InError text as part of the body

.NOTES
Updated: 05/29/2020
Cleaned up formatting a little bit
Added #Requires -Modules ActiveDirectory
Added a Comment Help section
Made this an advance function by adding [cmdletbinding()] so that Verbose will work
This function was written for Test-ADInternalTimeSync function but is being used by 3 other functions currently (Test-ADObjectReplication, Test-ADReplication, Test-SysvolReplication)
I defined $CallingFunction by getting the name of the function that called Send-AlertCleared (Get-Variable -Name MyInvocation -Scope 1).Value.MyCommand.Name
I then modified the email subject and body to utilize this variable so that the clear message will make more sense. I also include the $InError parameter in the body of the email

#>
[cmdletbinding()]
Param($InError)
Write-Verbose "Sending Email"
Write-Verbose "Output is -- $InError"
#Requires -Modules ActiveDirectory
$CallingFunction = (Get-Variable -Name MyInvocation -Scope 1).Value.MyCommand.Name
Write-Verbose -Message "Calling Function: $CallingFunction"
Write-Verbose -Message "Sending Email"
Write-Verbose -Message "Output is -- $InError"

#Mail Server Config
$NBN = (Get-ADDomain).NetBIOSName
Write-Verbose -Message "NetBIOSName: $NBN"
$Domain = (Get-ADDomain).DNSRoot
Write-Verbose -Message "Domain : $Domain"
$smtpServer = $Configuration.SMTPServer
Write-Verbose -Message "SMTPServer : $smtpServer"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg = new-object Net.Mail.MailMessage

Expand All @@ -15,23 +44,24 @@ function Send-AlertCleared {
If ($emailCount -gt 0){
$Emails = $Configuration.MailTo
foreach ($target in $Emails){
Write-Verbose "email will be sent to $target"
$msg.To.Add("$target")
Write-Verbose -Message "email will be sent to $target"
$msg.To.Add("$target")
}
}
Else{
Write-Verbose "No email addresses defined"
Write-Verbose -Message "No email addresses defined"
Write-eventlog -logname "Application" -Source "PSMonitor" -EventID 17030 -EntryType Error -message "ALERT - No email addresses defined. Alert email can't be sent!" -category "17030"
}
#Message:
$msg.From = $Configuration.MailFrom
$msg.ReplyTo = $Configuration.MailFrom
$msg.subject = "$NBN AD Internal Time Sync - Alert Cleared!"
$msg.subject = "$NBN - $CallingFunction - Alert Cleared!"
$msg.body = @"
The previous Internal AD Time Sync alert has now cleared.
$InError
The previous $CallingFunction alert has now cleared.

Thanks.
"@
#Send it
$smtp.Send($msg)
}
}
Loading