Rods-RDServer-Tools.psm1
function Get-AdminStatus { Return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } function Get-RDGWLogons { # Show RD Gateway Connection Log (Successful Connections) Get-WinEvent -FilterHashTable @{LogName='Microsoft-Windows-TerminalServices-Gateway/Operational';ID='302'} } function Enable-OfficeSharedActivation { # Check Admin Elevation Status if ((Get-AdminStatus) -ieq $false) { Write-Host "TERMINATING: This script needs to run from elevated PowerShell console." -ForegroundColor Red Return } Set-ItemProperty -Path "HKLM:\Software\Microsoft\Office\ClickToRun\Configuration" -Name "SharedComputerLicensing" -Value 1 -Type String -Force Write-Host "Microsoft Offce 365 Apps Shared Computer Activation is now enabled on this system." } ############################### # RD Web Bad Actors ############################### function Get-RDWebBadActorIPs { # Scan latest IIS Log (Daily) for multiple failed logon attempts that exceed threshold # Command Line Paramters param([string]$Firewall,[int]$Days,[switch]$Clip,[switch]$EventLog,[int]$LogonAttempts) # Debugging output $debug = 0 Write-Host "Get-RDWebBadActorIPs v24.5.5" -ForegroundColor Yellow # Check Admin Elevation Status if ((Get-AdminStatus) -ieq $false) { Write-Host "TERMINATING: This script needs to run from elevated PowerShell console." -ForegroundColor Red Return } # If no days specified in arguments, set to 2 (today and yesterday) if($Days -eq 0){$Days = 2} # If no LogonAttempts value set in arguments, set the number of of logon attempts to 20 if ($LogonAttempts -eq 0) {$LogonAttempts = 20} # Count the number of failed logons in the Log $Instances = 0 # Set the path to the log folder $logFolderPath = "C:\inetpub\logs\LogFiles\W3SVC1" Write-Host "Starting scan of $Days IIS log files located at $logFolderPath" Write-Host "Failed Logon Attempts threshold set to $LogonAttempts" # Get the latest log file in the folder $latestLogFile = Get-ChildItem -Path $logFolderPath -Filter "*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First $Days # Search for lines with HTTP code 200 and 'POST' method in the log files $ipCount = @{} Get-Content -Path $latestLogFile.FullName | Where-Object { # Only process lines with HTTP code 200 and 'POST' method $_ -match 'POST' -and $_ -match ' 200 ' -and [DateTime]::ParseExact($_.Substring(0, 19), 'yyyy-MM-dd HH:mm:ss', $null) } | ForEach-Object { # Extract timestamp and IP address from each matching line $Instances++ $line = $_ $ipAddress = ($line -split ' ')[-7] # IP Filtering $regexPattern = "^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*" # Check if IP is private or public if ($ipaddress -match $regexPattern) { # Debugging output if ($debug -eq 1) {Write-Host "Skipping $ipaddress"} } else { # Count the occurrences of the IP address if ($ipCount.containskey($ipaddress)) { $ipCount[$ipaddress]++ } else { $ipCount[$ipaddress] = 1 } } } Write-Host "Found $Instances failed logons from the selected log files" $BadIPAddresses = @() # Send IPs that occur more than a defined number of times $ipCount.getenumerator() | Where-Object { $_.value -gt $LogonAttempts } | ForEach-Object { $ipaddress = $_.name $BadIPAddresses += $_.name if ($debug -eq 1) {Write-Host "`tIPv4: $ipaddress"} # Debugging output #if ($debug -eq 1) {Write-Host "Many failed logons from: $ipaddress"} } # Determine if UPDATE Firewall arg was used, if so if ($Firewall -ieq "update") { Write-Host "Firewall will be updated with new IPs found in the log" $RuleExists = Get-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" 2> $null if ($null -eq $RuleExists) { Write-Host "Existing Firewall Rule does not exist. Creating new one..." New-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" -Direction Inbound -LocalPort Any -Protocol Any -Action Block -RemoteAddress $BadIPAddresses $FWCountAfter = $BadIPAddresses.Count Write-Host "Firewall Rule added with $FWCountAfter IPs blocked.`n" if ($Clip) { Write-Host "`nCopying all blocked IPs to Windows Clipboard" $BadIPAddresses | clip.exe } if ($EventLog) { New-EventLog -Source "Aktion" -LogName Application 2> $null Write-EventLog -LogName "Application" -Source "Aktion" -EventID 1001 -EntryType Information -Message "$Instances failed logons from the selected log files`n`nFirewall Rule added with $FWCountAfter IPs blocked." } } else { Write-Host "Updating existing Firewall Rule..." $ExistingBlockedIPs = (Get-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" | Get-NetFirewallAddressFilter ).RemoteAddress $UpdatedBlockedIPs = $BadIPAddresses + $ExistingBlockedIPs $UpdatedBlockedIPs = $UpdatedBlockedIPs | Select-Object -Unique | Sort-Object Set-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" -RemoteAddress $UpdatedBlockedIPs $FWCountBefore = $ExistingBlockedIPs.Count $FWCountAfter = $UpdatedBlockedIPs.Count $FWDelta = $FWCountAfter - $FWCountBefore Write-Host "`nOriginal number of IPs Blocked: $FWCountBefore" Write-Host "New Bad Actor IPs found this run: $FWDelta" Write-Host "Total Number of IPs now being blocked: $FWCountAfter" if ($Clip) { Write-Host "`nCopying all blocked IPs to Windows Clipboard" $UpdatedBlockedIPs | clip.exe } if ($EventLog) { New-EventLog -Source "Aktion" -LogName Application 2> $null $MessageDetails = "$Instances failed logons from the selected log files`n`nOriginal number of IPs Blocked: $FWCountBefore`nNew Bad Actor IPs found this run: $FWDelta`nTotal Number of IPs now being blocked: $FWCountAfter" Write-EventLog -LogName "Application" -Source "Aktion" -EventID 1001 -EntryType Information -Message $MessageDetails } Write-Host "`nOperation complete." } } else {Write-Host "Firewall was not updated since -Firewall update parameter was not used`n"} } function Import-PublicBlackListIPs { Write-Host "Import-PublicBlackListIPs v24.5.5" -ForegroundColor Yellow # Check Admin Elevation Status if ((Get-AdminStatus) -ieq $false) { Write-Host "TERMINATING: This script needs to run from elevated PowerShell console." -ForegroundColor Red Return } # https://binarydefense.com/banlist.txt # https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt # https://rules.emergingthreats.net/blockrules/compromised-ips.txt If(!(Test-Path -Path "C:\Temp")) { New-Item -Path "C:\Temp" -ItemType Directory | Out-Null } Write-Host "Downloading Blocklist Files from Internet..." Invoke-WebRequest "https://binarydefense.com/banlist.txt" -outfile "c:\temp\banlist.txt" Invoke-WebRequest "https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt" -outfile "c:\temp\emerging-Block-IPs.txt" Invoke-WebRequest "https://rules.emergingthreats.net/blockrules/compromised-ips.txt" -outfile "c:\temp\compromised-ips.txt" $file1 = Get-Content -Path 'c:\temp\banlist.txt' $file1 = $file1 | Where-Object { $_ -match '\S' -and $_ -notmatch '^#' } $file2 = Get-Content -Path 'c:\temp\compromised-ips.txt' $file2 = $file2 | Where-Object { $_ -match '\S' -and $_ -notmatch '^#' } $file3 = Get-Content -Path 'c:\temp\emerging-block-ips.txt' $file3 = $file3 | Where-Object { $_ -match '\S' -and $_ -notmatch '^#' } $PublicBlockedIPs = $file1 + $file2 + $file3 $PublicBlockedIPs = $PublicBlockedIPs | Select-Object -Unique | Sort-Object -Unique Write-Host "Updating existing Firewall Rule..." $ExistingBlockedIPs = (Get-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" | Get-NetFirewallAddressFilter ).RemoteAddress $UpdatedBlockedIPs = $PublicBlockedIPs + $ExistingBlockedIPs $UpdatedBlockedIPs = $UpdatedBlockedIPs | Select-Object -Unique | Sort-Object -Unique Set-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" -RemoteAddress $UpdatedBlockedIPs $FWCountBefore = $ExistingBlockedIPs.Count $FWCountAfter = $UpdatedBlockedIPs.Count $FWDelta = $FWCountAfter - $FWCountBefore Write-Host "`nOriginal number of IPs Blocked by Firewall: $FWCountBefore" Write-Host "New unique IPs imported from public blacklists: $FWDelta" Write-Host "Total Number of IPs now being blocked by Firewall: $FWCountAfter" } function Export-BlockedIPs { # Check Admin Elevation Status if ((Get-AdminStatus) -ieq $false) { Write-Host "TERMINATING: This script needs to run from elevated PowerShell console." -ForegroundColor Red Return } $ExistingBlockedIPs = (Get-NetFirewallRule -DisplayName "RDWeb Bad Actors - Blocked IP addresss" | Get-NetFirewallAddressFilter ).RemoteAddress $ExistingBlockedIPs | Out-File "BlockedIPs.txt" } |