PowerShell Is Still the Best Tool Nobody Talks About
Every few years someone writes a blog post declaring PowerShell dead. Python replaced it. YAML is the future. Meanwhile, I'm still using it every single day to do things that would take hours through any GUI.
Why PowerShell endures
PowerShell's core insight — that everything is an object, not text — remains underappreciated. When you pipe commands in Bash, you're parsing text. When you pipe in PowerShell, you're passing structured objects with properties you can filter, sort, and transform without regex gymnastics.
Get-ADUser -Filter * | Where-Object {$_.LastLogonDate -lt (Get-Date).AddDays(-90)} | Disable-ADAccount
That's a one-liner that disables every AD account that hasn't logged in for 90 days. Try doing that in Bash against Active Directory. You can't, because AD isn't a Linux service. But more importantly: the output is a collection of user objects, not a text stream. If I want to export it to CSV, add it to the pipeline. If I want to send an email report, add it. The object model means I compose operations instead of fighting with sed.
The module ecosystem nobody appreciates
The PowerShell Gallery has modules for everything in the Microsoft ecosystem: Exchange Online, Azure, SharePoint, Teams, Active Directory, Entra ID, VMware, Hyper-V, SQL Server, Windows Server. These aren't community hacks. Most are maintained by the product teams.
When I need to bulk-update 500 distribution group memberships, I don't open the Exchange admin center. I write a five-line script using the ExchangeOnlineManagement module. When I need to audit Azure resource compliance across 20 subscriptions, I don't click through the portal. I use the Az module.
The modules aren't perfect. Some are poorly documented. Some have breaking changes between versions. Some require you to install three different authentication libraries because Microsoft can't settle on one. But they exist, they work, and they save me hours every week.
The automation that runs my week
Every Monday morning, four PowerShell scripts run:
-
AD hygiene check. Disabled accounts older than 90 days get deleted. Expired accounts get disabled. Password-never-expires accounts get flagged for review. This script has been running since 2017 and has probably prevented a dozen security audits from becoming nightmares.
-
Azure cost snapshot. Collects the current month's spend by subscription, compares against budget, sends a one-page summary. Not as pretty as the Azure Cost Management dashboard, but it hits my inbox automatically instead of requiring me to log in.
-
Backup status report. Queries the backup infrastructure, checks for failed jobs in the last 24 hours, sends alerts if anything is off. A backup job that failed at 2am and nobody noticed is a disaster waiting to happen.
-
Certificate expiry check. Scans all servers for certificates expiring in the next 30 days. Certs expiring on a Saturday at 3pm that nobody remembered to renew: there's always at least one. Better to find it on Monday than Saturday.
These four scripts run in about 90 seconds combined. Before I automated them, each one was 15-30 minutes of manual checking. Spread across a year, that's roughly 150 hours of work replaced by 78 minutes of PowerShell.
The thing people get wrong about PowerShell
"It's only for Windows." This hasn't been true since PowerShell Core (now PowerShell 7) launched in 2018. It runs on Linux and macOS. I have the same automation scripts managing Windows and Linux servers, calling the same cmdlets, because the modules abstract the platform differences.
"It's too verbose." Verbose means readable. Readable means maintainable. A PowerShell script I wrote three years ago is still understandable today because the cmdlet names tell you what they do. Get-Mailbox | Set-Mailbox doesn't need comments. It's self-documenting.
"It's not as powerful as Python." For system administration on the Microsoft stack, it's more powerful than Python. The modules exist. The integration exists. You can call .NET libraries directly. You can embed C#. The ceiling is higher than most people realise.
When I don't use PowerShell
I use Bicep and ARM for infrastructure provisioning because declarative infrastructure makes more sense for that use case. I use Bash for quick Linux tasks because it's already there. I use Python when I need libraries that exist in the Python ecosystem. PowerShell is not the only tool. It's the right tool for a specific class of problems, and that class is "everything that touches Microsoft infrastructure."
If you manage Windows, Active Directory, Exchange, Azure, or M365, learn PowerShell. Not because it's cool. Because it's the difference between clicking through wizards for three hours and writing a script that finishes while your coffee is still hot.