-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDomain Expiry Check.ps1
454 lines (388 loc) · 18.1 KB
/
Domain Expiry Check.ps1
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.191
Created on: 04/07/2022 16:10
Created by: Dvir F
Organization: ITMS
Filename: Domain Expiry Check.ps1
===========================================================================
.DESCRIPTION
Script to get expiry info.
#>
# If not using a json file for SMTP please provide the config here:
param (
[Parameter(Mandatory = $false)]
[String]$smtpUser = "apikey",
[Parameter(Mandatory = $false)]
[String]$smtpPass = "PASS",
[Parameter(Mandatory = $false)]
[String]$smtpServer = "smtp.sendgrid.net",
[Parameter(Mandatory = $false)]
[String]$smtpPort = "587",
[Parameter(Mandatory = $false)]
[Bool]$smtpUseSSL = $true,
[Parameter(Mandatory = $false)]
[String]$smtpFrom = "ExpiryReport@corp.com",
[Parameter(Mandatory = $false)]
[String]$smtpTo = "helpdesk+ExpiryReport@corp.com",
[Parameter(Mandatory = $false)]
[String]$smtpSubject = "Cert And Domain Expiry Report"
)
# If you want, you can use a json file instead for the smtp, leave it empty if using the params:
#$smtpFile = "$PSScriptRoot\smtp.json" # Link or file location for SMTP json
#===========================================================================
$inputFile = "https://XXXXXXXXX.sharepoint.com/:x:/s/Automation/EQx1SzOpO5hPt7YseUVjTC8Bi-xxxxxxxxx_ysTC7Q?e=rbkymn&download=1" # Link or file location for Expiry list
$inputFile = "C:\Temp\Domains.xlsx"
$formatTime = "yyyy-MM-dd" <# Time format for report #>
$warningDays = "30"
$outputFilesFolder = "C:\Temp"
$domainFileHTML = "DomainExpiry.html" <# Domain HTML Report file name #>
$certFileHTML = "CertExpiry.html" <# Cert HTML Report file name #>
$domainFileXLSX = "DomainExpiry.xlsx" <# Domain XLSX Report file name #>
$certFileXLSX = "CertExpiry.xlsx" <# Cert XLSX Report file name #>
$domainExpiryWarningJSON = "DomainExpiryWarning.json" <# Domain JSON Report file name #>
$certExpiryWarningJSON = "CertExpiryWarning.json" <# Cert JSON Report file name #>
function Get-DomainExpiry
{
if (Test-Path -Path "$outputFilesFolder\$domainFileHTML") { Remove-Item -Path "$outputFilesFolder\$domainFileHTML" -Force } <# Clean before running #>
if (Test-Path -Path "$outputFilesFolder\$domainFileXLSX") { Remove-Item -Path "$outputFilesFolder\$domainFileXLSX" -Force } <# Clean before running #>
# Grab today date in the formats required
try { $todayTime = Get-Date -format $formatTime } <# Try to handle time issues on US or EU formats #>
catch { [datetime]$todayTime = Get-Date -format $formatTime } <# Try to handle time issues on US or EU formats #>
Write-Output "Today: $todayTime"
$resultArray = @()
$warningArray = @()
if (!([string]::IsNullOrEmpty($inputFile))) # if the domain names file isnt missing, run domain names testing
{
if ($inputFile -like "*://*") # if link
{
Write-Output "Downloading to `"$env:windir\Temp\Domains.xlsx`""
try { Invoke-WebRequest $inputFile -OutFile "$env:windir\Temp\Domains.xlsx" -Verbose -ErrorAction Ignore | Wait-Job }
catch [System.Net.WebException] { Write-Output "Link Broken / No network."; exit }
$inputFile = "$env:windir\Temp\Domains.xlsx"
}
elseif ($inputFile -like "*.xlsx*") { Write-Output "Using `"$inputFile`"" }
else { Write-Verbose "Cant find a link for or an .xlsx or a `".xlsx`" file."; exit }
$importXLSX = Import-XLSX -Path $inputFile -Header "Domain", "Cert"
$inputFile = $([Array]$importXLSX.Domain)
}
foreach ($item in $inputFile)
{
if (!([string]::IsNullOrEmpty($item)))
{
$domainExpiryCommand = Invoke-Process -FilePath "$env:windir\Temp\whois.exe" -ArgumentList $item
function Get-DomainExpiryDate <# Function to get the Exipry based on info pattern & time format in the whois registry #>
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Array]$InfoPatterns,
[Parameter(Mandatory = $true)]
[Array]$timeFormatsPatterns
)
Clear-Variable -Name domainExpiryInfo -ErrorAction SilentlyContinue
Clear-Variable -Name domainExpiryDate -ErrorAction SilentlyContinue
Clear-Variable -Name updateTimeFormat -ErrorAction SilentlyContinue
foreach ($infoPattern in $infoPatterns)
{
$domainExpiryInfo = $domainExpiryCommand -split "`n" | Select-String -Pattern $infoPattern -AllMatches | Select-Object -Unique <# Try to find a pattern #>
if ($domainExpiryInfo -ne $null) { <#Write-Output "$infoPattern" ;#> break } <# Stop the loop when found a line with exipry info #>
}
$domainExpiryDate = $domainExpiryInfo -replace "$infoPattern", "" -replace "`n", "" -replace "`r", "" -replace " ", "" <# Clean the date #>
if ($domainExpiryDate -like "*T*") { $domainExpiryDate = $domainExpiryDate.split('T')[0] } <# Split time data if found (Remove hh:mm:ss) #>
#Write-Output "$item - `"$domainExpiryDate`""
foreach ($timeFormatsPattern in $timeFormatsPatterns) <# Try to match the date format from the list #>
{
#Write-Output "tryTimeFormat: $tryTimeFormat"
$error.clear() <# Clean errors before next test #>
try { $updateTimeFormat = [datetime]::ParseExact($domainExpiryDate, $timeFormatsPattern, $null) } <# Test the date format and try to match it #>
catch { } <# Error found, loop #>
if (!$error) { break } <# If there is no errors keep going #>
}
try { $domainExpiryDate = Get-Date $($updateTimeFormat) -Format $formatTime } <# Fix the data format for the script output #>
catch { $domainExpiryDate = $todayTime } <# In case of a broken date, reset to today (0) #>
return $domainExpiryDate
}
if ($item -like "*.com") <# Mini filter to skip testing for "*.com" #>
{
$domainExpiryDate = Get-DomainExpiryDate -InfoPatterns "Registry Expiry Date:" -TimeFormatsPatterns "yyyy-MM-dd"
}
elseif ($item -like "*.co.il") <# Mini filter to skip testing for "*.com" #>
{
$domainExpiryDate = Get-DomainExpiryDate -InfoPatterns "validity:" -TimeFormatsPatterns "dd-MM-yyyy"
}
else <# For everything else #>
{
[Array]$InfoPatterns = "Registry Expiry Date:", "Expiration Date:", "validity:", "Expiry date:" <# Every info pattern I found, I could be missing more #>
[Array]$TimeFormatsPatterns = "$formatTime", "yyyy-MM-dd", "dd-MM-yyyy", "dd-MMM-yyyy" <# Every time pattern I found, I could be missing more #>
$domainExpiryDate = Get-DomainExpiryDate -InfoPatterns $InfoPatterns -TimeFormatsPatterns $TimeFormatsPatterns
}
$domainExpiryLeft = New-Timespan -Start $todayTime -End $domainExpiryDate
$domainExpiryLeft = $domainExpiryLeft -replace ".00:00:00", "" -replace "00:00:00", "0" <# Remove hours and keep only date #>
#Write-Output "domainExpiryInfo: $domainExpiryInfo"
#Write-Output "$item - `"$domainExpiryLeft($domainExpiryDate)`""
if ([int]$domainExpiryLeft -le [int]$warningDays) <# feed domain into the warning list if its under or equal to $warningDays #>
{
$warningArray = @(
@{
Domain = $item
DomainExpiryLeft = $domainExpiryLeft
} <# warning into json format #>
)
[Array]$domainWarningList += $warningArray <# feed all warnings into array for json file #>
}
# Export results
$exportResult = @{ 'Domain' = $item; 'Expiry Date' = $domainExpiryDate; 'Expiry Left' = $domainExpiryLeft }
$exportResults = New-Object PSObject -Property $exportResult
$exportResults | Select-Object 'Domain', 'Expiry Date', 'Expiry Left' <# Show in output #>
$exportResults | Select-Object 'Domain', 'Expiry Date', 'Expiry Left' | Export-XLSX -Path "$outputFilesFolder\$domainFileXLSX" -Force -Append <# Export to XLSX #>
$resultArray += $exportResults | Select-Object 'Domain', 'Expiry Date', 'Expiry Left' <# Feed the data into array for the HTML file #>
Start-Sleep -Seconds 10 # To not get blocked by whois for spam
}
}
$domainWarningList | ConvertTo-Json | Out-File "$outputFilesFolder\$domainExpiryWarningJSON" -Force
$resultArray | Out-HtmlView -FilePath "$outputFilesFolder\$domainFileHTML" -DisablePaging -PreventShowHTML <# Export to HTML #>
}
function Get-CertExpiry
{
if (Test-Path -Path "$outputFilesFolder\$certFileHTML") { Remove-Item -Path "$outputFilesFolder\$certFileHTML" -Force } <# Clean before running #>
if (Test-Path -Path "$outputFilesFolder\$certFileXLSX") { Remove-Item -Path "$outputFilesFolder\$certFileXLSX" -Force } <# Clean before running #>
# Grab today date in the formats required
try { $todayTime = Get-Date -format $formatTime } <# Try to handle time issues on US or EU formats #>
catch { [datetime]$todayTime = Get-Date -format $formatTime } <# Try to handle time issues on US or EU formats #>
Write-Output "Today: $todayTime"
$resultArray = @()
$warningArray = @()
if (!([string]::IsNullOrEmpty($inputFile))) # if the domain names file isnt missing, run domain names testing
{
if ($inputFile -like "*://*") # if link
{
Write-Output "Downloading to `"$env:windir\Temp\Domains.xlsx`""
try { Invoke-WebRequest $inputFile -OutFile "$env:windir\Temp\Domains.xlsx" -Verbose -ErrorAction Ignore | Wait-Job }
catch [System.Net.WebException] { Write-Output "Link Broken / No network."; exit }
$inputFile = "$env:windir\Temp\Domains.xlsx"
}
elseif ($inputFile -like "*.xlsx*") { Write-Output "Using `"$inputFile`"" }
else { Write-Verbose "Cant find a link for or an .xlsx or a `".xlsx`" file."; exit }
$importXLSX = Import-XLSX -Path $inputFile -Header "Domain", "Cert"
$inputFile = $([Array]$importXLSX.Cert)
}
foreach ($item in $inputFile)
{
if (!([string]::IsNullOrEmpty($item)))
{
# Run the qurry to get cert information
$certFail = $false
try
{
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$req = [Net.HttpWebRequest]::Create($item)
$req.GetResponse() | Out-Null
$certExpiryDate = Get-Date $($req.ServicePoint.Certificate.GetExpirationDateString()) -Format $formatTime
}
catch { $certFail = $true }
if ($certFail)
{
try
{
$servicePoint = [System.Net.ServicePointManager]::FindServicePoint("$item")
$certExpiryDate = Get-Date $($servicePoint.Certificate.GetExpirationDateString()) -Format $formatTime
}
catch { $certExpiryDate = $todayTime; $certFail = $true }
}
# Fix the domain cert time format
if (![string]::IsNullOrEmpty($certExpiryDate)) <# In case no cert found #>
{
#Write-Output "Test domainCertExpiryDate: $certExpiryDate"
try { $certExpiryLeft = New-Timespan -Start $todayTime -End $certExpiryDate <# Get the domainCertExpirydateLeft (EU Format) #> }
catch { $certExpiryLeft = New-Timespan -Start ([datetime]$todayTime) -End ([datetime]$certExpiryDate) <# Get the domainCertExpirydateLeft (US Format) #> }
$certExpiryLeft = $certExpiryLeft -replace ".00:00:00", "" -replace "00:00:00", "0" <# Remove hours and keep only date #>
#Write-Output "Test domainCertExpiryDateLeft: $certExpiryLeft"
}
else { $certExpiryLeft = "0" }
if ([int]$certExpiryLeft -le [int]$warningDays) <# feed domain into the warning list if its under or equal to $warningDays #>
{
$warningArray = @(
@{
Cert = $item
CertExpiryLeft = $certExpiryLeft
} <# warning into json format #>
)
[Array]$certWarningList += $warningArray <# feed all warnings into array for json file #>
}
# Export results
$exportResult = @{ 'Cert' = $item; 'Expiry Date' = $certExpiryDate; 'Expiry Left' = $certExpiryLeft }
$exportResults = New-Object PSObject -Property $exportResult
$exportResults | Select-Object 'Cert', 'Expiry Date', 'Expiry Left' <# Show in output #>
$exportResults | Select-Object 'Cert', 'Expiry Date', 'Expiry Left' | Export-XLSX -Path "$outputFilesFolder\$certFileXLSX" -Force -Append <# Export to XLSX #>
$resultArray += $exportResults | Select-Object 'Cert', 'Expiry Date', 'Expiry Left' <# Feed the data into array for the HTML file #>
}
}
$certWarningList | ConvertTo-Json | Out-File "$outputFilesFolder\$CertExpiryWarningJSON" -Force
$resultArray | Out-HtmlView -FilePath "$outputFilesFolder\$certFileHTML" -DisablePaging -PreventShowHTML <# Export to HTML #>
}
function Send-CustomMailMessage
{
if (!([string]::IsNullOrEmpty($smtpFile))) # if the domain names file isnt missing, run domain names testing
{
if ($smtpFile -like "*://*") # if link
{
Write-Output "Downloading to `"$env:windir\Temp\smtp.json`""
try { Invoke-WebRequest $smtpFile -OutFile "$env:windir\Temp\smtp.json" -Verbose -ErrorAction Ignore | Wait-Job }
catch [System.Net.WebException] { Write-Output "Link Broken / No network."; exit }
$smtpFile = "$env:windir\Temp\smtp.json"
}
elseif ($smtpFile -like "*.json*") { Write-Output "Using `"$smtpFile`"" }
$smtpConfig = (Get-Content "$smtpFile" -Raw) | ConvertFrom-Json <# Grab config from JSON file #>
$sstr = ConvertTo-SecureString -string $($smtpConfig.Login_Pass) -AsPlainText -Force; $smtpCredential = New-Object System.Management.Automation.PSCredential -argumentlist $($smtpConfig.Login_User), $sstr # Convert Pass
# SSL true or false
If ($smtpConfig.SSL -like "*true*") { $smtpUseSSL = $true }
If ($smtpConfig.SSL -like "*false*") { $smtpUseSSL = $false }
$smtpServer = $smtpConfig.Server
$smtpPort = $smtpConfig.Port
$smtpFrom = $smtpConfig.From
$smtpTo = $smtpConfig.To
$smtpSubject = $smtpConfig.Subject
}
else
{
Write-Output "Using provided SMTP Settings"
$sstr = ConvertTo-SecureString -string $smtpPass -AsPlainText -Force; $smtpCredential = New-Object System.Management.Automation.PSCredential -argumentlist $smtpUser, $sstr # Convert Pass
}
# Add files if it can find the files
$attachmentsFiles = "$outputFilesFolder\$domainFileHTML", "$outputFilesFolder\$domainFileXLSX", "$outputFilesFolder\$certFileHTML", "$outputFilesFolder\$certFileXLSX"
foreach ($attachmentsFile in $attachmentsFiles) { if (Test-Path $attachmentsFile) { [Array]$smtpAttachments += $attachmentsFile } }
# Add the warnings from JSON files.
$domainWarningList = (Get-Content "$outputFilesFolder\$domainExpiryWarningJSON" -Raw) | ConvertFrom-Json
foreach ($domainWarning in $domainWarningList)
{
$domainWarningOutput += @"
`'$($domainWarning.Domain)`' - $($domainWarning.DomainExpiryLeft) Days left<br>
<br>
"@
}
$certWarningList = (Get-Content "$outputFilesFolder\$CertExpiryWarningJSON" -Raw) | ConvertFrom-Json
foreach ($certWarning in $certWarningList)
{
$certWarningNotHyper = $($certWarning.Cert).replace("://", " ")
$certWarningOutput += @"
`'$certWarningNotHyper`' - $($certWarning.CertExpiryLeft) Days left<br>
<br>
"@
}
function Get-ExternalIP
{
$NetworkIP = "1.1.1.1" <# Ping Test server IP #>
[Array]$ipTestSitesList = "http://ifconfig.me/ip", "http://icanhazip.com", "http://icanhazip.com", "http://ident.me", "http://smart-ip.net/myip"
$ipPattern = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"
$pingNetwork = Test-Connection -ComputerName $NetworkIP -Count 1 -Quiet -ErrorAction Ignore
if ($pingNetwork)
{
foreach ($ipTestSites in $ipTestSitesList) <# Get external IP #>
{
$ipTest = (Invoke-WebRequest -uri "$ipTestSites" -UseBasicParsing).Content
if ($ipTest -match $ipPattern)
{
Return $ipTest
break
}
}
}
}
$externalIP = Get-ExternalIP
$smtpBody = @"
<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
<tbody>
<tr>
<td style="text-align:center">Domain certs with less than $warningDays days</td>
<td style="text-align:center">Domain names with less than $warningDays days</td>
</tr>
<tr>
<td style="text-align:center">$certWarningOutput</td>
<td style="text-align:center">$domainWarningOutput</td>
</tr>
</tbody>
</table>
<p>Script running from server: $env:COMPUTERNAME</p>
<p>IP: $externalIP</p>
<p> </p>
"@
Send-MailMessage -SmtpServer $smtpServer -Port $smtpPort -UseSsl:$smtpUseSSL -Credential $smtpCredential -From $smtpFrom -To $smtpTo -Subject $smtpSubject -Attachments $smtpAttachments -Body $smtpBody -BodyAsHtml
}
function Invoke-Program-Install
{
$installSource = "https://download.sysinternals.com/files/WhoIs.zip"
$installZip = "WhoIs.zip"
if (!(Test-Path -Path "$env:windir\Temp\$installZip")) <# Lookup if the exe is there #>
{ Invoke-WebRequest $installSource -OutFile "$env:windir\Temp\$installZip" | Wait-Job }
Expand-Archive -Path "$env:windir\Temp\$installZip" -DestinationPath "$env:windir\Temp" -Force -ErrorAction SilentlyContinue
#if (Test-Path -Path "$env:windir\Temp\$installZip") { Remove-Item -Path "$env:windir\Temp\$installZip" -Force }
}
function Invoke-Process
{
[CmdletBinding(SupportsShouldProcess)]
param
(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$ArgumentList
)
$ErrorActionPreference = 'Stop'
try
{
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $FilePath
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.WindowStyle = 'Hidden'
$pinfo.CreateNoWindow = $true
$pinfo.Arguments = $ArgumentList
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$result = [pscustomobject]@{
Title = ($MyInvocation.MyCommand).Name
Command = $FilePath
Arguments = $ArgumentList
StdOut = $p.StandardOutput.ReadToEnd()
StdErr = $p.StandardError.ReadToEnd()
ExitCode = $p.ExitCode
}
$p.WaitForExit()
return $result.StdOut; break
}
catch { exit }
}
function Install-CustomModule
{
param (
[Parameter(Mandatory = $true)]
[Array]$modules
)
foreach ($module in $modules)
{
try
{
#Write-Output "Importing module '$module'"
Import-Module $module -ErrorAction Stop
}
catch
{
Write-Output "Could not find '$module' module, installing..."
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Verbose:$false *>$null
Install-Module -Name $module -Scope AllUsers -AllowClobber -Force
Import-Module $module -ErrorAction Stop
#Write-Output "Importing module '$module'"
}
}
}
Invoke-Program-Install
Install-CustomModule -modules "PSWriteHTML", "PSExcel"
Get-DomainExpiry
Get-CertExpiry
Send-CustomMailMessage