The rdp-run module of our original Windows remote desktop security system consists of two files: the core PowerShell script rdp-run.ps1 (which identifies and blocks unauthorized connection attempts) and a helper file rdp-run.bat (which is called from Windows Task Scheduler every 10 minutes and runs the main rdp-run.ps1 file).
The rdp-run.bat file looks like this on our system:
powershell.exe -File "C:\Scripts\rdp-run.ps1"
Be sure to replace "C:\Scripts" with the actual path to your installation directory. The primary script, rdp-run.ps1, contains the following logic:
. "$PSScriptRoot\common.ps1"
# 2. RETRIEVING VIOLATIONS (Iterating through ban rules)
$RawOffenders = @()
foreach ($Rule in $BanRules) {
$StartTime = (Get-Date).AddHours(-$Rule.Hours)
$Events = Get-WinEvent -FilterHashtable @{LogName=$LogName; ID=$Rule.ID; StartTime=$StartTime} -ErrorAction SilentlyContinue
if ($Events) {
$List = $Events | ForEach-Object {
if ($_.Message -match "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") {
$FoundIP = $Matches[1]
# CHECKING AGAINST WHITELIST
$IsWhite = $false
foreach ($WhiteIP in $WhiteList) {
if ($FoundIP -like $WhiteIP) {
$IsWhite = $true
break
}
}
if (-not $IsWhite) {
[PSCustomObject]@{ IP = $FoundIP; Type = $Rule.Type }
}
}
} | Group-Object IP | Where-Object { $_.Count -ge $Rule.Limit }
if ($List) { $RawOffenders += $List }
}
}
# Merge and collapse duplicates
$Offenders = $RawOffenders | Group-Object Name | ForEach-Object { $_.Group[0] }
# 3. BAN NEW OFFENDERS
if ($Offenders) {
$CurDate = Get-Date -Format "yyyy-MM-dd"
foreach ($Offender in $Offenders) {
$IP = $Offender.Name
$Type = $Offender.Group[0].Type
$FirewallPrefix = $FirewallPrefixes['short']
$TechnicalName = $FirewallPrefix + $IP.Replace('.', '_')
if (-not (Get-NetFirewallRule -Name $TechnicalName -ErrorAction SilentlyContinue)) {
$Description = "Type: $Type. Attempts: $($Offender.Count). Created: $(Get-Date)"
New-NetFirewallRule -Name $TechnicalName -DisplayName "$FirewallPrefix$CurDate`_$IP" -Direction Inbound -Action Block -RemoteAddress $IP -Description $Description | Out-Null
# --- NEW BLOCK FOR DB ---
# Calculate subnet: extract everything up to the last octet and append .0
$Subnet = $IP.Substring(0, $IP.LastIndexOf('.')) + ".0"
# The SQL query saves both the IP and its subnet
$LogQuery = "INSERT INTO ban_log (ban_addr, ban_subnet) VALUES (INET_ATON('$IP'), INET_ATON('$Subnet'));"
# Execute the database query
& $mysql_path --user=$mysql_user --password=$mysql_password --database=$mysql_dbName --execute="$LogQuery" 2>$null
# -------------------------
}
}
}
As shown in the snippet above, this script relies on the general system settings from the file common.ps1, and also documents its activity in the ban_log table (this is necessary for the operation of other modules whose task is secondary banning - repeat offenders, address blocks, etc.).
The content of this page is also available in Russian.
| © Extra Systems, 2026 |
|