Skip to content

Instantly share code, notes, and snippets.

@ConnorGriffin
Created March 12, 2018 19:34
Show Gist options
  • Save ConnorGriffin/3c73ec7dd143f3f7aedd3785756ae6b9 to your computer and use it in GitHub Desktop.
Save ConnorGriffin/3c73ec7dd143f3f7aedd3785756ae6b9 to your computer and use it in GitHub Desktop.
Script to schedule Nessus scans based around the Microsoft patch cycle
<#
.SYNOPSIS
Schedule Nessus scans based around the Microsoft patch cycle
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][String]$ComputerName,
[Int]$Port = 8834,
[Parameter(Mandatory=$true)][String]$ScanFolder,
[Parameter(Mandatory=$true)][DateTime]$RangeStartTime,
[Parameter(Mandatory=$true)][DateTime]$RangeEndTime,
[Parameter(Mandatory=$true)][Int]$PatchTuesdayOffset,
[Bool]$EmailNotify=$false,
[String[]]$SendTo,
[PSCredential]$Credential,
[String]$AccessKey,
[String]$SecretKey
)
# Simplified Get-PatchTuesday, returns based on current month
function Get-PatchTuesday {
# Calculate patch tuesday for this month
$baseDate = Get-Date (Get-Date -Format "yyyy-MM-01")
(0..30 | ForEach-Object {$baseDate.AddDays($_)} | Where-Object {$_.DayOfWeek -like "Tue*"})[1]
}
# Get the patch and scan dates
$patchTuesday = Get-PatchTuesday
$scanDate = $patchTuesday.AddDays($PatchTuesdayOffset)
# Set the static nessus parameters
$nessusParams = @{
ComputerName = $ComputerName
Port = $Port
}
# Add the credentials or API keys
if ($Credential) {
$nessusParams.Credentials = $Credential
}
elseif ($AccessKey -and $SecretKey) {
$nessusParams.AccessKey = $AccessKey
$nessusParams.SecretKey = $SecretKey
}
else {
Write-Error 'No credentials or API keys provided'
Return
}
# Initialize a session with Nessus
$session = New-NessusSession @nessusParams
# Get all of the scan folders
$scanFolders = Get-NessusFolder -SessionId $session.SessionId
# Get the target folder and the scan IDs within
$targetFolder = $scanFolders.Where{$_.Name -eq $ScanFolder}
if (!$targetFolder) {Write-Error "Folder: $ScanFolder not found."}
[Array]$targetScans = Get-NessusScan -SessionId $session.SessionId -FolderId $targetFolder.FolderId
# Add a day to datetimes if the end time is in the next day
if ($RangeEndTime.Hour -lt $RangeStartTime.Hour) {
$RangeEndTime = $RangeEndTime.AddDays(1)
$scanEndDate = $scanDate.AddDays(1)
} else {
$scanEndDate = $scanDate
}
# Calculate the start time
$startYMD = $scanDate.ToString('yyyy-MM-dd')
$startHM = $RangeStartTime.ToString('HH:mm')
$startDateTime = Get-Date ("$startYMD $startHM")
# Calculate the end time
$endYMD = $scanEndDate.ToString('yyyy-MM-dd')
$endHM = $RangeEndTime.ToString('HH:mm')
$endDateTime = Get-Date ("$endYMD $endHM")
# Calculate the time span
$timeSpan = New-TimeSpan -Start $startDateTime -End $endDateTime
$msOffset = $timeSpan.TotalMilliseconds / ($targetScans.Count - 1)
# Iterate through scans, scheduling across the time range
$scheduledScans = $targetScans.ForEach{
# Offset the scan
$currentScan = $targetScans.IndexOf($_)
if ($targetScans.Count -gt 1) {
$scanStart = $startDateTime.AddMilliseconds($msOffset * $currentScan)
} else {
$scanStart = $startDateTime
}
$scan = Set-NessusScanSchedule -SessionId $session.SessionId -ScanId $_.ScanId -StartTime $scanStart
[PSCustomObject]@{
'Scan' = $_.name
'Start Time' = $scanStart.ToString('yyyy-MM-dd HH:mm:ss')
}
}
# Send an email if the setting is enabled
if ($EmailNotify -and $SendTo) {
$html = Get-Content "$PSScriptRoot\Resources\ScheduleEmailTemplate.html"
$html = $html.Replace('$schedule',"$($startDateTime.ToString('yyyy-MM-dd HH:mm:ss')) to $($endDateTime.ToString('yyyy-MM-dd HH:mm:ss'))")
$html = $html.Replace('$table',($scheduledScans | ConvertTo-Html -Fragment))
$emailParams = @{
SmtpServer = 'azmtaprd01.az.int'
From = 'No Reply <[email protected]>'
To = $SendTo
Subject = "Nessus Scan Scheduling - $ScanFolder"
Body = $html -join "`n"
BodyAsHtml = $true
}
Send-MailMessage @emailParams
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment