-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSolarWinds-FileContentMonitor.ps1
More file actions
131 lines (107 loc) · 5.58 KB
/
SolarWinds-FileContentMonitor.ps1
File metadata and controls
131 lines (107 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function Search-FileContentForSolarWinds {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[string]
$FolderPath,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[string]
$FileNameRegularExpression,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[string]
$ContentRegularExpression,
[Parameter(Mandatory = $false,
ValueFromPipelineByPropertyName = $true,
Position = 3)]
[string]
$StatisticsFileDirectory = (Join-Path $env:temp "SolarWindsFileContentMonitor")
)
process {
Write-Verbose "Statistics files will be written to $StatisticsFileDirectory";
# Make sure the TempFileDirectory exists
if ((Test-Path $StatisticsFileDirectory) -eq $false) {
New-Item -Path $StatisticsFileDirectory -ItemType Directory -ErrorAction Stop | Out-Null;
}
$StatisticsExtension = ".stats";
# Find all files that match the filename pattern
$MatchingFiles = Get-ChildItem -Path $FolderPath -ErrorAction SilentlyContinue | Where-Object -FilterScript {$_.Name -match $FileNameRegularExpression} -ErrorAction Stop;
# Sort based on last date - makes the output later in the script reflect the name of the newest file (which is usually what is wanted)
$MatchingFiles = $MatchingFiles | Sort-Object LastWriteTime;
# If no matching files, just end
Write-Host "Statistic.MatchingFiles: $(@($MatchingFiles).Count)";
Write-Host "Message.MatchingFiles: $(@($MatchingFiles).Count) matching files found in $FolderPath";
if ((@($MatchingFiles).Count -gt 0) -eq $false) {
return 0;
}
# Setup variables for looping through monitored files and collecting totals
$TotalNewRows = 0;
$LastOccurenceFileName = "";
$LastOccurenceLineNumber = 0;
$LastOccurenceLine = "";
# For each monitored file
foreach ($MonitoredFile in $MatchingFiles) {
# Find a matching ScriptRun file in the temp directory
$StatsFile = Join-Path $StatisticsFileDirectory ($MonitoredFile.Name + $StatisticsExtension);
# Stats variable
$Stats = @{
FileSize = $null;
LastModifiedDateUtcTicks = $null;
RowCount = 0;
}
# If not present create one; otherwise attempt to read it
if ((Test-Path $StatsFile) -eq $false) {
Write-Verbose "Creating $StatsFile";
$Stats | ConvertTo-Json | Out-File $StatsFile -ErrorAction Stop;
} else {
Write-Verbose "Reading $StatsFile";
$Stats = Get-Content $StatsFile -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop;
}
# With file present, determine if you need to exhaust resources searching
$ShouldSearch = $false;
# Convert to UTC and get the ticks. Had a lot of trouble with JSON conversion to/from DateTime simplifying the time.
if ($MonitoredFile.LastWriteTimeUtc.Ticks -ne $Stats.LastModifiedDateUtcTicks) {
$ShouldSearch = $true;
} elseif ($MonitoredFile.Length -ne $Stats.FileSize) {
$ShouldSearch = $true;
}
if ($ShouldSearch) {
Write-Verbose "$($MonitoredFile.Name) has changed and will be searched.";
# File has changed, so search it
$MatchingRows = $MonitoredFile | Select-String -Pattern $ContentRegularExpression;
$RowCount = $MatchingRows.Count;
# See if the RowCount matches what is recorded in the Stats file
if ($RowCount -ne $Stats.RowCount) {
$NewRows = $RowCount - $Stats.RowCount;
$MatchingRow = $MatchingRows | Select-Object -Last 1;
Write-Verbose "$($MonitoredFile.Name) has $NewRows occurrences";
$TotalNewRows = $TotalNewRows + $NewRows;
$LastOccurenceFileName = $MonitoredFile.Name;
$LastOccurenceLineNumber = $MatchingRow.LineNumber;
$LastOccurenceLine = $MatchingRow.Line;
}
# Update stats file
Write-Verbose "Updating $StatsFile";
$Stats = @{
FileSize = $MonitoredFile.Length;
LastModifiedDateUtcTicks = $MonitoredFile.LastWriteTimeUtc.Ticks;
RowCount = $RowCount;
}
$Stats | ConvertTo-Json | Out-File $StatsFile -ErrorAction Stop;
}
}
if ($TotalNewRows -gt 0) {
Write-Host "Statistic.NewMatches: $TotalNewRows";
Write-Host "Message.NewMatches: Last occurence appears to be found in $LastOccurenceFileName on line $LastOccurenceLineNumber '$LastOccurenceLine'";
} else {
Write-Host "Statistic.NewMatches: 0";
Write-Host "Message.NewMatches: No new matches found since last occurrence.";
}
}
}
Search-FileContentForSolarWinds -FolderPath 'C:\Program Files (x86)\SomeLogDirectory' -FileNameRegularExpression "log" -ContentRegularExpression "error";