Here’s a question worth sitting with: when was the last time you ran a script you wrote more than six months ago and actually trusted it?
Not skimmed it. Not crossed your fingers and ran it anyway. Actually trusted it, the way you’d trust a coworker who has never once let you down.
If you’re honest with yourself, that number is probably smaller than your total script count by a wide margin. And I say that as someone who has a folder called scripts_good sitting next to a folder called scripts_final sitting next to a folder called scripts_final_USE_THIS_ONE. I know exactly what I’m talking about here.
The thing most of us don’t admit is that there are two completely different activities happening when we write scripts. They look identical from the outside. Same editor, same language, same terminal window. But one of them is building something that works for you over time, and the other is solving a problem fast enough that you can close the ticket and move on. Both have their place. Confusing one for the other is where the trouble starts.
The One-and-Done Script Isn’t Broken, It’s Just Honest
Let’s give the throwaway script its due credit, because it actually earns it.
At work, I’m in Exchange and Active Directory most of the day. Sometimes I need to pull a list of mailboxes matching a specific condition, fix a bulk attribute issue, or chase down why a dynamic distribution list is resolving wrong. I write a PowerShell script to handle it. It runs. Problem solved. That script is never running again and we both know it.
That’s not technical debt. That’s the right tool used appropriately. You wouldn’t keep a bandage after the cut healed. The mistake is when you take that same approach into something that’s going to need to run at 2 AM next Tuesday without you watching it.
One-time scripts are allowed to be fragile. They’re allowed to have hardcoded values, no error handling, and a comment at the top that says # don't judge me. The implicit understanding is that you’re present when it runs. You can catch the weird edge case. You are, functionally, the error handler.
The moment that script gets scheduled, or handed off, or is expected to run unattended, the rules change. And not everyone makes that adjustment.
What Real Automation Actually Requires
A script that’s genuinely doing automation work has a different job description than a script that’s helping you right now.
It has to handle the situation where the thing it’s looking for doesn’t exist. It has to log what it did, because you won’t be there to remember. It has to fail loudly when something goes wrong, not quietly succeed and leave a mess you’ll find three weeks later. It has to be readable to you six months from now, because future-you is basically a different person who inherited a codebase with no documentation.
That last one gets me every time. I am very good at starting a project with full context loaded in my head and slightly less good at leaving enough breadcrumbs for myself to pick it back up later. HookHouse-Pro has comments in it that say things like # fix this later with no indication of what “this” refers to. That’s on me.
Real automation scripts have a few things in common regardless of language:
- They log to a file, not just the console
- They validate inputs before acting on them
- They fail with a clear message, not a silent exit
- They’re written so that someone else, or future-you, can understand what they were supposed to do without running them first
That last point matters more than most people account for. A script with no context around it is not a script. It’s a binary. You run it and hope.
So Which One Should You Write?
Both. That’s the actual answer, and it’s not a dodge.
Write throwaway scripts aggressively. Don’t gold-plate a one-time fix. That’s wasted effort, and it’s also a sneaky form of procrastination where you optimize something instead of shipping it. I have caught myself doing exactly this, spending forty-five minutes making a script “reusable” for a problem that will never recur in my lifetime.
But before you schedule something, or share it, or walk away from it expecting it to run without you, ask yourself whether it can survive that. Whether it can tell you what happened. Whether it can fail in a way that doesn’t silently corrupt your data or lock out fifty user accounts before anyone notices.
The discipline isn’t in writing better scripts. It’s in knowing which kind you’re writing before you start, and building accordingly.
Most of what’s failed on me over the years didn’t fail because I wrote bad code. It failed because I wrote the right code for the wrong expectation. I built a note and called it infrastructure.
Those are very different things, and the gap between them tends to show up at the worst possible time.