Skip to content

Instantly share code, notes, and snippets.

@davidlu1001
Last active July 7, 2024 22:13
Show Gist options
  • Select an option

  • Save davidlu1001/b82cdd3b0b00eb2936e18d1d19401f46 to your computer and use it in GitHub Desktop.

Select an option

Save davidlu1001/b82cdd3b0b00eb2936e18d1d19401f46 to your computer and use it in GitHub Desktop.
Scan Config
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerNames = @($env:COMPUTERNAME),
[string[]]$ScanPaths = @("D:\", "E:\"),
[string]$OutputFile = "DNSUrls_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv",
[string]$LogFile = "ScanLog_$(Get-Date -Format 'yyyyMMdd_HHmmss').log",
[string]$UrlPattern = '(?i)([a-z0-9-]+\.)+co\.nz',
[int]$MaxConcurrentJobs = 5,
[int]$BatchSize = 1000
)
$ErrorActionPreference = "Stop"
function Write-Log {
param([string]$Message)
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $Message"
Add-Content -Path $LogFile -Value $logMessage
Write-Verbose $logMessage
}
function Scan-ConfigFiles {
param (
[string]$ComputerName,
[string[]]$Paths,
[string]$Pattern,
[int]$BatchSize
)
$scriptBlock = {
param($Paths, $Pattern, $BatchSize)
function Process-FileBatch {
param($Files)
$results = @()
foreach ($file in $Files) {
try {
$content = [System.IO.File]::ReadAllText($file.FullName)
$matches = [regex]::Matches($content, $Pattern)
foreach ($match in $matches) {
$results += New-Object PSObject -Property @{
HostName = $env:COMPUTERNAME
ConfigPath = $file.FullName
DnsUrl = $match.Value
}
}
}
catch {
Write-Warning "Error processing file $($file.FullName): $_"
}
}
return $results
}
$allFiles = @()
foreach ($path in $Paths) {
try {
$allFiles += Get-ChildItem -Path $path -Recurse -Include *.json, *.conf -ErrorAction Stop
}
catch {
Write-Warning "Error accessing path $path: $_"
}
}
$totalFiles = $allFiles.Count
Write-Verbose "Total files found: $totalFiles"
$results = @()
for ($i = 0; $i -lt $totalFiles; $i += $BatchSize) {
$batch = $allFiles | Select-Object -Skip $i -First $BatchSize
$batchResults = Process-FileBatch -Files $batch
$results += $batchResults
Write-Verbose "Processed $($i + $batch.Count) of $totalFiles files"
}
return $results
}
try {
if ($ComputerName -eq $env:COMPUTERNAME) {
return & $scriptBlock $Paths $Pattern $BatchSize
} else {
$session = New-PSSession -ComputerName $ComputerName -ErrorAction Stop
return Invoke-Command -Session $session -ScriptBlock $scriptBlock -ArgumentList $Paths, $Pattern, $BatchSize
}
}
catch {
Write-Log "Error scanning $ComputerName: $_"
return $null
}
finally {
if ($session) {
Remove-PSSession $session
}
}
}
try {
Write-Log "Starting scan on computers: $($ComputerNames -join ', ')"
$jobs = @()
foreach ($computer in $ComputerNames) {
Write-Log "Initiating scan on $computer"
$job = Start-Job -ScriptBlock ${function:Scan-ConfigFiles} -ArgumentList $computer, $ScanPaths, $UrlPattern, $BatchSize
$jobs += $job
while (($jobs | Where-Object { $_.State -eq 'Running' }).Count -ge $MaxConcurrentJobs) {
$completedJob = $jobs | Wait-Job -Any
$results = Receive-Job $completedJob
if ($results) {
$results | Export-Csv -Path $OutputFile -NoTypeInformation -Append
}
Remove-Job $completedJob
$jobs = @($jobs | Where-Object { $_.State -ne 'Completed' })
}
}
while ($jobs) {
$completedJob = $jobs | Wait-Job -Any
$results = Receive-Job $completedJob
if ($results) {
$results | Export-Csv -Path $OutputFile -NoTypeInformation -Append
}
Remove-Job $completedJob
$jobs = @($jobs | Where-Object { $_.State -ne 'Completed' })
}
Write-Log "Scan complete. Results saved to $OutputFile"
# stats
$results = Import-Csv -Path $OutputFile
$hostCount = @($results | Select-Object -Unique HostName).Count
$urlCount = $results.Count
Write-Log "Scanned $hostCount hosts, found $urlCount matching URLs"
}
catch {
Write-Log "Critical error in main script execution: $_"
}
finally {
Write-Log "Script execution completed"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment