Skip to content

Commit 6faeb93

Browse files
Merge pull request #294 from P6g9YHK6/main
updates updates updates
2 parents a43d3bf + 4cbe674 commit 6faeb93

File tree

7 files changed

+239
-93
lines changed

7 files changed

+239
-93
lines changed

scripts_staging/Backend/Mail notification password expiry.ps1

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,49 @@
11
<#
22
.SYNOPSIS
3-
Analyse et notification avancée des utilisateurs dont le mot de passe Active Directory approche de l’expiration.
3+
Analyzes Active Directory user accounts for upcoming password expiration and optionally sends notifications.
4+
45
.DESCRIPTION
5-
Ce script interroge Active Directory pour lister les utilisateurs d’une OU cible et calcule la date d’expiration de leur mot de passe selon la politique du domaine.
6-
Les comptes sont classés selon l’urgence :
7-
- Expiré : mot de passe déjà expiré
8-
- Critique : expiration imminente (seuil critique)
9-
- Avertissement : expiration proche (seuil d’avertissement)
10-
Notifications automatiques :
11-
• Email pour tous les utilisateurs concernés
12-
Un rapport HTML détaillé est généré :
13-
• Politique de mot de passe du domaine
14-
• Statistiques par catégorie
15-
• Liste détaillée des comptes par statut
16-
.PARAMETER TargetOU
17-
OU cible pour la recherche des utilisateurs (ex : "OU=Utilisateurs,DC=domaine,DC=local")
18-
.PARAMETER WarningThreshold
19-
Jours avant expiration pour déclencher un avertissement (défaut : 15)
20-
.PARAMETER CriticalThreshold
21-
Jours avant expiration pour déclencher une alerte critique (défaut : 7)
22-
.PARAMETER IncludeDisabled
23-
Inclure les comptes désactivés dans le rapport (défaut : false)
24-
.PARAMETER IncludeNeverExpires
25-
Inclure les comptes dont le mot de passe n’expire jamais (défaut : false)
26-
.PARAMETER EmailSignature
27-
Signature personnalisée pour les emails (optionnel)
6+
This script is configured entirely through environment variables and performs the following:
7+
- Targets a specific Organizational Unit (OU) for user account analysis
8+
- Uses configurable thresholds to classify accounts as warning or critical
9+
- Optionally includes disabled accounts and accounts with passwords set to never expire
10+
- Sends email reports to a list of administrator recipients or can generate reports only
11+
- Supports customizable email signature and SMTP configuration for email delivery
12+
13+
Accounts are classified based on password expiration:
14+
- Warning: password is approaching expiration (WarningThreshold)
15+
- Critical: password is close to expiring (CriticalThreshold)
16+
2817
.NOTES
29-
Prérequis :
30-
- Module ActiveDirectory
31-
- Accès SMTP pour l’envoi d’emails
32-
- Droits d’administration pour les tâches planifiées
18+
Dependency:
19+
CallPowerShell7 snippet
3320
Author: PQU
3421
Date: 29/04/2025
3522
#public
23+
24+
.EXAMPLE
25+
# Example usage with environment variables set before running the script:
26+
27+
TARGET_OU=OU=Employees,DC=example,DC=local
28+
SMTP_SERVER=smtp.example.com
29+
SMTP_PORT=587
30+
31+
32+
WARNING_THRESHOLD=14
33+
CRITICAL_THRESHOLD=7
34+
EMAIL_SIGNATURE=Best regards,<br>IT Department
35+
INCLUDE_DISABLED=true
36+
INCLUDE_NEVER_EXPIRES=false
37+
GENERATE_REPORT_ONLY=false
38+
3639
.CHANGELOG
3740
22.05.25 SAN – Added UTF8 encoding to resolve issues with Russian and French characters.
3841
06.06.25 PQU – Added support for multiple admin emails and centralized config.
42+
03.07.25 SAN - Update docs
43+
44+
.TODO
45+
Multiple Locale support
46+
3947
#>
4048

4149

scripts_staging/Checks/Active Directory Health.ps1

Lines changed: 108 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,113 @@
1313
#public
1414
1515
.CHANGELOG
16+
17.07.25 SAN Big cleanup of bug fixes for the dcdiag function, fixes of error codes, output in stderr of all errors for readability
17+
18+
.TODO
19+
Do a breakdown at the top of the output for easy read with ok/ko returns from functions
1620
1721
#>
1822

1923
# Initialize exit code
20-
$exitCode = 0
24+
$global:exitCode = 0
2125

2226
# Function to perform Active Directory tests
2327
function CheckAD {
2428
[CmdletBinding()]
2529
param (
26-
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
27-
[string[]]$Tests
30+
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
31+
[string[]]$Tests,
32+
33+
[Parameter()]
34+
[hashtable]$SuccessPatterns = @{
35+
'en' = @('passed test')
36+
'fr' = @('a réussi', 'a reussi', 'a russi', 'ussi')
37+
},
38+
39+
[Parameter()]
40+
[int]$MinimumMatches = 2
2841
)
2942

30-
process {
31-
$results = @{}
43+
$DebugMode = $false
44+
$global:exitCode = 0
3245

33-
foreach ($test in $Tests) {
34-
$output = dcdiag /test:$test
46+
# Combine all success patterns from all languages into a single list
47+
$allPatterns = @()
48+
foreach ($lang in $SuccessPatterns.Keys) {
49+
$allPatterns += $SuccessPatterns[$lang]
50+
}
3551

36-
if ($output -notmatch "chou") {
37-
$results[$test] = "OK"
38-
} else {
39-
$results[$test] = "Failed!"
40-
$global:exitCode++
52+
if ($DebugMode) {
53+
Write-Host "`n[DEBUG] Loaded Success Patterns:"
54+
foreach ($p in $allPatterns) {
55+
Write-Host " - $p"
56+
}
57+
Write-Host ""
58+
}
59+
60+
$results = @{}
61+
62+
foreach ($test in $Tests) {
63+
Write-Host "`nRunning DCDIAG test: $test"
64+
65+
# Start dcdiag process and redirect output
66+
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
67+
$startInfo.FileName = "dcdiag.exe"
68+
$startInfo.Arguments = "/test:$test"
69+
$startInfo.RedirectStandardOutput = $true
70+
$startInfo.RedirectStandardError = $true
71+
$startInfo.UseShellExecute = $false
72+
$startInfo.CreateNoWindow = $true
73+
$process = New-Object System.Diagnostics.Process
74+
$process.StartInfo = $startInfo
75+
$process.Start() | Out-Null
76+
$stream = $process.StandardOutput.BaseStream
77+
$memoryStream = New-Object System.IO.MemoryStream
78+
$buffer = New-Object byte[] 4096
79+
while (($read = $stream.Read($buffer, 0, $buffer.Length)) -gt 0) {
80+
$memoryStream.Write($buffer, 0, $read)
81+
}
82+
$process.WaitForExit()
83+
84+
$bytes = $memoryStream.ToArray()
85+
$output = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
86+
87+
if ($DebugMode) {
88+
$preview = if ($output.Length -gt 800) { $output.Substring(0,800) + "`n..." } else { $output }
89+
Write-Host "[DEBUG] DCDIAG Output Preview:"
90+
Write-Host $preview
91+
Write-Host ""
92+
}
93+
94+
$matchCount = 0
95+
foreach ($pattern in $allPatterns) {
96+
$count = ([regex]::Matches($output, [regex]::Escape($pattern))).Count
97+
$matchCount += $count
98+
99+
if ($DebugMode) {
100+
Write-Host "[DEBUG] Pattern '$pattern' matched $count time(s)."
41101
}
102+
}
103+
104+
if ($DebugMode) {
105+
Write-Host "[DEBUG] Total success match count: $matchCount`n"
106+
}
42107

43-
# Output individual test result
44-
Write-Host "DCDIAG Test: $test Result: $($results[$test])"
108+
if ($matchCount -ge $MinimumMatches) {
109+
$results[$test] = "OK"
110+
} else {
111+
$results[$test] = "Failed!"
112+
Write-Error "$results[$test] = Failed!"
113+
$global:exitCode++
45114
}
46115

47-
$results
116+
Write-Host "DCDIAG Test: $test Result: $($results[$test])"
48117
}
118+
119+
return $results
49120
}
50121

51122
# Function to compare GPO version numbers
52-
53123
function Compare-GPOVersions {
54124
[CmdletBinding()]
55125
param ()
@@ -72,34 +142,36 @@ function Compare-GPOVersions {
72142

73143
# USER - Compare version numbers
74144
if ($NumUserSysvol -ne $NumUserAD) {
75-
Write-Host "$GPOName ($GPOId) : USER Versions différentes (Sysvol : $NumUserSysvol | AD : $NumUserAD)" -ForegroundColor Red
145+
Write-Host "$GPOName ($GPOId) : USER Versions différentes (Sysvol : $NumUserSysvol | AD : $NumUserAD)"
146+
Write-Error "$GPOName ($GPOId) : USER Versions différentes (Sysvol : $NumUserSysvol | AD : $NumUserAD)"
76147
$global:exitCode++
77148
} else {
78-
Write-Host "$GPOName : USER Versions identiques" -ForegroundColor Green
149+
Write-Host "$GPOName : USER Versions identiques"
79150
}
80151

81152
# COMPUTER - Compare version numbers
82-
if ($NumComputerSysvol -ne $NumComputerAD) {
83-
Write-Host "$GPOName ($GPOId) : COMPUTER Versions différentes (Sysvol : $NumComputerSysvol | AD : $NumComputerAD)" -ForegroundColor Red
153+
if ($NumComputerSysvol -ne $NumComputerAD) {Health
154+
Write-Host "$GPOName ($GPOId) : COMPUTER Versions différentes (Sysvol : $NumComputerSysvol | AD : $NumComputerAD)"
155+
Write-Error "$GPOName ($GPOId) : COMPUTER Versions différentes (Sysvol : $NumComputerSysvol | AD : $NumComputerAD)"
84156
$global:exitCode++
85157
} else {
86-
Write-Host "$GPOName : COMPUTER Versions identiques" -ForegroundColor Green
158+
Write-Host "$GPOName : COMPUTER Versions identiques"
87159
}
88160
}
89-
Write-Host "GPO USER/COMPUTER Version OK" -ForegroundColor Green
161+
Write-Host "GPO USER/COMPUTER Version OK"
90162
}
91163
}
92164

93165
# Function to check if the Recycle Bin in enabled
94-
95166
function Check-ADRecycleBin {
96167
$recycleFeatures = Get-ADOptionalFeature -Filter {name -like "recycle bin feature"}
97168

98169
foreach ($feature in $recycleFeatures) {
99170
if ($null -ne $feature.EnabledScopes) {
100-
Write-Output "OK: Recycle Bin enabled"
171+
Write-Host "OK: Recycle Bin enabled"
101172
} else {
102-
Write-Output "KO: Recycle Bin disabled"
173+
Write-Host "KO: Recycle Bin disabled"
174+
Write-Error "KO: Recycle Bin disabled"
103175
$global:exitCode++
104176
}
105177
}
@@ -110,31 +182,29 @@ try {
110182
$adFeature = Get-WindowsFeature -Name AD-Domain-Services -ErrorAction Stop
111183

112184
if ($adFeature.InstallState -eq "Installed") {
113-
# Specify your AD tests
185+
186+
# function with the AD tests
114187
$tests = ("Advertising", "FrsSysVol", "MachineAccount", "Replications", "RidManager", "Services", "FsmoCheck", "SysVolCheck")
115-
# Call the function with the AD tests
116-
Write-Host "DCDIAG"
188+
Write-Host "DCDIAG tests: $tests"
117189
$testResults = CheckAD -Tests $tests
118-
119190
$failedTests = $testResults.GetEnumerator() | Where-Object { $_.Value -eq "Failed!" }
120-
121191
if ($failedTests) {
122192
Write-Error "Some Active Directory tests failed."
123-
$failedTests | ForEach-Object { Write-Error "$($_.Key) test failed." }
124-
$global:exitCode += $failedTests.Count
125193
} else {
126194
Write-Host "All Active Directory tests passed successfully."
127195
}
128196
Write-Host ""
197+
198+
# function to compare GPO versions
129199
Write-Host "GPO Versions checks"
130-
# Call the function to compare GPO versions
131200
Compare-GPOVersions
132-
133201
Write-Host ""
202+
203+
# function to check the Recycle Bin
134204
Write-Host "Recycle Bin checks"
135-
# Call the function to check the Recycle Bin
136205
Check-ADRecycleBin
137-
206+
Write-Host ""
207+
138208
} else {
139209
Write-Host "Active Directory Domain Services feature is not installed or not in the 'Installed' state."
140210
exit
@@ -144,4 +214,5 @@ try {
144214
$global:exitCode++
145215
}
146216

147-
exit $exitCode
217+
$host.SetShouldExit($global:exitCode)
218+
exit $global:exitCode

scripts_staging/Checks/Disk Free Space.ps1

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,38 @@
2929
#public
3030
3131
.CHANGELOG
32-
32+
17.07.25 SAN Added debug flag, taken into account cases where all drives are ignored.
33+
34+
3335
.TODO
34-
Add debug flag
3536
move flags to env
3637
3738
#>
3839

39-
4040
param(
4141
[int]$warningThreshold = 10,
4242
[int]$errorThreshold = 5,
43-
[string[]]$ignoreDisks = @()
43+
[string[]]$ignoreDisks = @(),
44+
[bool]$DebugOutput = $false
4445
)
4546

4647
function CheckDiskSpace {
4748
[CmdletBinding()]
4849
param()
4950

5051
# Get all local drives excluding network drives and the ones specified to ignore
51-
$drives = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 -and $_.DeviceID -notin $ignoreDisks }
52+
$allDrives = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 }
53+
$drives = $allDrives | Where-Object { $_.DeviceID -notin $ignoreDisks }
54+
55+
if ($drives.Count -eq 0) {
56+
Write-Host "OK: disks $($ignoreDisks -join ', ') are ignored"
57+
if ($DebugOutput) {
58+
Write-Host "[DEBUG] Total drives found: $($allDrives.Count)"
59+
Write-Host "[DEBUG] Ignored drives: $($ignoreDisks -join ', ')"
60+
}
61+
$host.SetShouldExit(0)
62+
return
63+
}
5264

5365
$failedDrives = @()
5466
$warningDrives = @()
@@ -77,23 +89,38 @@ function CheckDiskSpace {
7789
Write-Host "OK: $($drive.DeviceID) has $($freeSpacePercent)% free space."
7890
}
7991
}
92+
93+
if ($DebugOutput) {
94+
if ($failedDrives.Count -gt 0) {
95+
Write-Host "DEBUG: The following drives failed:"
96+
$failedDrives | ForEach-Object {
97+
$p = [math]::Round(($_.FreeSpace / $_.Size) * 100, 2)
98+
Write-Host "DEBUG: $($_.DeviceID): $p%"
99+
}
100+
} elseif ($warningDrives.Count -gt 0) {
101+
Write-Host "DEBUG: The following drives are in warning:"
102+
$warningDrives | ForEach-Object {
103+
$p = [math]::Round(($_.FreeSpace / $_.Size) * 100, 2)
104+
Write-Host "DEBUG: $($_.DeviceID): $p%"
105+
}
106+
} else {
107+
Write-Host "DEBUG: All drives have sufficient free space."
108+
}
109+
}
110+
80111
if ($failedDrives.Count -gt 0) {
81-
# Write-Host "ERROR: The following drives have less than $($errorThreshold)% free space:"
82-
# $failedDrives | ForEach-Object { Write-Host "$($_.DeviceID): $([math]::Round(($_.FreeSpace / $_.Size) * 100, 2))%" }
83-
# Write-Host "ERROR: exit 2"
112+
if ($DebugOutput) { Write-Host "DEBUG: exit code 2" }
84113
$host.SetShouldExit(2)
85114
}
86115
elseif ($warningDrives.Count -gt 0) {
87-
# Write-Host "WARNING: The following drives have less than $($warningThreshold)% free space:"
88-
# $warningDrives | ForEach-Object { Write-Host "$($_.DeviceID): $([math]::Round(($_.FreeSpace / $_.Size) * 100, 2))%" }
89-
# Write-Host "Warning: exit 1"
116+
if ($DebugOutput) { Write-Host "DEBUG: exit code 1" }
90117
$host.SetShouldExit(1)
91118
}
92119
else {
93-
# Write-Host "OK: All drives have sufficient free space."
120+
if ($DebugOutput) { Write-Host "DEBUG: exit code 0" }
94121
$host.SetShouldExit(0)
95122
}
96123
}
97124

98125
# Execute the function
99-
CheckDiskSpace
126+
CheckDiskSpace

0 commit comments

Comments
 (0)