IT Operations Engineer · 5 years experience · Surrey / London
I look after Windows and macOS estates, identity and compliance. Most of what I build takes manual steps out of IT processes.
New starters needed accounts in Slack, Atlassian, Keeper and Dialpad. None of the provisioning APIs were available on the plans we had, so each connector uses the best method its tier allowed.
Exchange Online administration is a lot of half-remembered PowerShell. I wrapped the tasks I ran most often in a local web UI, so they could be run without rebuilding the cmdlet from memory each time.
A single-machine network recon and testing toolkit for Linux. It puts nmap, tshark, John the Ripper and BlueZ behind one BIOS-styled desktop GUI, with a few things built from scratch where nothing quite fit. A personal project, built in my own time.
I am a Senior IT Operations Engineer, currently supporting over 750 users across a company's global offices. Before that I spent three years at a SaaS company, where I covered a 110-user business on my own for the first year and was promoted to Senior Service Desk Engineer.
Most of my work is endpoint management, identity and compliance — ISO 27001, PCI DSS and Cyber Essentials. The part I enjoy most is automation.
Node · React · Microsoft Graph
A one-click tool to set up new starters across four services, built on plans that had none of the provisioning APIs.
Setting up a new starter meant creating accounts in Slack, Atlassian, Keeper and Dialpad by hand, one service at a time. It was slow, easy to get half-done, and exactly the kind of repetitive work worth removing.
The catch was the plans. The clean way to do this is each service's provisioning API, but those sit behind tiers the company wasn't on — Slack's admin.users:write needs Enterprise Grid, Keeper's SCIM needs Enterprise. So the interesting part wasn't wiring up four APIs. It was working out what to do when most of them were out of reach.
An Express backend with one connector module per service, and a React front end that reads the list of available services from the backend rather than hard-coding them. Each connector uses the best method its plan actually allowed:
The Keeper connector is the honest weak point. Driving a web console with a headless browser works, but it's fragile: it breaks the day Keeper changes their admin UI, and it depends on a login session staying alive. It was the right call given the plan, not the right call in the abstract. The day someone paid for SCIM, I'd throw it away and not miss it.
The design that made me happiest is the connector interface. Adding a service is a new file exporting isConfigured() and invite(), and the front end picks it up on its own. That part I would keep.
PowerShell · Exchange Online
The Exchange Online tasks I ran most often, wrapped in a local web interface so they didn't have to be rebuilt from memory each time.
A lot of Exchange Online administration is half-remembered PowerShell. Checking which domains are configured, testing whether external-sender tagging is working, fixing a mailbox timezone, auditing settings across accounts — each is a cmdlet or two, but the kind you look up every time because you don't run them often enough to memorise.
I wanted the common ones in one place, runnable without opening a shell and reconstructing the syntax.
A set of PowerShell tools behind a local web UI, launched from one script. Each tool is a tab: search, domain and external-domain checks, external-tag testing, timezone fixes, an audit-settings view, and a couple of destructive ones (mailbox and calendar-entry removal) kept clearly separate because they don't undo.
The web front end matters more than it sounds. A form with named fields is harder to get wrong at 4pm than a raw cmdlet, and it means someone who isn't fluent in Exchange PowerShell can still run the safe operations.
The destructive tools need a confirmation step that makes you type the target back, not just click. They work, but "click to delete calendar entries" is one bad afternoon away from a mistake, and a UI that makes the dangerous action as easy as the safe one is a UI with the wrong emphasis.
View on GitHub →Python · GTK / WebKit · Linux
A single-machine network recon and testing toolkit for Linux, wrapping the standard CLI tools behind one BIOS-styled desktop GUI. A personal project, built in my own time.
Built for use only against devices and networks I own or have explicit permission to test. Several features actively change routing, ARP or DNS behaviour, or emulate other hardware, and are meant to be treated with the same care as any pentesting tool.
I kept reaching for the same handful of tools — nmap, tshark, John the Ripper, BlueZ, traceroute — and running each from its own terminal with its own flags. Zippy puts them behind one interface: a black-and-red, BIOS-styled desktop GUI, with each tool as a tab. The UI is plain HTML, CSS and JavaScript rendered through pywebview on GTK and WebKit, so it's a real desktop app rather than a browser tab or an Electron bundle.
Most tabs wrap an existing tool. A few are built from scratch where nothing quite fit: ARP and NDP spoofing to route a target's traffic through the machine, DNS-spoof-based redirection, Bluetooth HID emulation, and rogue-DHCP probing.
The privileged features rely on things that only exist on Linux — AF_PACKET raw sockets, ip_forward, D-Bus and BlueZ. Rather than run the whole app as root, each privileged action prompts individually through polkit's pkexec. The app itself never runs as root. run.sh detects and installs missing dependencies across dnf, apt, pacman and zypper, so it comes up on most desktop distros without hand-holding.
The Bluetooth HID tab is the newest and least-proven, and I've written it up that way rather than hidden it. BlueZ's peripheral-role HID registration over D-Bus is a sparsely documented, version-sensitive corner, so behaviour varies by distro. It's confirmed working against a Steam Deck — I caught a successful pairing and key-press round trip in a btmon capture — and general phone pairing, but not yet against Windows, Android-as-host, TVs or consoles.
Two real bugs turned up through hardware testing rather than code review: a "UUID already registered" conflict, fixed by consolidating to a single profile registration with a combined SDP record; and a "PSM not supported" refusal, fixed by binding raw L2CAP sockets directly instead of relying on BlueZ's Profile1.NewConnection. More hardware will probably surface more.
Some limits are deliberate rather than unfinished: single key presses only, no text-typing or macros, no mouse. That was a scope decision — I wanted a live interactive remote, not anything that looks like payload injection.
The repository is private, and given what several of the tabs do I intend to keep it that way. Happy to walk through the code in an interview.