ROM File Cleanup – Powershell – GoodMerge – NoIntro

ROM File Cleanup

You just downloaded a massive ROM pack for emulation, could be NES, SNES, N64, Genesis, etc… In the pack you would expect the ~600 games that actually came out in stores. Instead you find 15,000 games containing every version and prototype cartridge imaginable from every corner of the world.

Powershell can be the cure for this complete mess, by simply purging out the files matching filters. Code is below. Star (*) is a wildcard character. Just define the source and destination at the beginning.

This script assumes you want United States compatible releases. Note that some games were only released as (EU) [Europe + United States], or (JU) [Japan + United Sates]. This script includes these titles. If you find a pattern or format you do not like, feel free to add your own filter in to the list. If you are from Europe, you would want the (E)  or (EU) releases. (W) is a World-Wide Release.

This script is not perfect — it cannot catch everything because collectors often use custom naming conventions, but this code very easy to work with. After you are done, I recommend scrolling through your list and checking for any duplicate games.

There are two scripts:

  1. The first script creates a a copy of your files to a folder where you can process them all.
  2. The other script actually purges out the unwanted games with the Remove-Item command — a permanent delete command (no Recycle Bin)

ROM File Copy / Move Code

#File Copy or Move Code.
#Delete the comment (#) for Move-Item if you want to use that instead, and then comment out #Copy-Item
#Edit your source path (Original copy of unzipped ROMs) and destination path (Working area for ROMs).
$source = "C:\Installers\GenesisSource"
$destination = "C:\Installers\GenesisDestination"

cd $source
#Use if you want to work on your copy
#The symbol [!] means verified working, usable ROM.
Copy-Item *[!]* $destination

#Uncomment if you want to move -- This is a cut/paste, these files will not be coming back.
#Move-Item *[!]* $destination

 ROM File Cleanup Code

#Dan Kruse - - December 2nd 2016
#To run this command, you can either copy/paste in all of the code, or more easily, save it into a TEXT file in the format .ps1.
#Then open Powershell.exe in Windows and run the filename of the script. For example:

#The hash-symbol(# will deactivate a line of code. Useful for pausing the copy/pasting of the script on the row beginning with "Copy-Item"

#Remove by Country Initials
get-childitem -Recurse -path "$destination" -filter '*(B)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Bra]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(CCE)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(CH)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Chi]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(E)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(F)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(G)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(J)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(JE)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(K)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(R)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(PAL)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(PD)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(SECAM)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(UA)*' | remove-item

#Remove by Country Name
get-childitem -Recurse -path "$destination" -filter '*Canada*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*China*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(Europe)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*France*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Germany*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Italy*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Japan*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Sachen*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Spain*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(Unknown)*' | remove-item

#Remove by Keyword
get-childitem -Recurse -path "$destination" -filter '*AKA*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*(Alpha)*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Beta*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*canal*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*demo*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*hack*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*preview*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Proto*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Rev A*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Rev02*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Rev03*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Rev04*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*Screen Search*' | remove-item

#Remove by Invalid ROM Type
get-childitem -Recurse -path "$destination" -filter '*[a*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[b*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[f*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[fixed]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[h*C]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[hI*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[o*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[p*]*' | remove-item
get-childitem -Recurse -path "$destination" -filter '*[p1]*' | remove-item


Mikrotik Guest Wireless Network

Mikrotik Guest Wireless Network

If you’ve got a Mikrotik router with wireless or a Mikrotik Wireless Access Point and desire to setup WiFi with a Guest Network — you’re in the right place!

This guide will assume the most common setup scenario — Guest Wireless and Private Wireless share the same internet connection, but cannot talk to each other- your guest devices only need internet access and do not need to interact with any other devices.


Note that the Mikrotik QuickSet feature now includes all of these steps in a single interface. The lower left of QuickSet has a section for “Guest Wireless Network”.

This guide will explain the details of how it is operating.



Interface SSIDs

A SSID is the name of a wireless network. For Mikrotik, you can have a single SSID bound to each interface. If you only have one antenna interface, like many routers/WAPs, you will need to create a virtual AP interface and assign it an SSID as well.

Use Winbox to login to your Mikrotik router, by default IP

On the left page: Wireless > Double-Click Interface (wlan1 usually) > Wireless Tab.


Here you can configure your AP Bridge, which means “Access Point, bridge to wired network.” You can also change the SSID.

Security Profile (Password)

To change the password: Wireless > Security Profiles > Double-Click Entry > WPA and WPA2 Pre-Shared Key (PSK). These are usually the same password.


Adding the Guest Interface (Virtual Access Point)

Create a new Security Profile (password) for what will become our guest wireless network.

Wireless > Security Profiles Tab > Click Plus Symbol (+) > Name, WPA and WPA2 Pre-Shared Key.


Wireless > Interfaces > Blue Plus (+) Symbol > Virtual


You can name the interface however you would like, but generally giving them a number is best. wlan1 means Wireless LAN 1. So to follow naming you may use wlan2 or wlan3 for your 2nd and 3rd SSIDs.


Click the Wireless Tab to decide the SSID for this new AP Bridge, and give it a fun name. You can also select the Security Profile (password) to use for this interface.


Guest IP Addresses and DHCP Server

Let’s start by assigning your new Virtual AP Interface a Static IP address. Choose a different subnet. So if you are currently say,, we might use

IP > Addresses > Plus (+) > Address/Subnet > Interface (Virtual AP Interface, like wlan2)


To add a DHCP Server: IP > DHCP Server > DHCP Setup > Select Virtual AP Interface (wlan2)

Follow the prompts, it should auto-populate the fields for you.



As a switch is to ethernet cable, so a bridge is to network interfaces — it connects them together. To have your physical wireless interface (antenna) send and receive traffic through your wired interface (RJ-45 port on ETH2), they need to know to talk to one another, and bridges make this happen. You do not need to also bridge your Virtual AP wireless interface (guest) because wlan1 is it’s master port. This entry is just in case you don’t have any bridge between wlan1 and ethernet. Don’t worry, we will isolate them from your private devices via a firewall rule. You could also isolate the wlan2 (guest) interface traffic to a separate ethernet plug (say, ether5, while ether2-4 is private traffic and ether1-gateway is your WAN).


Allow NAT Translation (Masquerade for Internet Access)

You likely already have NAT translation enabled, but if you don’t, enabled a masquarade rule that allows srcnat traffic to go out through your WAN interface (usually gateway or ETH1). This goes for all interfaces, including your existing local ports, existing wireless interface and new wireless virtual AP interface. You can specific Source Address if you want to, but if you leave the field blank Mikrotik assumes all sources are valid.


Block Guest Interface From Communicating with Private with Firewall Rule

You’ll want to make a firewall rule, forward chain, action will be DROP. This blocks traffic from the source network (, in this case, Guest Wireless), from communicating with the destination network (, in this case, Private Wireless).



I hope that helped you out a bit, enjoy!

MikroTik wAP – Setup Guide – Multiple APs with Roaming

MikroTik wAP Quick Setup Guide

Hello there, this post will provide instructions configuring a MikroTik wireless access points from start to finish with a quick script. The goal is a wireless network where you can walk around the building and have client devices jump from WAP to WAP via access rules (Min-RSSI).

These principles will work on any Mikrotik device with wireless capability since they all run the same Routerboard software.



My company deployed 12 Ubiquiti UAP Pros to a client, we experienced intermittent connectivity with Apple devices (MacBook Air, MBP, and iPhones), Ubiquiti forums were not helpful, firmware upgrades/downgrades didn’t make a difference, and devs shifted the blame to Apple. We decided to try a different vendor, MikroTik, and purchased four RBwAP2nD units (Looks like a rounded, white rectangle).

The Mikrotiks did the job beautifully after proper setup! Not only did they not have issues with Apple devices, but the quality of signal was FAR higher than with Ubiquiti. More capacity, better signal, 1/4 the cost, with granted much harder management than the beautiful UniFi Controller, but in this setting it is acceptable — one location, set it and forget it.

Rather than set up a Wireless Mesh (WDS) or use the CAPsMAN controller, I’m keeping it simple. Set each AP in each corner of the building, use Min-RSSI to kick off clients when their signal is too weak, then they join the strongest signal near them. It’s short-and-sweet roaming, not seamless, but good enough.

The wAP can be powered by PoE or power-plug, between 12v-57v. We are using our already purchased Ubiquiti Toughswitch-8-Pro to power the units, but you could use any standard 24v or 48v PoE switch.

 Initial LoginMikrotik1

By default the WAP runs a DHCP Server, so I made sure to not plug it directly into our existing
network. You can connect directly to the WAP through wireless with a laptop. Once connected, you’ll pull a DHCP IP, usually You can connect to the Mikrotik wAP with Winbox, their management software — very powerful!


Click the three dots next to “Connect” and WinBox will search for any Mikrotik devices. You can connect by IP, or direct MAC address (no matching IP/subnet needed!). Default username/password is admin/<blank>.


Initial Setup

All of these commands are menu presses. So “/system identity” means click the System button on the left, then the identity drop-down, further commands are tabs or fields. These commands can be entered DIRECTLY into the WAP applying immediately by using “New Terminal” on the left. The terminal lets you rapidly set up units after you’ve got your base commands in a text file. With these codes I’m able to crank out a matching WAP in about 4 minutes.

Name the AP

/system identity set name="NAME"

Wireless / Wired Bridge

Allow the wireless and wired connections to talk to each other. A bridge functions like a switch, it lets different interfaces talk to each other (whether that is a physical port, antenna, or VLAN, it connects them together).

/interface bridge add name="bridge1" 
/interface bridge port add interface=ether1-gateway bridge=bridge1
/interface bridge port add interface=wlan1 bridge=bridge1

LAN Dynamic IP

Force the wired connection to pull a dynamic IP address by turning on the DHCP-Client service.

/ip dhcp-client add comment="default configuration" dhcp-options=hostname,clientid disabled=no interface=ether1-gateway

Overwrite the existing ( IP Address applied to the wired NIC. This will be an additional  static IP to the wired NIC, the first being by DHCP Client.

Edit the IP
/ip address set address= interface=ether1-gateway numbers=0

Disable DHCP Server

This is just an access point, no DHCP Server needed.

/ip dhcp-server disable 0


Minimum-RSSI (Kickoff when the signal is too weak)

Called Min-RSSI by Ubiquiti, Mikrotik uses an access rule to allow or deny connections. It is almost like a firewall yes/no rule, if your signal is between this range (-84dB through 120dB, written as -84..120), you are allowed to authenticate and to talk to other devices (forward). If your signal is below this range (-120 through -85dB, written as -120..-85), you will be kicked. In reality, it takes about 1-2 seconds of a device having a signal lower than -84dB before the kick happens.

The way signal measurements work, a negative number is a receive number. A positive number is a transmitted or sent number.

Here are some quick dB examples. I have found the Mikrotiks to continue running well at even -85dB because the hardware has such an extremely low/quiet noise floor: -105dB, which is insanely quiet, means you get MUCH better range for the power. 1000mW is a great marketing feature, but it doesn’t mean squat without a good noise floor to compare to. For comparison, Ubiquiti gear (which is usually quite good for the money) signal becomes unusable around -72dB.

General Client Receiving Signal Examples

  • -55dB, this is a great signal quality for a client like a laptop or cell-phone
  • -75dB, we are nearing the limits of usable signal, expect some packet loss or stutters in video/VOIP.
  • -30dB, power is extremely high, you are probably standing within 3 feet of the antenna, or your transmit power is way too high.
## Each of these commands will restart the networking interfaces, so you'll probably be disconnected.

#Configure Min-RSSI Connect
/interface wireless access-list add signal-range=-84..120
#Configure Min-RSSI Kickoff
/interface wireless access-list add authentication=no forwarding=no signal-range=-120..-85

Edit the Wireless Password:WPA or WPA2

####Edit the Password in two places, once for WPA and WPA2####
/interface wireless security-profiles set [ find default=yes ] authentication-types=wpa-psk,wpa2-psk eap-methods="" mode=dynamic-keys supplicant-identity=MikroTik wpa-pre-shared-key=MyPassword wpa2-pre-shared-key=MyPassword

Edit the SSID, and set your transmit power in dB

Antenna/Station Transmitting Examples

  • +12dB, low power, usable 40 foot radius with 1 piece of drywall between station and client.
  • +16dB, medium power, usable 60 fo0t radius with 2 drywalls between station and client..
  • +21dB, high power, range is unpredictable, could be 400 foot radius with line of sight, or 120 foot radius with interference.

High transmit power for MikroTiks is 19-21dB, be aware that though your transmitter may be loud, clients may not be loud enough to reply back. You would see this as a client having full bars of signal, but extreme packet loss or “unable to connect”. For comparison, a Ubiquiti running on High power (Auto) is +30dB.

Don’t just turn up the dB to get farther range, it’s possible to burn out amplifiers/antennas if you don’t know what you’re doing, and may make your signal-to-noise ratio worse.

/interface wireless set [ find default-name=wlan1 ] band=2ghz-b/g/n channel-width=20/40mhz-Ce disabled=no distance=indoors frequency=auto l2mtu=1600 mode=ap-bridge name=wlan1-local rx-chains=0,1 ssid=WirelessName tx-chains=0,1 tx-power=16 tx-power-mode=all-rates-fixed wireless-protocol=802.11

Configure Time (NTP) and Automatic Nightly Reboot

Mikrotiks do not have a battery inside, and thus the time resets whenever they reboot. Configure a NTP server to have the clock auto-update after boot.

In addition, it never hurts to reboot once per day to work out any glitches.

#Reboot router every day at 12:10AM
/system scheduler add interval=1d name="Reboot Router Daily" on-event="/system reboot" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=jan/01/1970 start-time=00:10:00

#Configure the client to use Google as time servers
/system ntp client set enabled=yes primary-ntp= secondary-ntp=,


Update Packages

I updated each WAP at the end, since it was easier to configure them to a usable state and avoid conflict with DHCP-Servers, so data can be pulled via the ethernet cable once they are hooked into the primary switches.

Winbox > System > Packages > Check for Updates > Download and Install


Hopefully this quick start guide was helpful in getting you going on MikroTik WAPs. I’m really amazed by what these units can do for so little money. Harder to configure than most WAPs for sure, but they are extremely reliable — I never have to reboot them, they just take a beating with capacity and handle it like a champ, and don’t even get me started on the reliability of home routers like Netgear, ASUS, or Linksys. Have fun! 😉

Ubuntu 16.04.1 LTS UniFi Beta Controller with Wildcard SSL

This article covers how to install UniFi Beta from a .deb file for Ubuntu Server (so command line only), and how to install a WildCard SSL into UniFi. This article does not cover installing Ubuntu and applying updates.

If you already have a controller, confirm you have a backup of your controller to restore your sites and data!

Controller > Maintenance > Backup > Download



Obtain Putty, a SSH tool to remote into your server with copy/paste functionality

Installing UniFi Base Packages

Run the following code to install UniFi. Note that unifi-rapid and unifi-beta are no longer used, Ubiquiti changed to the single release and if you want a specific version you can install it yourself with the .deb file (below)

#Make your session administrative
sudo -i

#Open a text editor to allow UniFi to be downloaded from the repository
nano /etc/apt/sources.list

#Go to the bottom of the list with the arrow keys, and paste in (through putty, it's Right-Click)
deb unifi5 ubiquiti
deb debian ubiquiti
#Save (Ctrl + X, Y for Yes)

#Add the Ubiquiti GPG Signed Keys to allow you to install their software
apt-key adv --keyserver --recv C0A52C50
apt-key adv --keyserver --recv 7F0CEB10

#Refresh the repositories (download sources)
apt-get update

#Install from the repositories
apt-get install unifi


Upgrading to UniFi Beta with .DEB Image

Sign up for the UniFi Beta community forums. Check the blog to get the newest update packages.

Find the release you want, most likely the newest, and copy the URL of the .deb file.


Putty into your server, and run the following code to install UniFi, then upgrade to the Beta.

#Make your session administrative
sudo -i
#Download your .deb file to the /tmp directory
cd /tmp

#Wait for download to complete, then unpackage and install
dpkg -i unifi_sysvinit_all.deb

#Clean up the mess, delete the old .deb file
rm unifi_sysvinit_all.deb


Applying the SSL Certificate

The scope of this guide does not cover how to create a CSR and obtain your wildcard certificate. Once you have exported your certificate keychain (with private key) as a PKCS #12, these instruction will APPLY the key to your UniFi controller.

By default, UniFi installs inself to /var/lib/unifi

In here is the file “keystore”, that contains the self-signed “UniFi” SSL certificate.

  1. Download Keystore Explorer
  2. Create a new keystore – JKS (OpenSSL)
  3. Tools > Import Key Pair – PKCS #12 > Browse to PFX Wildcard Cert
  4. Decrypt with private key password
  5. Encrypt NEW keystore with the password “aircontrolenterprise”
  6. File > Save As > “keystore”
  7. FTP file to your UniFi box, I recommend Filezilla to connect via sftp://192.168.1.X on port 22.
  8. Transfer the file to your home directory /home/username, since /var/lib/unifi is protected
  9. Connect via Putty > sudo -i > [password] > cd /var/lib/unifi
  10. Stop the service: service unifi stop
  11. Create a backup file: mv keystore keystore.orig
  12. Move your newly encrypted keystore: cd /home/username > cp keystore /var/lib/unifi/keystore
  13. Reboot the Linux OS, when the UniFi controller starts up it will auto import the file keystore and apply it to web services, giving you that nice shiny HTTP green lock 🙂


Dell Open Manage Event ID Monitoring

Monitoring Event IDs with Dell Open Manage

All right, it’s time to set up some kickass event ID monitoring. You’ve installed Dell Open Manage / Server Administrator on all of your physical hosts, and want to make sure you are aware if anything breaks or is about to explode! You’ve been searching for hours trying to find the Event IDs that actually matter — you’re in the right place!

The alerting system you use is up to you, Kaseya, Labtech, Nagios, Pandora FMS, Zabbix, whatever — what matters is getting the correct Event IDs and a matching description filter. Just alerting by Event ID may give you a flood of alerts, there are only so many low ID numbers to go around. The description filter matches only events from OpenManage.

These logs are generated across BOTH Application and System Event Logs, so be sure you are capturing both categories of Event IDs.

I’ve done the hard work of looking through all 500+ of Dell’s individually paged Event ID descriptions — visible here.

Below is a massive list of the ones that matter (or at least, the ones I think matter — any warnings, errors, or critical alerts related to hardware health — anything storage (RAID disks, rebuilds, hot spares, SMART, controller battery, etc), memory (bit errors, ECC failures, failed sticks, etc), CPU (failed processors, temperature, etc), power supplies (redundancy, device failure, cord unplugged, etc). You may want more logs to look at, but I tried to pick anything that could lead to degraded performance or failure.

Open Manage 2

Take my list to get you started. All event descriptions should have wildcards (*), so the description does not require an exact match, otherwise one letter off and you don’t get an alert. Enjoy the code — let me know if it helped you out! 🙂

Dell Open Manage Event ID Cheat

Event ID		Description Filter
1004			*Thermal shutdown*	
1053			*Temperature sensor*	
1054			*Temperature sensor*	
1104			*Fan sensor*	
1153			*Voltage sensor*	
1154			*Voltage sensor*	
1203			*Current sensor*	
1204			*Current sensor*	
1305			*Redundancy*	
1306			*Redundancy*	
1353			*Power supply*	
1354			*Power supply*	
1403			*Memory*	
1404			*Memory*	
1405			*Memory*	
1501			*AC power*	
1503			*AC power*	
1504			*AC power*	
1505			*AC power*	
1552			*Log size*	
1554			*Log size*	
1555			*Log size*	
1604			*Processor*	
1703			*Battery*	
1704			*Battery*	
1705			*Battery*	
2048			*Device failed*	
2049			*disk removed*	
2051			*disk degraded*	
2056			*Virtual disk failed*	
2057			*degraded*	
2076			*Consistency failed*	
2081			*reconfiguration failed*	
2082			*rebuild failed*	
2083			*rebuild failed*	
2094			*Predictive*	
2100			*Temperature*	
2102			*Temperature exceeded*	
2106			*SMART*	
2107			*SMART*	
2108			*SMART*	
2109			*SMART*	
2110			*SMART*	
2112			*Enclosure was shut down*	
2122			*Redundancy degraded*	
2123			*Redundancy lost*	
2126			*sector reassign*	
2129			*BGI failed*	
2145			*Controller battery*	
2146			*Bad block*	
2146			*DR0*	
2147			*DR0*	
2147			*Bad block*	
2148			*Bad block*	
2149			*Bad block*	
2150			*Bad block*	
2169			*controller battery*	
2187			*ECC error*	
2201			*hot spare failed*	
2203			*hot spare failed*	
2272			*uncorrectable media*	
2273			*punctured*	
2289			*ECC error*	
2290			*ECC error*	
2310			*permanently degraded*	
2312			*power supply*	
2313			*power supply*	
2318			*battery*	
2319			*ECC error*	
2320			*ECC error*	
2321			*ECC error*	
2324			*AC power supply cable*	
2340			*uncorrectable errors*	
2342			*inconsistent parity*	
2346			*Error on PD*	
2347			*rebuild failed*	
2348			*rebuild failed*	
2349			*bad disk block*	
2350			*unrecoverable disk media*	
2367			*Rebuild is not possible*	
2367			*Rebuild is not possible*	
2384			*hot spare*	
2385			*hot spare*	
2387			*bad block medium*	
2396			*uncorrectable multiple medium*	
2397			*uncorrectable errors*	
2402			*Disk Power status*	
2405			*Command timeout*	
2416			*medium error*	
2417			*medium error*	
2434			*wear-out limit*	
2436			*read-only mode*	
2441			*critical temperature*	
2442			*degraded*	
2443			*Data loss*	
2900			*cache device*	
2901			*inaccessible*	
2911			*cached LUN*	
2930			*caching*	
1				*device*	
20				*Device*IO failed*	
4098			*returning error*
7				*bad block*
11				*controller error*	
52				*predicted that it will fail*


Easy TCP Port Listener for Network Monitoring

Easy TCP Port Listener for Network Uptime Monitoring

Products like Nagios, Zabbix, or PHP Server Monitor can monitor the uptime of services by performing a TCP port query. In short, “is port TCP 25” open? — its on/offline!

Well what if the server I want to monitor doesn’t have any services to even open up to the public internet for monitoring. Using TCP 135 (Microsoft RPC), TCP 445 (NetBIOS), TCP 3389 (Remote Desktop) built into every Server OS to monitor uptime can be very dangerous. Well I want a program that can listen on a port without massively exposing my servers.

There are two ways to go about this from the scope of this article:

  1. Install an application that hosts a service listener, like a HTTP (TCP 80) server or FTP (TCP 21) server. But you probably don’t want a HTTP or FTP server on say, a Domain Controller or backup machine.
  2. Run a small portable executable that listens on a single port as a scheduled task.

Enter: Port Listener

Made by RJL Software (, it’s a single EXE that can be programmed to listen to any port. It is a simple program, just responding with a TCP-ACK and that’s it!

The Port Listener Code

::It doesn't get simpler than this.
::Change the number "9999" to whatever TCP port you want to listen on.

listener.exe 9999

Port Listener CLI

##Client Query
##Check if the port is being listened on. If there is no output, the port is not being listened on. If you get a response of code, it's open and LISTENING.

netstat -ano | find "9999"


Task Scheduler

Start > Run > taskschd.msc

Task Scheduler Library > Right-Click > Create Basic Task >

Name:#### Uptime TCP Listener

Right-Click > Properties > Run whether user is logged on or not > enter password.

Also edit Conditions (turn off “only run when idle”) and Settings (Stop if runs longer than 3 days) so it always runs , if task fails, restart every 10 minutes, etc.

Command Line Version:

::Create a Windows Firewall Rule
netsh advfirewall firewall add rule name="9999 Uptime TCP Listener" dir=in action=allow protocol=TCP localport=9999

::Create a Scheduled Task that runs on computer boot (ONSTART)
::Note the use of double quotes (") for the full command, and single quotes (') to isolate the executable so arguments/parameters can be passed through.
schtasks /create /TN "9999 Uptime TCP Listener" /SC ONSTART /RU "NT AUTHORITY\NETWORKSERVICE" /TR "'C:\Scripts\listener.exe' 9999"

::Run scheduled task
schtasks /Run /TN "9999 Uptime TCP Listener"

Port Listener Image

Reboot, see if it’s listening, you should have a port listening indefinitely. Add a firewall rule, add a monitor to Nagios/Your System, you’re done – woohoo!

Run on any Windows Server you want monitored, easy peasy! Have fun!

PHP Server Monitor – Add Ping Functionality

Adding Ping (ICMP) to PHP Server MonitorPHP Monitor ICMP

I love PHP Server Monitor, it is an amazing tool for my business to have a simple, reliable, practical way to ensure which services or devices are online. The only complaint I have with it is that it does not support ping monitors, only services (query Port 3389 for example).

Major thanks to Michele Mariotti and insuman on the PHP Server Monitor forums (Post Link) for writing up some code that allows ICMP functionality, as long as the service is Port 1.

Log in to your server via Putty, make a backup of the StatusUpdater function definitions, and replace the old code that will allow you to use ICMP.


# For me, PHP Server Monitor it installed under /var/www/html, your path may be different.
cd /var/www/html/src/psm/Util/Server/Updater

cp StatusUpdater.class.php StatusUpdater.class.php.bak

sudo nano StatusUpdater.class.php


#Find the function
Ctrl + W (search)

function updateService


 Old Code in StatusUpdater.class.php

protected function updateService($max_runs, $run = 1) {
    $errno = 0;
    // save response time
    $starttime = microtime(true);

    $fp = fsockopen ($this->server['ip'], $this->server['port'], $errno, $this->error, 10);

    $status = ($fp === false) ? false : true;
    $this->rtime = (microtime(true) - $starttime);

    if(is_resource($fp)) {

    // check if server is available and rerun if asked.
    if(!$status && $run < $max_runs) {
      return $this->updateService($max_runs, $run + 1);

    return $status;


Change to New Code in StatusUpdater.class.php

This is hardcoding TCP Port 1 in PHP Monitor, to use ICMP/Ping. The default timeout is 5 seconds, adjust the number 5  in the timeout variable ($timeout) to whatever time in seconds you want.

You can use Ctrl+K in nano to delete an entire line at once, rather than holding the Backspace or Delete keys.

###NEW CODE###
protected function updateService($max_runs, $run = 1) {

        if (($this->server['port']) == 1) {
            /* timeout min: 5 sec */
            $timeout = ($this->server['timeout'] < 5 ? 5 : $this->server['timeout']);
            /* save response time */
            $starttime = microtime(true);
            /* ICMP ping packet with a pre-calculated checksum */
            $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";

            $socket = socket_create(AF_INET, SOCK_RAW, 1);
            socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
            socket_connect($socket, $this->server['ip'], null);
            $ts = microtime(true);
            socket_send($socket, $package, strLen($package), 0);

            if (socket_read($socket, 255)) {
                $status = true;
            } else {
                /* store error reason */
                $this->error = socket_last_error() .' '. socket_strerror(socket_last_error());
                $status = false; 
            $this->rtime = (microtime(true) - $starttime);
        } else
        //rest of code
            $errno = 0;
            // save response time
            $starttime = microtime(true);

            $fp = fsockopen ($this->server['ip'], $this->server['port'], $errno, $this->error, 10);

            $status = ($fp === false) ? false : true;
            $this->rtime = (microtime(true) - $starttime);

            if(is_resource($fp)) {

Ping Monitor Example

PHP Monitor ICMP Server Example

OwnCloud Server 9.0 – Ubuntu 12.04 Installation

OwnCloud Server 9.0 on Ubuntu 12.04 with PHP 5.6

A quick setup guide to setting up a private OwnCloud Server on Ubuntu Server.

From building a fresh machine, to setting static IP, installing dependencies, and taking everything online.


Ubuntu 12.04 and PHP 5.6

Current Ubuntu is 14.04, but our AppAssure software threw a fit trying to back up a 14.04 that is apt-get updated to the newest. The lovely error: “Buffer I/O error on device sdb0, logical block #”

Some patch must have broken whatever the backup is using. So I had to install on Ubuntu 12.04, except it by default only installs PHP 5.3…. OwnCloud needs 5.4+


OS Setup

Install the OS, check the OpenSSH feature, use Putty to connect over SSH so you can copy/paste.

#Configure a Static IP

#Use nano to edit > Ctrl+X to close
nano /etc/network/interfaces

#Change iface eth0 inet dhcp to:
iface eth0 inet static


Upgrade 12.04 with the newest patches, security fixes, etc. Then add a repository that normally is not in 12.04, to allow the install of php5.6

#Update the OS
apt-get update
apt-get upgrade

#Allow PHP 5.6 to be installed on an older OS
apt-get install python-software-properties
add-apt-repository ppa:ondrej/php5-5.6
apt-get update
apt-get install apache2
apt-get install php5 php5-mysql
apt-get install php5-gd php5-json php5-curl php5-intl php5-mcrypt php5-imagick
apt-get install mysql-server

#Lock down your SQL, remove the anonymous and remote access.

#Go configure MySQL for OwnCloud
mysql -u root -p
#Enter the DB password prompted when installing.
#Make a table and make priveleges.
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON ownclouddb.* TO 'user'@'localhost';

Install OwnCloud

#Download the installer, unzip/untar it
cd /var


tar -xvf owncloud-9.0.0.tar.bz2 -C /var/www/html/

 Configure Apache2

#Point Apache to your website directory
cd /etc/apache2/sites-available
#Make a backup
cp 000-default.conf 000-default.conf.bak
nano 000-default.conf
#Change ServerName to your FQDN (
#Change DocumentRoot to your path (/var/www/html/owncloud)
service apache2 restart

#Edit OwnCloud to accept your website URL (FQDN)
cd /var/www/html/owncloud/config
nano config.php
#Change your array to look like:
  array (
    0 => '',
    1 => '',
#Change the CLI URL
'overwrite.cli.url' => '',

 Configure Data Directory

mkdir /owncloud
mkdir /owncloud/data
chown -R www-data:www-data /owncloud/data/

Go login to your website,, pop the the applicable information, and change the data path to something outside of the www subdirectory (I use /owncloud/data/)

You *may* have a permission error preventing you from changing the maximum file upload size, File Handling > “Missing permissions to edit from here.”
Just edit the hidden .htaccess file permissions

chmod 776 /var/www/html/owncloud/.htaccess
chmod 776 /owncloud/data.htaccess
#Edit Apache2.conf
nano /etc/apache2/apache2.conf
#Change "AllowOverride None" to "AllowOverRide All"
#Import for the /var/www directory.

I recommend updating your OwnCloud installation, located in the Username > Admin > Updater section. There are some bugs such as Internet Explorer 11/Edge getting the error “Could not create folder “<FOLDERNAME>”” that can be fixed with an update.

Good luck, enjoy OwnCloud, beats the heck out of Dropbox 🙂

HyperV Migration – 0x80090303 – Failed to Authenticate

HyperV Live Migration SPNs – 442 Failed to Authenticate (0x80090303)

Good golly, I just want to move, export, or replicate a VM from one HyperV Server to another. Why is it so frustrating? Commonly received is the rror 0x80090303, meaning that a HyperV host is not allowed to make a live migration connection to another HyperV host — It must become delegated.


The reasons for why this has to be so much work (at least, per worthless Microsoft Technet articles), are beyond the scope of this article. The fix can be quick and easy. From my personal experience, I’ve only gotten CredSSP to work once after a lot of pain and agony. Kerberos through constrained delegation can work, but only if the SPNs are set correctly. Make sure both servers are joined to the same domain, and the VM to be migrated has it’s Processor expanded Compatibility Settings configured for “Migrate to a physical computer with a different process version” checked.


Delegation can be done through Active Directory Users and Computers, but then you have to get the servers to pull their new SPN settings through either a reboot or “gpupdate /force”, which even then only occasionally works.


The quick and easy fix

Take the code below, find & replace the SERVERA, SERVERB, and domain.local fields, and punch it into each server. ServerA commands entered into an administrative command prompt on Server A, and ServerB commands for Server B. By reloading the vmms service you force pull the new settings.

If you cannot find the Active Directory Attribute Editor button for “Trust this computer”, don’t worry about it, the SPNs are really what matter.

Punch in the commands, close and re-open HyperV manager on both, and give your move/export/replication another whirl.

=-=-=-=-=-=-= Hyper-V Live Migrations =-=-=-=-=-=-=
Active Directory > Right-Click Machine > Properties > Delegation > Trust this computer for delegation to any service (Kerberos Only)

setspn -S "Hyper-V Replica Service/SERVERA" SERVERA
setspn -S "Hyper-V Replica Service/SERVERA.domain.local" SERVERA
setspn -S "Microsoft Virtual Console Service/SERVERA" SERVERA
setspn -S "Microsoft Virtual Console Service/SERVERA.domain.local" SERVERA
setspn -S "Microsoft Virtual System Migration Service/SERVERA" SERVERA
setspn -S "Microsoft Virtual System Migration Service/SERVERA.domain.local" SERVERA
net stop vmms && net start vmms
setspn -S "Hyper-V Replica Service/SERVERB" SERVERB
setspn -S "Hyper-V Replica Service/SERVERB.domain.local" SERVERB
Setspn -S "Microsoft Virtual Console Service/SERVERB" SERVERB
setspn -S "Microsoft Virtual Console Service/SERVERB.domain.local" SERVERB
setspn -S "Microsoft Virtual System Migration Service/SERVERB" SERVERB
setspn -S "Microsoft Virtual System Migration Service/SERVERB.domain.local" SERVERB

net stop vmms && net start vmms



SystemRescueCD Dual Boot with Windows

SystemRescueCD Dual Boot

SystemRescueCD is an incredibly usefulful tool for data recovery.

I run a Windows laptop and continually use Easy2Boot for my ISO booting USB stick. It works well with most ISOs, including SystemRescueCD. However my laptop only has two USB plugs.

USB Port Limits

USB 1 – Mounted external HDD

USB 2 – USB Boot Stick

USB … – Target USBHDD to copy data to. No third plug.


Old, Ineffective Solutions

Well drat! This means I need to boot SystemRescueCD off hard-disk, rather than a USB port. After much scrounging on the SystemRescueCD forums, I found some very old, outdated, complicated articles to get dual-boot working.

Old Link 1 –

Old Link 2 –

Old Link 3 –

They involve making a directory, extracting files from the ISO, and editing the BCD bootloader to ham out a rickity boot process. In short —  a nightmare!


IT Dual-Boot Bag of Tricks

I got pretty lucky in figuring out a MUCH easier solution.

Configure EasyBCD to boot the ISO, and extract “sysrcd.dat”, the actual chunk of the ISO that matters, to C:\.


Step 1 – Install EasyBCD, just snag the free version if it is for personal use.

Step 2 – Download the SystemRescueCD ISO. If the download is going to take a long time (1 hour), try another mirror (1-3 minutes).

Step 3 – Copy your ISO to root C:\

Step 4 – Add a boot entry in EasyBCD for portable media, and point it to the ISO, C:\systemrescuecd-x86.iso

**Note** If you were to boot at this point, you would successfully boot to the SystemRescueCD menus, but wouldn’t be able to fully load the Live OS. It would continually search \dev\sda, \dev\sdb, \dev\sdc, etc for the sysrcd.dat, which it is looking for in a mounted CD drive.

Step 5 – Extra the file “sysrcd.dat” from the root of the ISO into root C:\


Upon rebooting you should have another option and be good to go! Woohoo!