PSLogonFailures Install Guide

From Jonsdocswiki
Jump to: navigation, search


System Requirements

  • Windows Vista or Windows Server 2008 RTM (Windows Server 2008)
    • Includes Windows Small Business Server 2008
  • Windows 7 or Windows Server 2008 R2.
    • Windows Server 2008 R2 includes Windows Small Business Server 2011
  • Windows Server 2012
  • Windows Firewall
    • The Windows firewall must be turned on.
    • This script does not work with third party firewall products.
  • PowerShell v2 (part of Windows Management Framework Core package (KB968930)) (or greater)
  • Microsoft .net framework 3.5 (or greater)
  • Administrator access to the server.

Tested on

  • Windows Server 2008
  • Windows Server 2008 R2 (Windows Small Business Server 2011)
  • Windows Server 2012


Note this script contains absolutely no warranty. Improper use could result in locking yourself out of your system and require local system access to fix. If you are in any doubt, seek assistance from an IT professional (preferably a BCS member)

Installation is reasonably simple and should take less than 30 minutes assuming you meet the prerequisites outlined above.

Install the .net Framework

For Windows Server 2008 R2, this can is installed as a feature:

  1. Open Server Manager (Start > Administrative Tools > Server manager)
  2. From the left hand pane, click Features.
  3. Click Add features.
  4. Expand .NET Framework 3.5.1 Features and tick .NET Framework 3.5.1.
  5. Click Next.
  6. Click Install.
    • Note: a server reboot may be required after .Net framework is installed.

Windows Server 2008

For the original release of Windows Server 2008 you'll need to download and install the .net Framework 3.5 from Microsoft's website.

Customise the script

Very few changes to the script are required although it is important to customise the script to match your environment. To change a value, edit the value after the variable (see the examples below). The default value is beneath the heading.

Security Log name

$LogName = "Security"

This is the Windows log that contains details of logon and failed logon attempts. By default on a Windows system this log is called security so it is recommended to leave this at the default (above):

Set the log name and log source

$WriteLogSource = "PSLogonFailures"
$WriteLog = "Application"

These variables are used to specify what log the script will record its activity to (defaults above). Convention suggests this script should add its log entries to the Application log. You can change the source ($WriteLogSource) to something more meaningful to you if you wish (ensure this matches the Source you create under setup the log source).

$WriteLogSource = "FirewallScript"
$WriteLog = "Application"

Decide when to write to the log

Available from: v1.2

$WriteLogStart = 1
$WriteLogEnd = 1

When set to 1, and event is written to the log at the start and end of the script respectively. You can configure this to suit your needs. For example, to only log upon script completion:

$WriteLogStart = 0
$WriteLogEnd = 1


$minutes = 20

This is the number of minutes of logs to process - i.e. the period in which time an attacker is not permitted to reach the threshold value. This value should be set to a greater value than the repeat frequency of the scheduled task you'll create later.

$minutes = 10

Threshold value

$threshold = 4

The threshold value is the number of failed logons permitted from an IP address within the time period ($minutes) before the IP is blocked, It is recommended you set this to a value less than your account lockout policy for user accounts so if a legitimate user is trying to logon they don't lock out their account immediately.

$threshold = 2

RDP (Remote Desktop) port

$RDPPort = 3389

As mentioned, this script was originally designed to stop attacks against Remote Desktop for which the default port is 3389. If your server listens on a different port then change this value (Note: if your firewall forwards port 90 to 3389 on your server, the port here is still 3389).

$RDPPort = 3390

Choose which services to block

Available from: v1.4.1

Upgrading from pre-1.4
Given the rule name changes, and the addition of new rules as part of service blocking, please manually remove all PSLogonFailures created firewall rules (they should start PSLogonFailures - Block) to ensure old rules are not left behind.
$BlockAll = 0
$BlockWeb = 0
$BlockSMTP = 0
$BlockRWW_RDP = 0

As of 1.4.1 the script will block a number of services (HTTP, HTTPS, SMTP, port 4125 (used for Remote Web Workplace)) which can be used to further limit the attacker's chances against your server. By default, each variable is set to not block (i.e. zero).

$BlockAll = 1

Setting $BlockAll to 1 ($BlockAll = 1) blocks inbound connections on all TCP ports for the agressors. Unless there is a valid reason to permit an attacker to continue their access to any other service this may be your best option.

$BlockWeb = 1

Blocks all inbound connections from the agressor's IP to HTTP (port 80) and HTTPS (port 443) of the server.

$BlockSMTP = 1

Prevents inbound connections from the agressor's IP to SMTP (port 25), used by mail servers.

$BlockRWW_RDP = 1

Stops inbound access from the agressor to port 4125, used for Remote Web Workplace (on SBS servers).

Firewall Profile

$fwprofile = "Any"

The Windows firewall is split into a number of profiles (domain, private, public) and this setting defines which firewall profile the rule is applied to. Applying to any is safest as it doesn't matter what profile is in use on the server - it is recommended this be left at Any

IP Address Whitelist

Whitelist type changed
As of v1.5 the whitelist becomes a text file and the default is - ensure you customise the whitelist!!
$whitelist = 'C:\psl\whitelist.txt'

Set this variable to be the full path to your whitelist containing text file. Then, in your whitelist file, enter 1 IP address per line, ranges are not supported. For example:

Whitelist - Pre-v1.5

Pre v1.5 only
Whitelist instructions here are only relevant if using earlier versions of the script.
$whitelist = @("")

The whitelist is one of the most important lines in the script and IP addresses within the whitelist are never blocked. The list is comprised of IP addresses wrapped in double quotes ("), separated by commas (,). It is essential the @( and closing ) remain present.

Note: Each IP address must be entered individually (ranges are not supported).

$whitelist = @("", "", "")


Available from: v1.6.1

$blacklist = 'C:\PSL\Blacklist.txt'

In a similar vein to the whitelist, PSLogonFailures allows you to specify a blacklist to persistently block IPs you specify there. Specify the full path to the blacklist text file. IPs should be entered one per line:

Note: The whitelist is processed before any firewall rules are created so if you accidentally put yourself in the blacklist, the whitelist takes precedence.

Setup the log source

Once the script is customised you need to create the log source on your server. If you have changed the defaults you will need to update the line below to reflect your $WriteLog and $WriteLogSource values. These commands should be typed all on one line and you'll need to be in an elevated command prompt to run these commands successfully.

POWERSHELL: Creating a log source
PS c:\> New-EventLog -LogName "Application" -Source "PSLogonFailures"

If you changed $WriteLogSource = "FirewallScript" then you'd need to change this to:

POWERSHELL: Creating a log source (non-default)
PS c:\> New-EventLog -LogName "Application" -Source "FirewallScript"

Allow the script to run

By default, Powershell will not allow unsigned scripts to run. The PSLogonFailures script is not signed so you will need to allow these by entering the command below and following the on screen instructions.

POWERSHELL: Adjust the execution level
PS c:\> Set-ExecutionPolicy remotesigned

Create a scheduled task

This script works best when automatically run every 10 minutes although you will need to adjust the frequency to suit your environment. Instructions on how to do this have been adapted from Techhead - the Techhead version has pictures.

  1. Open the Task Scheduler (Start > Administrative Tools > Task Scheduler).
  2. From the right hand pane click Create Task.
  3. On the General tab:
    • In Name type a meaningful name (e.g. PSLogonFailures Script)
    • Enter a helpful desctiption in the Description field.
    • Set the user to run this script as (the user will need to be an administrator of the server) by clicking the Change User or Group button.
    • Select Run whether the user is logged on or not.
    • Tick Run with highest privileges (very important).
  4. On the Trigers tab:
    • Click New.
    • From the begin the task drop down menu choose At startup.
    • Tick Reapeat task every and choose 10 minutes (adjust to suit) and indefinitely from the drop down boxes.
    • Ensure Enabled is ticked.
    • Click OK.
  5. Create another trigger so the task starts (and repeats) without having to restart, on the triggers tab:
    • Click New.
    • From the begin the task drop down menu choose On a schedule.
    • Leave the task set to One time and set it to start today in 5 minutes time (more if you think it will take you more than 5 minutes to setup the tasks).
    • Tick Reapeat task every and choose 10 minutes (adjust to suit) and indefinitely from the drop down boxes.
    • Ensure Enabled is ticked.
    • Click OK.
  6. Move to the Actions tab and click New.
    • Leave Action as Start a program.
    • In Program/script type powershell.exe.
    • In Add arguments type –Noninteractive –Noprofile –Command "&{<fullpath to script>}" (e.g. –Noninteractive –Noprofile –Command "&{c:\scripts\PSLogonFailures.ps1}"
    • Click OK
  7. Click OK to create your task.
  8. Press F5 to refresh the list of tasks - you should see your scheduled task present.

Check the script is working

If you performed the above steps correctly the Application log should contain events from the PSLogonFailures source:

  • One event stating the script is starting.
  • Another event stating that the script has finished and listing the IPs it has blocked.

If these events don't exist, check you have $WriteLogStart and $WriteLogEnd to 1. Then, check the troubleshooting guide.

Personal tools