<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Chrissy LeMaire's blog on netnerds.net</title><link>https://blog.netnerds.net/</link><description>Recent content in Chrissy LeMaire's blog on netnerds.net</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright © 2003-2022 all rights reserved.</copyright><lastBuildDate>Sat, 07 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.netnerds.net/index.xml" rel="self" type="application/rss+xml"/><item><title>Fixing Claude Code's PowerShell Problem with Hooks</title><link>https://blog.netnerds.net/2026/02/claude-code-powershell-hooks/</link><pubDate>Sat, 07 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2026/02/claude-code-powershell-hooks/</guid><description>
&lt;blockquote&gt;
&lt;p&gt;TIP: Just paste this url into Claude Code and say &amp;quot;implement this for me&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude Code writes great PowerShell, but it's not the best at using it as a shell. It's basically bash on top of PowerShell. Every single session, I see the same thing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It tries &lt;code&gt;powershell.exe -Command&lt;/code&gt; (Windows PowerShell 5.1, modules don't load)&lt;/li&gt;
&lt;li&gt;It fails, switches to &lt;code&gt;pwsh -Command&lt;/code&gt; with inline code (bash eats the quoting)&lt;/li&gt;
&lt;li&gt;It fails again, finally writes a &lt;code&gt;.ps1&lt;/code&gt; file and runs &lt;code&gt;pwsh -File&lt;/code&gt; (works instantly)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Three attempts. Most times. Even with explicit instructions in CLAUDE.md telling it to go straight to the script file approach. I documented the correct pattern months ago and it still burns through two failures before doing the right thing.&lt;/p&gt;</description><content>
&lt;blockquote&gt;
&lt;p&gt;TIP: Just paste this url into Claude Code and say &amp;quot;implement this for me&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude Code writes great PowerShell, but it's not the best at using it as a shell. It's basically bash on top of PowerShell. Every single session, I see the same thing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It tries &lt;code&gt;powershell.exe -Command&lt;/code&gt; (Windows PowerShell 5.1, modules don't load)&lt;/li&gt;
&lt;li&gt;It fails, switches to &lt;code&gt;pwsh -Command&lt;/code&gt; with inline code (bash eats the quoting)&lt;/li&gt;
&lt;li&gt;It fails again, finally writes a &lt;code&gt;.ps1&lt;/code&gt; file and runs &lt;code&gt;pwsh -File&lt;/code&gt; (works instantly)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Three attempts. Most times. Even with explicit instructions in CLAUDE.md telling it to go straight to the script file approach. I documented the correct pattern months ago and it still burns through two failures before doing the right thing.&lt;/p&gt;</content></item><item><title>Fixing SQL Server Case Sensitivity Issues with GitHub Copilot CLI</title><link>https://blog.netnerds.net/2025/11/sql-server-case-sensitivity/</link><pubDate>Mon, 10 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/11/sql-server-case-sensitivity/</guid><description>
&lt;p&gt;When creating dbatools commands, most of us use case-insensitive collation because that's the default and what we use in our labs. So creating commands that call T-SQL always works on our machines, but then &lt;a href="https://github.com/dataplat/dbatools/issues/6014"&gt;we'll get an issue&lt;/a&gt; requesting that we fix a command to work on someone's case-sensitive SQL Server.&lt;/p&gt;
&lt;p&gt;With case-sensitive collation (CS), &lt;code&gt;dbo.cats&lt;/code&gt; and &lt;code&gt;dbo.Cats&lt;/code&gt; are two distinct objects.&lt;/p&gt;
&lt;p&gt;Fixing these SQL queries usually requires me to open the command, copy the T-SQL, paste it into SSMS (which would fix the casing), then copy it back to the command.&lt;/p&gt;</description><content>
&lt;p&gt;When creating dbatools commands, most of us use case-insensitive collation because that's the default and what we use in our labs. So creating commands that call T-SQL always works on our machines, but then &lt;a href="https://github.com/dataplat/dbatools/issues/6014"&gt;we'll get an issue&lt;/a&gt; requesting that we fix a command to work on someone's case-sensitive SQL Server.&lt;/p&gt;
&lt;p&gt;With case-sensitive collation (CS), &lt;code&gt;dbo.cats&lt;/code&gt; and &lt;code&gt;dbo.Cats&lt;/code&gt; are two distinct objects.&lt;/p&gt;
&lt;p&gt;Fixing these SQL queries usually requires me to open the command, copy the T-SQL, paste it into SSMS (which would fix the casing), then copy it back to the command.&lt;/p&gt;</content></item><item><title>Got a ChatGPT Subscription? Use It to Keep Your Blog Up-to-date</title><link>https://blog.netnerds.net/2025/11/update-blog-chatgpt-codex/</link><pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/11/update-blog-chatgpt-codex/</guid><description>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; ChatGPT Pro ($20/month) gives you access to GPT-5 via Codex CLI which is perfect for automating blog updates. I used it on this very blog and was able to update about 50 blog posts before I hit the rate limit. After the rate limit is hit, I have to wait for up to 4 hours then start again. Skip the recommended Codex model (it's terrible) and GPT-5 minimal reasoning.&lt;/p&gt;</description><content>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; ChatGPT Pro ($20/month) gives you access to GPT-5 via Codex CLI which is perfect for automating blog updates. I used it on this very blog and was able to update about 50 blog posts before I hit the rate limit. After the rate limit is hit, I have to wait for up to 4 hours then start again. Skip the recommended Codex model (it's terrible) and GPT-5 minimal reasoning.&lt;/p&gt;</content></item><item><title>Update your blog with an AI CLI (No, really)</title><link>https://blog.netnerds.net/2025/11/update-your-blog/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/11/update-your-blog/</guid><description>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I used Claude Code CLI to batch-update 100+ dbatools blog posts from 2016-2025. It fixed broken links, converted old PowerShell screenshots to text, updated deprecated commands, and even found new websites for people mentioned in old posts.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-ChildItem&lt;/span&gt; &lt;span class="p"&gt;*.&lt;/span&gt;&lt;span class="nb"&gt;md &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Invoke-AITool&lt;/span&gt; &lt;span class="n"&gt;-Prompt&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;blog-refresh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The AI handled nuanced judgment calls I'd never do manually. &lt;a href="https://github.com/dataplat/web/commit/ab50afab01d4f0b11ad1f6d9e534405fa49c8a3f"&gt;See the full commit&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We have hundreds of blog posts on dbatools, dating back to 2016. Links rot. Commands change. Screenshots turn into ancient Windows PowerShell blue screens that look embarrassing in 2025.&lt;/p&gt;</description><content>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I used Claude Code CLI to batch-update 100+ dbatools blog posts from 2016-2025. It fixed broken links, converted old PowerShell screenshots to text, updated deprecated commands, and even found new websites for people mentioned in old posts.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-ChildItem&lt;/span&gt; &lt;span class="p"&gt;*.&lt;/span&gt;&lt;span class="nb"&gt;md &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Invoke-AITool&lt;/span&gt; &lt;span class="n"&gt;-Prompt&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;blog-refresh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The AI handled nuanced judgment calls I'd never do manually. &lt;a href="https://github.com/dataplat/web/commit/ab50afab01d4f0b11ad1f6d9e534405fa49c8a3f"&gt;See the full commit&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We have hundreds of blog posts on dbatools, dating back to 2016. Links rot. Commands change. Screenshots turn into ancient Windows PowerShell blue screens that look embarrassing in 2025.&lt;/p&gt;</content></item><item><title>Update Your Blog with GitHub Copilot CLI</title><link>https://blog.netnerds.net/2025/11/update-blog-copilot-cli/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/11/update-blog-copilot-cli/</guid><description>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Use GitHub Copilot CLI to batch-update old blog posts—fix broken links, modernize code examples, convert screenshots to text.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-ChildItem&lt;/span&gt; &lt;span class="p"&gt;*.&lt;/span&gt;&lt;span class="nb"&gt;md &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Invoke-AITool&lt;/span&gt; &lt;span class="n"&gt;-Prompt&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;blog-refresh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Write a prompt doc with your rules, run the command, review the diffs, commit what works.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Yesterday I wrote about &lt;a href="https://blog.netnerds.net/2025/11/update-your-blog/"&gt;updating blog content with Claude Code&lt;/a&gt;. But what if your company uses GitHub Copilot instead? If you've got GitHub, Copilot's probably already available to you. Here's how to do the same blog maintenance work with GitHub Copilot CLI.&lt;/p&gt;</description><content>
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Use GitHub Copilot CLI to batch-update old blog posts—fix broken links, modernize code examples, convert screenshots to text.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-ChildItem&lt;/span&gt; &lt;span class="p"&gt;*.&lt;/span&gt;&lt;span class="nb"&gt;md &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Invoke-AITool&lt;/span&gt; &lt;span class="n"&gt;-Prompt&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;blog-refresh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Write a prompt doc with your rules, run the command, review the diffs, commit what works.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Yesterday I wrote about &lt;a href="https://blog.netnerds.net/2025/11/update-your-blog/"&gt;updating blog content with Claude Code&lt;/a&gt;. But what if your company uses GitHub Copilot instead? If you've got GitHub, Copilot's probably already available to you. Here's how to do the same blog maintenance work with GitHub Copilot CLI.&lt;/p&gt;</content></item><item><title>Rebuilding dbatools.io: From Notepad++ to Cursor</title><link>https://blog.netnerds.net/2025/10/haiku-finally-works/</link><pubDate>Fri, 31 Oct 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/10/haiku-finally-works/</guid><description>
&lt;p&gt;I just rebuilt &lt;a href="https://dbatools.io"&gt;dbatools.io&lt;/a&gt; in a day. The new site is developer-focused, modern, and actually useful. And I did it all with Claude Haiku, which until recently was completely useless to me.&lt;/p&gt;
&lt;h2 id="the-origin-story-notepad"&gt;The Origin Story: Notepad++&lt;/h2&gt;
&lt;p&gt;When I first designed dbatools.io back in 2016, I based it on &lt;a href="https://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt;. At the time, I had no idea they were open source—they looked like a polished commercial product. That's exactly how I wanted to position dbatools: as a tool you didn't have to care about who developed it or whether it was open source. You just used the product.&lt;/p&gt;</description><content>
&lt;p&gt;I just rebuilt &lt;a href="https://dbatools.io"&gt;dbatools.io&lt;/a&gt; in a day. The new site is developer-focused, modern, and actually useful. And I did it all with Claude Haiku, which until recently was completely useless to me.&lt;/p&gt;
&lt;h2 id="the-origin-story-notepad"&gt;The Origin Story: Notepad++&lt;/h2&gt;
&lt;p&gt;When I first designed dbatools.io back in 2016, I based it on &lt;a href="https://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt;. At the time, I had no idea they were open source—they looked like a polished commercial product. That's exactly how I wanted to position dbatools: as a tool you didn't have to care about who developed it or whether it was open source. You just used the product.&lt;/p&gt;</content></item><item><title>Have You Considered Not Using SQL Server High Availability?</title><link>https://blog.netnerds.net/2025/10/go-ahead-and-remove-it/</link><pubDate>Mon, 20 Oct 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/10/go-ahead-and-remove-it/</guid><description>
&lt;p&gt;When someone asks about SQL Server architecture, the reflexive answer is usually 'High Availability,' as if it's a requirement rather than a choice. But after 20 years of managing SQL Server environments, I've found that HA often creates more problems than it solves, especially in certain types of organizations.&lt;/p&gt;
&lt;h2 id="the-turnover-problem"&gt;The Turnover Problem&lt;/h2&gt;
&lt;p&gt;Most places I've worked have rotating staff—people are out within 1-4 years for all kinds of reasons. That means the infrastructure we build needs to stay as simple as possible, because all of us might leave in that same timeframe.&lt;/p&gt;</description><content>
&lt;p&gt;When someone asks about SQL Server architecture, the reflexive answer is usually 'High Availability,' as if it's a requirement rather than a choice. But after 20 years of managing SQL Server environments, I've found that HA often creates more problems than it solves, especially in certain types of organizations.&lt;/p&gt;
&lt;h2 id="the-turnover-problem"&gt;The Turnover Problem&lt;/h2&gt;
&lt;p&gt;Most places I've worked have rotating staff—people are out within 1-4 years for all kinds of reasons. That means the infrastructure we build needs to stay as simple as possible, because all of us might leave in that same timeframe.&lt;/p&gt;</content></item><item><title>PowerShell Output Redirection with AI CLIs</title><link>https://blog.netnerds.net/2025/10/ai-cli-output/</link><pubDate>Mon, 20 Oct 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/10/ai-cli-output/</guid><description>
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: In Windows, many AI CLI tools (Aider, Claude Code, Gemini, etc.) work unreliably with PowerShell's standard output capture. The solution is to write to temp files instead of variables or add a &lt;code&gt;-Raw&lt;/code&gt; flag for when you need the tool to actually commit changes instead of just previewing them or hanging forever.&lt;/p&gt;
&lt;h2 id="the-unix-tooling-problem-on-windows"&gt;The Unix tooling problem on Windows&lt;/h2&gt;
&lt;p&gt;Most AI tools seem to be written using Unix-native tools like Python and Node.js. If you're building PowerShell modules that interact with AI CLIs like Claude Code or GitHub Copilot CLI, you're dealing with Node.js wrappers or Python processes, all running on Windows where nobody really designed them to work. It'll sometimes work, but then it doesn't.&lt;/p&gt;</description><content>
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: In Windows, many AI CLI tools (Aider, Claude Code, Gemini, etc.) work unreliably with PowerShell's standard output capture. The solution is to write to temp files instead of variables or add a &lt;code&gt;-Raw&lt;/code&gt; flag for when you need the tool to actually commit changes instead of just previewing them or hanging forever.&lt;/p&gt;
&lt;h2 id="the-unix-tooling-problem-on-windows"&gt;The Unix tooling problem on Windows&lt;/h2&gt;
&lt;p&gt;Most AI tools seem to be written using Unix-native tools like Python and Node.js. If you're building PowerShell modules that interact with AI CLIs like Claude Code or GitHub Copilot CLI, you're dealing with Node.js wrappers or Python processes, all running on Windows where nobody really designed them to work. It'll sometimes work, but then it doesn't.&lt;/p&gt;</content></item><item><title>dbatools is moving to Azure Trusted Signing</title><link>https://blog.netnerds.net/2025/08/dbatools-azure-trusted-signing/</link><pubDate>Tue, 05 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/08/dbatools-azure-trusted-signing/</guid><description>
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; dbatools is moving to Azure Trusted Signing, which means Microsoft backs our reputation and dbatools won't trigger as many antivirus false positives.&lt;/p&gt;
&lt;p&gt;Users upgrading from older signed versions will need &lt;code&gt;-SkipPublisherCheck&lt;/code&gt; only once during the initial transition. PowerShell users with strict ExecutionPolicies (AllSigned/RemoteSigned) will need to trust each new certificate after every update due to Azure Trusted Signing's daily cert rotation (but you can use the automation script provided below).&lt;/p&gt;</description><content>
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; dbatools is moving to Azure Trusted Signing, which means Microsoft backs our reputation and dbatools won't trigger as many antivirus false positives.&lt;/p&gt;
&lt;p&gt;Users upgrading from older signed versions will need &lt;code&gt;-SkipPublisherCheck&lt;/code&gt; only once during the initial transition. PowerShell users with strict ExecutionPolicies (AllSigned/RemoteSigned) will need to trust each new certificate after every update due to Azure Trusted Signing's daily cert rotation (but you can use the automation script provided below).&lt;/p&gt;</content></item><item><title>Document Intelligence with Azure Functions: A Practical Implementation</title><link>https://blog.netnerds.net/2025/03/intelligent-docs-with-azure-funtions-openai/</link><pubDate>Wed, 19 Mar 2025 00:00:00 +0000</pubDate><guid>https://blog.netnerds.net/2025/03/intelligent-docs-with-azure-funtions-openai/</guid><description>
&lt;p&gt;Recently, I &lt;a href="https://blog.netnerds.net/2025/03/sharepoint-power-platform-ai/"&gt;wrote about a system I created that automatically classifies SharePoint documents&lt;/a&gt;, but only briefly touched on the most important part—the Azure Function that does all the heavy lifting.&lt;/p&gt;
&lt;p&gt;This post walks through the technical part of this document processing engine and demos how to build an Azure Function that extracts text from documents, analyzes content with cognitive services, and outputs clean, structured data.&lt;/p&gt;
&lt;h2 id="why-document-intelligence-matters-for-automation-engineers"&gt;Why document intelligence matters for automation engineers&lt;/h2&gt;
&lt;p&gt;Automation engineers are often skeptical about AI's usefulness in their workflows, and I get it but document processing is &lt;em&gt;genuinely&lt;/em&gt; a good use case.&lt;/p&gt;</description><content>
&lt;p&gt;Recently, I &lt;a href="https://blog.netnerds.net/2025/03/sharepoint-power-platform-ai/"&gt;wrote about a system I created that automatically classifies SharePoint documents&lt;/a&gt;, but only briefly touched on the most important part—the Azure Function that does all the heavy lifting.&lt;/p&gt;
&lt;p&gt;This post walks through the technical part of this document processing engine and demos how to build an Azure Function that extracts text from documents, analyzes content with cognitive services, and outputs clean, structured data.&lt;/p&gt;
&lt;h2 id="why-document-intelligence-matters-for-automation-engineers"&gt;Why document intelligence matters for automation engineers&lt;/h2&gt;
&lt;p&gt;Automation engineers are often skeptical about AI's usefulness in their workflows, and I get it but document processing is &lt;em&gt;genuinely&lt;/em&gt; a good use case.&lt;/p&gt;</content></item></channel></rss>