Archive for June, 2018

So, 8 months since the original post; let’s see what’s changed…

Laptop Upgrades

Our newest laptops are all HP Probook 640 G1; The fourth generation and last to supersede the Elitebook 8440P whilst still fitting the HP docking stations we are using. Sooner or later we will have to bite the bullet and get some newer generation and replace some docking stations.

Printer Upgrade

The Xerox Phaser 6121MFP finally reached the end of days and got upgraded to a Xerox WorkCentre 6515N. Offering much the same features but much newer with more RAM, a faster processor and a few nice bonuses; Active Directory (LDAP) integration and duplex scanning/printing.

Version Control

Our development team have now moved from SVN to GIT. We are using GitLab Community Edition (hosted on-premise). I hope to share some of our practices and customisations soon. We feel GIT provides a more natural integration with Visual Studio and handles our collaboration better.

Support / Helpdesk / Ticket System

Over the Christmas period we wrote our own in-house helpdesk system which better fits our business. This continues to evolve each month and we hope to market it sometime in the future.

There should be a reasonable cost saving moving away from Solarwindows WebHelpDesk but we will be investing a large amount in developing the product and the biggest gains will be realised by the productivity improvements and enforced process/workflows.

Project Management

Once our in-house helpdesk system was live we quickly started work adding project managements features and moved away from Trello and Freedcamp. This will now prevent a lot of duplication previously keeping the disparate systems in sync.

Password Storage

We have now built a simple web based password manager with full and access control which we hope to market in the near future.

Internet Service Provider

After about 18 months of trying, Virgin Media Business has now been installed. The service is significantly poorer than I expected. Whilst we do often manage to achieve 100mb/s+ down and consistently 15mb/s up, the latency is poor (around 30ms) and the way they deliver static IP addresses is ridiculous (and forces you to use their router for the weird gre tunnel, you will need a minimum of 5 static IP addresses, the single IP will be assigned to the router itself and cannot be assigned to your own hardware).

We are now in a position where we want to monitor remote nodes (outside of our domain/LAN). Initially we were able to setup port forwarding on the remote network to allow traffic IN from our server to the agent on port 4700 (remembering to configure the windows firewall too). Then we hit a limitation with NetXMS server not allowing multiple nodes configured with the same ip/hostname (hopefully this will be resolved in a future release).

So we tried to flip the configuration so the remote agent connects in to our server. This proved a little challenging so i’ve documented how we got it working and some of the troubleshooting tips.

Enabling Logging

On the server server modify netxmsd.conf (on our server this was located at C:\NetXmsServer\etc). On the agent modify nxagentd.conf (on our agent this was found in C:\NetXMS\etc). Add;

LogFile = C:\path\to\log\log.txt
DebugLevel = 9

Then restart the NetXMS Core service (on the server) or NetXMS Agent service (on the agent).

**Make sure you change it back to 1 or remove it completely when you are done as the log file will grow very large, very quickly**

Creating the CA / Server Certificate

We wanted to do this with the bare minimum (most of the guides online were pages long). I was surprised there wasn’t an online tool to generate the certificate (perhaps I will build one sometime).

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 10240 -out ca.pem

When prompted for Country, State, Organization etc we just hit enter to accept the default value. We then need to combine the key and certificate (we just used Notepad++)


Make sure you have a blank line at the end of the file (and the certificate comes before the private key). You can download the pre-built certificate here

Configuring the Certificate

  • Drop the ca.pem file anywhere on the NetXMS server
  • Modify netxmsd.conf and add the following lines;
ServerCACertificate = C:\NetXmsServer\etc\cert\ca.pem
ServerCertificate = C:\NetXmsServer\etc\cert\ca.pem
ServerCertificatePassword = netxms

Notice both the CACertificate and Certifcate path point to the same file. I don’t think the password is needed at all.

  • Restart the NetXMS Core service

Creating a Tunnel / Adding a WAN Node

  • Ensure your router is configured to forward traffic received on port 4703 to your NetXMS server
  • Ensure your NetXMS server firewall is configured to allow traffic in on port 4703
  • Modify your nxagentd.conf and add the following linse;
ServerConnection = server_wan_fqdn_or_ip
  • Restart NetXMS Agent service
  • In the NetXMS server, look under Configuration, Agent Tunnel Manager
  • You should see a red entry (if you don’t, something above went wrong)
  • Right click and select Create node and bind
  • Name your node and enter for the ip/hostname and save (if the tunnel vanishes at this point, something above went wrong)

Good luck!

We have built a reporting tool for the Clover ePos which creates a text report for printing using the built-in receipt printer. The app has been through numerous iterations and the code which specifically handles alignment has always bugged me. The task seems trivial to the human mind, but when trying to code seems to throw a lot of curve balls! Here are some examples of the anticipated behavior;


So we revisited it, and I hope have now built a simpler “one size fits all” (not exactly, but considerably less conditional than before). The code accepts a string with pipe separators to determine alignment (refer to the diagram above for a bit more info) and spits out a string padded accordingly;

public static string Align(string key, int width)
            string newKey = "";
            string[] keyElements = key.Split('|');

            if (keyElements.Length == 1)
                newKey += key;
            else if (keyElements.Length == 2)
                //left align the first chunk
                newKey += keyElements[0];
                //insert blank spaces so the entire line length will be a multiple of width
                newKey += new string('.', width - ((key.Length - 1) % width));
                //insert the last chunk
                newKey += keyElements[1];
            else if (keyElements.Length == 3)
                if (keyElements[0] != "")
                    //left align the first chunk 
                    newKey += keyElements[0];
                    //and pad the rest of the line
                    newKey += new string('.', width - (keyElements[0].Length % width));
                //pad the left, center the second chunk and pad the right
                double sidePadding = width - (keyElements[1].Length % width);
                int leftPadding = (int)Math.Floor(sidePadding / 2);
                int rightPadding = (int)Math.Ceiling(sidePadding / 2);
                newKey += new string('.', leftPadding) + keyElements[1] + new string('.', rightPadding);

                if (keyElements[2] != "")
                    //pad the line
                    newKey += new string('.', width - (keyElements[2].Length % width));
                    //and right align the last chunk
                    newKey += keyElements[2];

            return newKey;

The receipt printer automatically wraps the string but we use a small method to split the string into chunks and add carriage returns/new lines for ease of use. Initially, this too was cumbersome (with loops and ifs etc), but we found a more elegant solution (avoiding re-inventing the wheel and reducing the number of lines of code- though I appreciate a loop is still occurring under the hood);

        public static string Wrap(string key, int width)
            return Regex.Replace(key, ".{" + width + "}", "$0" + Environment.NewLine);


Here’s some code we used to test the method(s);

        static void Main(string[] args)
            int width = 33;

            List keys = new List();
            keys.Add("This first part is really long|quick");
            keys.Add("The|second part is ridiculously long");
            keys.Add("The centre segment will always sit on it's own line|quick|brown");

            foreach (string key in keys)
                Console.WriteLine(new string('=', width));
                Console.WriteLine("Input: " + key);
                Console.WriteLine(new string('-', width));
                string aligned = Align(key, width);
                string wrapped = Wrap(aligned, width);


Can you think of any further way we can simplify/improve the code?

%d bloggers like this: