It was a Tuesday. I had maybe forty-five minutes to kill before a meeting, so I sat down to knock out a quick PowerShell script to automate some distribution list cleanup work in Exchange. Nothing complicated. Pull a list, filter some conditions, spit out a report, maybe make a few changes.
Three hours later, I had a 200-line script that worked perfectly.
I know it worked because I ran it. It did exactly what I needed it to do. The output was clean, the logic held, and I felt genuinely good about it. Saved myself probably two hours of manual work.
Then six months went by.
A colleague needed to do something similar, and I figured I’d just hand her the script. Minor adjustments, she’d be fine.
She called me within ten minutes. Not because the script was broken. Because she had no idea what it was doing or why. There were no comments. Variable names like $tempArr2 and $filteredObj_final_v3. A function I’d named Process-Stuff. Hardcoded values she’d have to hunt through four hundred characters of dense logic to find. A section I’d wrapped in a try/catch that silently swallowed errors and just moved on.
It ran fine. It was completely unmaintainable by anyone who wasn’t me at 3pm on that specific Tuesday.
The Thing About Scripts You Write for Yourself
When you’re writing a script for your own use, your brain is the documentation. You know what $tempArr2 holds because you just made it. You know why that one section loops three times instead of two. You know the if statement in the middle is covering for a specific edge case you ran into in testing.
That context lives entirely in your head, and when you write the script, you don’t bother putting it anywhere else because why would you? You already know it.
The script becomes an extension of your own thinking at that moment in time. Which is fine. Until you aren’t that version of yourself anymore.
I’ve gone back to scripts I wrote eighteen months ago and spent twenty minutes reverse-engineering my own logic. That’s not a hypothetical. That’s happened more times than I want to count. My productivity system mostly exists to stop me from reinventing things I already built, and even with that safety net, I’ve still found myself staring at a function and thinking, “what was I doing here?”
If I can lose context on my own script in a year, imagine what someone else experiences on day one.
Maintainable Scripts Require a Different Mindset at the Start
Here’s the thing that took me a while to actually internalize: writing for maintainability isn’t something you bolt on at the end. It’s not “add comments before you hand it off.” By the time you’re done, you’ve already made all the structural decisions. Variable names are set. Logic is baked in. The architecture, such as it is for a script, already exists.
If you’re going to write something someone else has to touch, you need to be thinking about that from line one.
That means different variable names. Not $x or $item or $data2, but $inactiveUserList or $dlMembersToRemove. Takes two extra seconds to type. Saves ten minutes of confusion every time someone reads it.
It means comments that explain why, not what. If I wrote:
# Loop through users
foreach ($user in $userList) {
That comment is worthless. The code already tells you it’s looping through users. What I should write is:
# Exclude service accounts — they match the filter but should never be modified
foreach ($user in $userList) {
Now someone knows there was a reason for that exclusion. Now they don’t accidentally remove it six months later when it looks redundant.
And it means handling errors in a way that surfaces information instead of burying it. A try/catch that silently continues isn’t error handling. It’s wishful thinking with a safety net you can’t see.
The Part Nobody Wants to Do
The honest answer is that writing maintainable scripts takes longer. Not a lot longer, but longer. You’re stopping to think about naming. You’re adding context that feels obvious to you right now. You’re structuring your error output to be readable by a human who will be stressed when they’re reading it.
I start optimizing a workflow and suddenly three hours have passed, and most of the time those three hours were spent making it work, not making it readable. That’s just how it goes when you’re deep in problem-solving mode. The cognitive load of the actual logic eats all the bandwidth.
The only fix I’ve found is to treat maintainability as a separate pass. Get it working. Then go back through it like you’re reading it for the first time and you’re mildly irritated. Because that’s exactly the energy the next person is going to bring to it.
What Actually Separates the Two Skills
Writing a script for yourself is an act of externalizing your current thinking. You’re basically transcribing your brain into syntax. It works because you’re the author and the reader simultaneously.
Writing a script someone else will maintain is a communication task. You’re writing for a reader who doesn’t have your context, your history with the problem, or your understanding of why that one condition is in there. You’re writing for past-you six months from now, or for a colleague at 8am on a Monday who just got paged because something broke.
Those are genuinely different things. One requires knowing PowerShell. The other requires knowing PowerShell and thinking about how information travels between people across time.
I’ve got 28 years of IT experience, and I’ll be straight with you: I’m a better script-writer-for-myself than I am a script-writer-for-others. That gap is real. I’m closing it slowly, mostly by having been the person on the receiving end of an undocumented script one too many times and remembering exactly how that felt.
The Actual Test
Before you hand a script to anyone, do this one thing: read it out loud like you’re explaining it to a smart person who has never seen it before. If you find yourself saying “okay, this part is a little confusing but basically…” that’s your sign. Fix that part first.
If it passes that test, it’s probably maintainable. If it doesn’t, no amount of “I’ll just walk them through it” is going to substitute for the documentation you didn’t write.
A script that works but can’t be maintained is a time bomb. It runs fine until something changes, and then whoever touches it is flying blind with a live wire.
Write the comments. Name the variables like words. Handle the errors loudly.
Your future colleague, and honestly your future self, will owe you one.