<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://psake.netlify.app/blog</id>
    <title>psake Blog</title>
    <updated>2026-04-08T18:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://psake.netlify.app/blog"/>
    <subtitle>psake Blog</subtitle>
    <icon>https://psake.netlify.app/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Building a Resilient build.ps1 for psake Projects]]></title>
        <id>https://psake.netlify.app/blog/resilient-build-ps1</id>
        <link href="https://psake.netlify.app/blog/resilient-build-ps1"/>
        <updated>2026-04-08T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[Extend your psake build.ps1 with clear error handling, dynamic tab completion, CI-safe module imports, and more.]]></summary>
        <content type="html"><![CDATA[<p>In psake projects, <code>build.ps1</code> is the entry point script that wires everything together. It installs dependencies, configures the environment, and hands off to psake to run your actual build tasks. Think of it as the bootstrapper that gets a fresh machine — or a CI agent — from zero to a working build in a single command: <code>.\build.ps1</code>.</p>
<p>The <a href="https://github.com/psake/psake/blob/main/build.ps1" target="_blank" rel="noopener noreferrer">default <code>build.ps1</code></a> that ships with psake handles the basics well: bootstrap installation, help output, build environment detection, and proper CI exit codes. But once you're running concurrent CI jobs, managing internal package feeds, or onboarding new contributors, a few gaps start to show. Here are five patterns that harden your entry point for the real world.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="clear-error-handling">Clear Error Handling<a href="https://psake.netlify.app/blog/resilient-build-ps1#clear-error-handling" class="hash-link" aria-label="Direct link to Clear Error Handling" title="Direct link to Clear Error Handling">​</a></h2>
<p>The default script silently fails with cryptic "term not recognized" errors when dependencies aren't installed. A simple guard clause makes the fix obvious:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">-not</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">Get-Module</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Name </span><span class="token string" style="color:#e3116c">'PSDepend'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">ListAvailable</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Missing dependencies. Please run with the "-Bootstrap" flag to install dependencies.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Instead of hunting through stack traces, new contributors get a one-line message telling them exactly what to do.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="dynamic-tab-completion">Dynamic Tab Completion<a href="https://psake.netlify.app/blog/resilient-build-ps1#dynamic-tab-completion" class="hash-link" aria-label="Direct link to Dynamic Tab Completion" title="Direct link to Dynamic Tab Completion">​</a></h2>
<p>Hardcoded <code>[ValidateSet()]</code> values require manual updates every time you add a task. Replace them with <code>[ArgumentCompleter]</code> for live discovery:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ArgumentCompleter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">param</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$Command</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$Parameter</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$WordToComplete</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$CommandAst</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$FakeBoundParams</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">Get-PSakeScriptTasks</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">BuildFile </span><span class="token string" style="color:#e3116c">'./build.psake.ps1'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">ErrorAction </span><span class="token string" style="color:#e3116c">'Stop'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">Where-Object</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$_</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name </span><span class="token operator" style="color:#393A34">-like</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$WordToComplete</span><span class="token string" style="color:#e3116c">*"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">Select-Object</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">ExpandProperty </span><span class="token string" style="color:#e3116c">'Name'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            @</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token namespace" style="opacity:0.7">[string[]]</span><span class="token variable" style="color:#36acaa">$Task</span><span class="token plain"> = </span><span class="token string" style="color:#e3116c">'default'</span><span class="token punctuation" style="color:#393A34">,</span><br></span></code></pre></div></div>
<p>Now tab completion always reflects the actual tasks in your psake file — no maintenance required.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="try-import-first-pattern">Try-Import-First Pattern<a href="https://psake.netlify.app/blog/resilient-build-ps1#try-import-first-pattern" class="hash-link" aria-label="Direct link to Try-Import-First Pattern" title="Direct link to Try-Import-First Pattern">​</a></h2>
<p>When parallel CI jobs share a module cache, <code>Install-Module</code> can hit file locks and fail. The fix: try importing existing modules first, and only install if the import fails.</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$importSucceeded</span><span class="token plain"> = </span><span class="token boolean" style="color:#36acaa">$false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Invoke-PSDepend</span><span class="token plain"> @psDependParameters</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$importSucceeded</span><span class="token plain"> = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Write-Verbose</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Successfully imported existing modules.'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Verbose</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Write-Verbose</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Could not import all required modules: </span><span class="token string variable" style="color:#36acaa">$_</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Verbose</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Write-Verbose</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Attempting to install missing or outdated dependencies...'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Verbose</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">-not</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$importSucceeded</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">Invoke-PSDepend</span><span class="token plain"> @psDependParameters </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Install</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">Write-Error</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to install and import required dependencies: </span><span class="token string variable" style="color:#36acaa">$_</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This eliminates a common source of flaky builds in enterprise CI pipelines.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="internal-repository-support">Internal Repository Support<a href="https://psake.netlify.app/blog/resilient-build-ps1#internal-repository-support" class="hash-link" aria-label="Direct link to Internal Repository Support" title="Direct link to Internal Repository Support">​</a></h2>
<p>Organizations often host modules on internal NuGet feeds (ProGet, Azure Artifacts, etc.). Idempotent registration keeps the script portable:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$repositoryName</span><span class="token plain"> = </span><span class="token string" style="color:#e3116c">'internal-nuget-repo'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">-not</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">Get-PSRepository</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Name </span><span class="token variable" style="color:#36acaa">$repositoryName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">ErrorAction </span><span class="token string" style="color:#e3116c">'SilentlyContinue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Register-PSRepository</span><span class="token plain"> @registerPSRepositorySplat</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Pair this with TLS protocol patching to ensure compatibility with modern security requirements:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token namespace" style="opacity:0.7">[System.Net.ServicePointManager]</span><span class="token plain">::SecurityProtocol = </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">[System.Net.ServicePointManager]</span><span class="token plain">::SecurityProtocol </span><span class="token operator" style="color:#393A34">-bor</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">[System.Net.SecurityProtocolType]</span><span class="token plain">::Tls12 </span><span class="token operator" style="color:#393A34">-bor</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">[System.Net.SecurityProtocolType]</span><span class="token plain">::Tls13</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="powershellget-version-pinning">PowerShellGet Version Pinning<a href="https://psake.netlify.app/blog/resilient-build-ps1#powershellget-version-pinning" class="hash-link" aria-label="Direct link to PowerShellGet Version Pinning" title="Direct link to PowerShellGet Version Pinning">​</a></h2>
<p>PowerShellGet v3 introduces breaking API changes. Pinning to v2.x keeps behavior predictable:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$powerShellGetModuleParameters</span><span class="token plain"> = @</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Name           = </span><span class="token string" style="color:#e3116c">'PowerShellGet'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MinimumVersion = </span><span class="token string" style="color:#e3116c">'2.0.0'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MaximumVersion = </span><span class="token string" style="color:#e3116c">'2.99.99'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Force          = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">-not</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$powerShellGetModule</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Install-Module</span><span class="token plain"> @powerShellGetModuleParameters </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Scope </span><span class="token string" style="color:#e3116c">'CurrentUser'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">AllowClobber</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Import-Module</span><span class="token plain"> @powerShellGetModuleParameters</span><br></span></code></pre></div></div>
<p>This prevents surprise breakage when a CI agent picks up a new PowerShellGet version.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-the-complete-script">Get the Complete Script<a href="https://psake.netlify.app/blog/resilient-build-ps1#get-the-complete-script" class="hash-link" aria-label="Direct link to Get the Complete Script" title="Direct link to Get the Complete Script">​</a></h2>
<p>These five patterns combine into a production-ready 143-line bootstrap that handles concurrent CI pipelines, enterprise package management, and mixed OS environments. For the full walkthrough and complete script, check out the <a href="https://tablackburn.github.io/p/resilient-build-ps1/" target="_blank" rel="noopener noreferrer">original post on my blog</a>.</p>]]></content>
        <author>
            <name>Trent Blackburn</name>
            <uri>https://tablackburn.github.io</uri>
        </author>
        <category label="psake" term="psake"/>
        <category label="PowerShell" term="PowerShell"/>
        <category label="Build Automation" term="Build Automation"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Best Practices" term="Best Practices"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[psake Meets VS Code: The Official Extension Hits v1.0]]></title>
        <id>https://psake.netlify.app/blog/psake-vscode-extension-v1</id>
        <link href="https://psake.netlify.app/blog/psake-vscode-extension-v1"/>
        <updated>2026-03-10T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[The psake VS Code extension v1.0 brings task discovery, CodeLens integration, a dedicated task explorer, and smart build script detection directly into your editor.]]></summary>
        <content type="html"><![CDATA[<p>We're thrilled to announce the v1.0 release of the <a href="https://github.com/psake/psake-vscode" target="_blank" rel="noopener noreferrer">psake VS Code extension</a>—bringing first-class psake support directly into the world's most popular code editor. If you've been running psake from the terminal, you can now discover, navigate, and execute your build tasks without ever leaving VS Code.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-a-vs-code-extension">Why a VS Code Extension?<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#why-a-vs-code-extension" class="hash-link" aria-label="Direct link to Why a VS Code Extension?" title="Direct link to Why a VS Code Extension?">​</a></h2>
<p>A core part of our mission with psake is meeting developers where they already work. Whether that's through <a href="https://psake.netlify.app/blog/introducing-psake-agent-skill">AI-assisted workflows with Agent Skills</a>, CI/CD pipelines, or your daily editor—we want psake to feel native to your environment. With VS Code being the editor of choice for so many PowerShell developers, a dedicated extension was a natural next step.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whats-in-v10">What's in v1.0<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#whats-in-v10" class="hash-link" aria-label="Direct link to What's in v1.0" title="Direct link to What's in v1.0">​</a></h2>
<p>This isn't a minimal snippet pack. The v1.0 release is a full-featured integration that makes VS Code aware of your psake build system.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="task-provider">Task Provider<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#task-provider" class="hash-link" aria-label="Direct link to Task Provider" title="Direct link to Task Provider">​</a></h3>
<p>The extension automatically detects tasks from your <code>psakefile.ps1</code> and surfaces them in VS Code's built-in task system. Your default task maps to the Build group, so <code>Ctrl+Shift+B</code> just works. Tasks refresh automatically when you save your build file—no manual reload needed.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="psake-tasks-explorer">psake Tasks Explorer<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#psake-tasks-explorer" class="hash-link" aria-label="Direct link to psake Tasks Explorer" title="Direct link to psake Tasks Explorer">​</a></h3>
<p>A dedicated sidebar panel in the Explorer view gives you an at-a-glance view of every task in your project, complete with descriptions and dependency chains. Click any task to navigate directly to its definition, or hit the run button to execute it immediately.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="codelens-integration">CodeLens Integration<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#codelens-integration" class="hash-link" aria-label="Direct link to CodeLens Integration" title="Direct link to CodeLens Integration">​</a></h3>
<p>Every <code>Task</code> declaration in your build file gets a "Run Task" CodeLens action. See a task, run it—right from the editor gutter. It's the fastest path from reading build logic to executing it.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="smart-build-script-detection">Smart Build Script Detection<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#smart-build-script-detection" class="hash-link" aria-label="Direct link to Smart Build Script Detection" title="Direct link to Smart Build Script Detection">​</a></h3>
<p>If your project uses a wrapper script like <code>build.ps1</code> (a common pattern in the psake ecosystem), the extension detects it automatically and routes task execution through it. This means your bootstrapping, dependency installation, and any custom setup all run correctly—just as they would from the terminal.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="tasksjson-intellisense">tasks.json IntelliSense<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#tasksjson-intellisense" class="hash-link" aria-label="Direct link to tasks.json IntelliSense" title="Direct link to tasks.json IntelliSense">​</a></h3>
<p>When you configure psake tasks in <code>.vscode/tasks.json</code>, the extension provides autocomplete for task names. Combined with the new "psake: Sync Tasks to tasks.json" command, you can quickly wire up your build tasks into VS Code's task runner with full IntelliSense support.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="nine-code-snippets">Nine Code Snippets<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#nine-code-snippets" class="hash-link" aria-label="Direct link to Nine Code Snippets" title="Direct link to Nine Code Snippets">​</a></h3>
<p>Scaffolding new tasks and build file structures is faster with nine built-in snippets covering everything from basic task definitions to <code>Properties</code>, <code>Include</code>, <code>Framework</code>, <code>FormatTaskName</code>, <code>TaskSetup</code>, and <code>TaskTearDown</code> blocks.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="quick-start">Quick Start<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#quick-start" class="hash-link" aria-label="Direct link to Quick Start" title="Direct link to Quick Start">​</a></h2>
<ol>
<li>Install the <a href="https://marketplace.visualstudio.com/publishers/psake" target="_blank" rel="noopener noreferrer">psake extension</a> from the VS Code Marketplace</li>
<li>Make sure you have the <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell" target="_blank" rel="noopener noreferrer">PowerShell extension</a> installed</li>
<li>Open a project that contains a <code>psakefile.ps1</code> or <code>build.ps1</code></li>
<li>The extension activates automatically—check the Explorer sidebar for the psake Tasks panel</li>
</ol>
<p>That's it. No configuration required—but there's plenty available if you need it.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="fully-configurable">Fully Configurable<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#fully-configurable" class="hash-link" aria-label="Direct link to Fully Configurable" title="Direct link to Fully Configurable">​</a></h2>
<p>The extension works out of the box, but every aspect of its behavior can be tuned to fit your workflow. Toggle CodeLens on or off, point to a custom PowerShell executable, pass extra parameters to <code>Invoke-psake</code> or your build script, and customize shell arguments—all without restarting VS Code.</p>
<p>For the full list of settings, check out the <a href="https://psake.netlify.app/docs/integrations/vscode-extension#configuration">VS Code extension docs</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="part-of-a-growing-ecosystem">Part of a Growing Ecosystem<a href="https://psake.netlify.app/blog/psake-vscode-extension-v1#part-of-a-growing-ecosystem" class="hash-link" aria-label="Direct link to Part of a Growing Ecosystem" title="Direct link to Part of a Growing Ecosystem">​</a></h2>
<p>The VS Code extension joins a growing set of tools designed to make psake easy to use wherever you are:</p>
<ul>
<li><strong><a href="https://github.com/psake/psake" target="_blank" rel="noopener noreferrer">psake</a></strong> — The build automation engine</li>
<li><strong><a href="https://github.com/psake/PowerShellBuild" target="_blank" rel="noopener noreferrer">PowerShellBuild</a></strong> — Common build tasks for PowerShell modules</li>
<li><strong><a href="https://github.com/psake/psake-llm-tools" target="_blank" rel="noopener noreferrer">psake Agent Skill</a></strong> — AI-assisted psake expertise for Claude and GitHub Copilot</li>
<li><strong><a href="https://github.com/psake/psake-vscode" target="_blank" rel="noopener noreferrer">psake VS Code Extension</a></strong> — First-class editor integration</li>
</ul>
<p>We're committed to making psake feel at home in every part of your development workflow. If you have ideas for where psake should go next, <a href="https://github.com/psake/psake-vscode/issues" target="_blank" rel="noopener noreferrer">open an issue</a> or join the conversation.</p>
<p>Give the extension a try and let us know what you think!</p>]]></content>
        <author>
            <name>Gilbert Sanchez</name>
            <uri>https://gilbertsanchez.com</uri>
        </author>
        <category label="Announcement" term="Announcement"/>
        <category label="Release" term="Release"/>
        <category label="psake" term="psake"/>
        <category label="PowerShell" term="PowerShell"/>
        <category label="VS Code" term="VS Code"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[PowerShellBuild v0.8.0: Authenticode Signing & New Documentation]]></title>
        <id>https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs</id>
        <link href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs"/>
        <updated>2026-02-21T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[PowerShellBuild v0.8.0 brings Authenticode code-signing support for PowerShell modules, and comprehensive docs are now available on the psake docs site.]]></summary>
        <content type="html"><![CDATA[<p>Two exciting updates to share today: <strong>PowerShellBuild v0.8.0</strong> has been released with built-in Authenticode code-signing support, and we've added a comprehensive <a href="https://psake.netlify.app/docs/powershellbuild/introduction">PowerShellBuild documentation section</a> right here on the psake docs site.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="powershellbuild-docs-are-now-on-the-psake-site">PowerShellBuild Docs Are Now on the psake Site<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#powershellbuild-docs-are-now-on-the-psake-site" class="hash-link" aria-label="Direct link to PowerShellBuild Docs Are Now on the psake Site" title="Direct link to PowerShellBuild Docs Are Now on the psake Site">​</a></h2>
<p>If you've been looking for guidance on using PowerShellBuild to streamline your PowerShell module builds, you no longer need to piece things together from the README alone. The psake docs site now has a dedicated <strong>PowerShellBuild</strong> section covering:</p>
<ul>
<li><a href="https://psake.netlify.app/docs/powershellbuild/introduction"><strong>Introduction</strong></a> — What PowerShellBuild is and how it relates to psake</li>
<li><a href="https://psake.netlify.app/docs/powershellbuild/getting-started"><strong>Getting Started</strong></a> — Installation and first-build walkthrough</li>
<li><a href="https://psake.netlify.app/docs/powershellbuild/configuration"><strong>Configuration</strong></a> — Deep dive into <code>$PSBPreference</code> and how to customize every aspect of your build</li>
<li><a href="https://psake.netlify.app/docs/powershellbuild/task-reference"><strong>Task Reference</strong></a> — Complete listing of all available tasks and their dependencies</li>
<li><a href="https://psake.netlify.app/docs/powershellbuild/real-world-example"><strong>Real-World Example</strong></a> — A practical end-to-end project setup</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whats-new-in-v080--authenticode-signing">What's New in v0.8.0 — Authenticode Signing<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#whats-new-in-v080--authenticode-signing" class="hash-link" aria-label="Direct link to What's New in v0.8.0 — Authenticode Signing" title="Direct link to What's New in v0.8.0 — Authenticode Signing">​</a></h2>
<p>The headline feature in <a href="https://github.com/psake/PowerShellBuild/releases/tag/v0.8.0" target="_blank" rel="noopener noreferrer">PowerShellBuild v0.8.0</a> is full Authenticode code-signing support for PowerShell modules. This was a highly requested capability, and it's now baked right into the standard build pipeline.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="three-new-public-functions">Three New Public Functions<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#three-new-public-functions" class="hash-link" aria-label="Direct link to Three New Public Functions" title="Direct link to Three New Public Functions">​</a></h3>
<p><strong><code>Get-PSBuildCertificate</code></strong> resolves a code-signing <code>X509Certificate2</code> from five different sources:</p>
<ul>
<li><strong>Auto</strong> — Automatically detects from environment variables or the certificate store</li>
<li><strong>Windows certificate store</strong> — With optional thumbprint filtering</li>
<li><strong>Base64-encoded PFX</strong> — From environment variables, ideal for CI/CD pipelines</li>
<li><strong>PFX file on disk</strong> — With optional password protection</li>
<li><strong>Pre-resolved certificate object</strong> — For custom providers like Azure Key Vault</li>
</ul>
<p><strong><code>Invoke-PSBuildModuleSigning</code></strong> signs your module files (<code>.psd1</code>, <code>.psm1</code>, <code>.ps1</code>) with Authenticode signatures. It supports configurable timestamp servers and hash algorithms including SHA256, SHA384, and SHA512.</p>
<p><strong><code>New-PSBuildFileCatalog</code></strong> creates Windows catalog (<code>.cat</code>) files that record cryptographic hashes of your module's contents for tamper detection.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="four-new-build-tasks">Four New Build Tasks<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#four-new-build-tasks" class="hash-link" aria-label="Direct link to Four New Build Tasks" title="Direct link to Four New Build Tasks">​</a></h3>
<table><thead><tr><th>Task</th><th>Description</th></tr></thead><tbody><tr><td><code>SignModule</code></td><td>Signs module files with Authenticode</td></tr><tr><td><code>BuildCatalog</code></td><td>Creates a Windows catalog file</td></tr><tr><td><code>SignCatalog</code></td><td>Signs the catalog file</td></tr><tr><td><code>Sign</code></td><td>Meta-task that orchestrates the full signing pipeline</td></tr></tbody></table>
<p>These tasks slot into the existing build pipeline with proper dependency ordering: <strong>Build → SignModule → BuildCatalog → SignCatalog</strong>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="certificate-sources">Certificate Sources<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#certificate-sources" class="hash-link" aria-label="Direct link to Certificate Sources" title="Direct link to Certificate Sources">​</a></h2>
<p>PowerShellBuild supports four ways to supply a certificate, listed here in order of common use:</p>
<p><strong>1. Automatic (CI/CD) — Base64 PFX in an env var</strong></p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Store your PFX as a base64 secret (e.g. GitHub Actions secret SIGNCERTIFICATE)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># PowerShellBuild picks it up automatically when Sign.Enabled = $true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Enabled = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># CertificateSource defaults to 'Auto' — done</span><br></span></code></pre></div></div>
<p><strong>2. Local dev — certificate store</strong></p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Enabled           = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CertificateSource = </span><span class="token string" style="color:#e3116c">'Store'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># picks first valid, unexpired code-signing cert in Cert:\CurrentUser\My</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Or pin to a specific one by thumbprint:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CertificateSource = </span><span class="token string" style="color:#e3116c">'Thumbprint'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Thumbprint        = </span><span class="token string" style="color:#e3116c">'AB12CD34EF...'</span><br></span></code></pre></div></div>
<p><strong>3. PFX file on disk</strong></p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Enabled           = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CertificateSource = </span><span class="token string" style="color:#e3116c">'PfxFile'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PfxFilePath       = </span><span class="token string" style="color:#e3116c">'./codesign.pfx'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PfxFilePassword   = </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">Read-Host</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">AsSecureString </span><span class="token string" style="color:#e3116c">'Password'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p><strong>4. Pre-resolved object (Azure Key Vault, HSM, etc.)</strong></p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Get the cert however you like, then hand it directly:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$cert</span><span class="token plain"> = </span><span class="token function" style="color:#d73a49">Get-AzKeyVaultCertificate</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">VaultName </span><span class="token string" style="color:#e3116c">'MyVault'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain">Name </span><span class="token string" style="color:#e3116c">'CodeSignCert'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Get-AzKeyVaultSecret</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># your Key Vault retrieval logic</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Enabled     = </span><span class="token boolean" style="color:#36acaa">$true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$PSBPreference</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Sign</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Certificate = </span><span class="token variable" style="color:#36acaa">$cert</span><span class="token plain">   </span><span class="token comment" style="color:#999988;font-style:italic"># bypasses CertificateSource entirely</span><br></span></code></pre></div></div>
<p>All of these go in your <code>Properties {}</code> block (psake) or before dot-sourcing (Invoke-Build), before the task file is loaded. To also sign before publishing:</p>
<div class="language-powershell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-powershell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token variable" style="color:#36acaa">$PSBPublishDependency</span><span class="token plain"> = @</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Sign'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>All signing operations include platform checks (Windows-only) with appropriate warnings, and verbose logging throughout makes troubleshooting straightforward.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a href="https://psake.netlify.app/blog/powershellbuild-v0.8.0-signing-and-docs#get-started" class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started">​</a></h2>
<ul>
<li><strong>Read the docs:</strong> Check out the <a href="https://psake.netlify.app/docs/powershellbuild/introduction">PowerShellBuild documentation</a> for a complete walkthrough</li>
<li><strong>Upgrade:</strong> <code>Install-Module PowerShellBuild -RequiredVersion 0.8.0</code></li>
<li><strong>Release notes:</strong> <a href="https://github.com/psake/PowerShellBuild/releases/tag/v0.8.0" target="_blank" rel="noopener noreferrer">v0.8.0 on GitHub</a></li>
<li><strong>Feedback:</strong> Open an issue on <a href="https://github.com/psake/PowerShellBuild/issues" target="_blank" rel="noopener noreferrer">GitHub</a> — we'd love to hear how you're using the signing tasks</li>
</ul>]]></content>
        <author>
            <name>Gilbert Sanchez</name>
            <uri>https://gilbertsanchez.com</uri>
        </author>
        <category label="Announcement" term="Announcement"/>
        <category label="Release" term="Release"/>
        <category label="PowerShell" term="PowerShell"/>
        <category label="Build Automation" term="Build Automation"/>
        <category label="psake" term="psake"/>
        <category label="Deployment" term="Deployment"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing the psake Agent Skill]]></title>
        <id>https://psake.netlify.app/blog/introducing-psake-agent-skill</id>
        <link href="https://psake.netlify.app/blog/introducing-psake-agent-skill"/>
        <updated>2026-01-27T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[Enhance your AI-assisted development with the new psake Agent Skill—bringing intelligent build automation guidance to Claude, GitHub Copilot, and other AI coding assistants.]]></summary>
        <content type="html"><![CDATA[<p>We're excited to announce the launch of the <a href="https://github.com/psake/psake-llm-tools" target="_blank" rel="noopener noreferrer">psake Agent Skill</a>—a specialized knowledge package that enables AI coding assistants like Claude and GitHub Copilot to provide expert assistance with psake build automation tasks. Built on the open <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer">Agent Skills</a> standard, this portable skill brings intelligent, context-aware guidance directly to your AI-assisted development workflow.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-psake-agent-skill">What is the psake Agent Skill?<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#what-is-the-psake-agent-skill" class="hash-link" aria-label="Direct link to What is the psake Agent Skill?" title="Direct link to What is the psake Agent Skill?">​</a></h2>
<p>The psake Agent Skill is part of our growing collection of LLM tools designed to enhance how developers work with psake. Built on the open <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer">Agent Skills</a> standard, it provides AI assistants with deep knowledge of psake patterns, syntax, and best practices. This portable format means the same skill works across different AI platforms—whether you're using Claude, GitHub Copilot, or other compatible AI tools.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="key-features">Key Features<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#key-features" class="hash-link" aria-label="Direct link to Key Features" title="Direct link to Key Features">​</a></h2>
<p>The skill includes four comprehensive knowledge components:</p>
<p><strong>SKILL.md</strong> – Core psake fundamentals covering command syntax, task definitions, dependencies, and troubleshooting patterns. This ensures your AI assistant understands the basics before diving into more complex scenarios.</p>
<p><strong>PowerShell Modules Reference</strong> – Detailed guidance on using PowerShellBuild for module development workflows, including task patterns, build configurations, and testing integration.</p>
<p><strong>Build Types Reference</strong> – Practical patterns for .NET, Node.js, and Docker builds, providing real-world examples for different project types.</p>
<p><strong>Advanced Reference</strong> – Coverage of sophisticated topics like dynamic task generation, custom logging implementations, and CI/CD pipeline integration.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-can-ai-assistants-do-with-this-skill">What Can AI Assistants Do With This Skill?<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#what-can-ai-assistants-do-with-this-skill" class="hash-link" aria-label="Direct link to What Can AI Assistants Do With This Skill?" title="Direct link to What Can AI Assistants Do With This Skill?">​</a></h2>
<p>Once you've loaded the psake skill, your AI assistant can help with tasks like:</p>
<ul>
<li>Building complete psakefiles with integrated Pester testing frameworks</li>
<li>Establishing build configurations for .NET solutions and PowerShell modules</li>
<li>Implementing dynamic task generation from configuration files</li>
<li>Troubleshooting build failures and dependency issues</li>
<li>Integrating psake workflows into CI/CD pipelines</li>
<li>Creating custom logging mechanisms</li>
<li>Developing cross-platform build scripts</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started">Getting Started<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#getting-started" class="hash-link" aria-label="Direct link to Getting Started" title="Direct link to Getting Started">​</a></h2>
<p>The psake Agent Skill works with multiple AI platforms thanks to the open Agent Skills standard.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="using-with-claude">Using with Claude<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#using-with-claude" class="hash-link" aria-label="Direct link to Using with Claude" title="Direct link to Using with Claude">​</a></h3>
<ol>
<li>Visit the <a href="https://github.com/psake/psake-llm-tools" target="_blank" rel="noopener noreferrer">psake-llm-tools repository</a></li>
<li>Download the <code>psake.skill</code> file from the releases section</li>
<li>Upload it to Claude through the skills interface</li>
<li>Start building with AI-assisted psake expertise</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="using-with-github-copilot">Using with GitHub Copilot<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#using-with-github-copilot" class="hash-link" aria-label="Direct link to Using with GitHub Copilot" title="Direct link to Using with GitHub Copilot">​</a></h3>
<ol>
<li>Download the <code>psake.skill</code> file from the <a href="https://github.com/psake/psake-llm-tools" target="_blank" rel="noopener noreferrer">repository</a></li>
<li>Follow the <a href="https://code.visualstudio.com/docs/copilot/customization/agent-skills#_use-shared-skills" target="_blank" rel="noopener noreferrer">VS Code instructions for using shared skills</a></li>
<li>Configure the skill in your workspace or user settings</li>
<li>Access psake expertise directly in your editor</li>
</ol>
<p>The same skill file works across both platforms, making it easy to maintain consistent AI assistance regardless of which tool you prefer.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="open-standard-open-source">Open Standard, Open Source<a href="https://psake.netlify.app/blog/introducing-psake-agent-skill#open-standard-open-source" class="hash-link" aria-label="Direct link to Open Standard, Open Source" title="Direct link to Open Standard, Open Source">​</a></h2>
<p>By building on the <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer">Agent Skills</a> open standard, we ensure that psake expertise is portable across AI platforms. As more tools adopt this standard, your investment in configuring the psake skill will continue to pay dividends across your entire development toolchain.</p>
<p>The psake-llm-tools repository is open source and welcomes community contributions. If you have patterns, examples, or improvements that would benefit other developers using psake with AI assistants, we'd love to see your pull requests.</p>
<p>Whether you're new to psake or a seasoned automation expert, the psake Agent Skill can help streamline your workflow and provide intelligent guidance when you need it most. Give it a try and let us know what you think!</p>
<p>Check out the project at <a href="https://github.com/psake/psake-llm-tools" target="_blank" rel="noopener noreferrer">github.com/psake/psake-llm-tools</a>.</p>]]></content>
        <author>
            <name>Gilbert Sanchez</name>
            <uri>https://gilbertsanchez.com</uri>
        </author>
        <category label="Announcement" term="Announcement"/>
        <category label="psake" term="psake"/>
        <category label="PowerShell" term="PowerShell"/>
        <category label="Build Automation" term="Build Automation"/>
        <category label="CI/CD" term="CI/CD"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[New Releases & More!]]></title>
        <id>https://psake.netlify.app/blog/new-releases-and-more</id>
        <link href="https://psake.netlify.app/blog/new-releases-and-more"/>
        <updated>2025-08-03T23:38:05.100Z</updated>
        <summary type="html"><![CDATA[Discover the latest updates and releases in psake and PowerShellBuild that you won't want to miss!]]></summary>
        <content type="html"><![CDATA[<p>It's been a while since our last update, and we've got some exciting news to
share! In this post, we'll cover recent releases, welcome new team members, and
highlight the various initiatives we're working on to make psake even better.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="latest-versions">Latest Versions<a href="https://psake.netlify.app/blog/new-releases-and-more#latest-versions" class="hash-link" aria-label="Direct link to Latest Versions" title="Direct link to Latest Versions">​</a></h2>
<p>Since launching this documentation site, we haven't been great about announcing
new versions here. You could say we've been in stealth mode (though we're
definitely not that cool).</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="psake">psake<a href="https://psake.netlify.app/blog/new-releases-and-more#psake" class="hash-link" aria-label="Direct link to psake" title="Direct link to psake">​</a></h3>
<p>Back in October, we released psake 4.9.1, and since then we've merged several
pull requests, including some fantastic community contributions.</p>
<p>Check out the
<a href="https://github.com/psake/psake/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">psake Changelog</a> for all
the details.</p>
<p>The next release will introduce a new way to override the psake logging
mechanism. This will allow teams to integrate additional logging frameworks or
create improved CI/CD-specific workflows.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="powershellbuild">PowerShellBuild<a href="https://psake.netlify.app/blog/new-releases-and-more#powershellbuild" class="hash-link" aria-label="Direct link to PowerShellBuild" title="Direct link to PowerShellBuild">​</a></h3>
<p>Just a few days ago, we updated PowerShellBuild - our collection of common tasks
for psake and Invoke-Build - to support overriding task dependencies. We also
added localization support (more on that below). This brings us to version 0.7.3
as our latest release. Since version 0.6.2, we've seen 4.5k downloads, and we
hope to keep improving the project based on your feedback.</p>
<p>See the
<a href="https://github.com/psake/PowerShellBuild/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">PowerShellBuild Changelog</a>
for complete details.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="welcome-our-newest-team-members">Welcome Our Newest Team Members<a href="https://psake.netlify.app/blog/new-releases-and-more#welcome-our-newest-team-members" class="hash-link" aria-label="Direct link to Welcome Our Newest Team Members" title="Direct link to Welcome Our Newest Team Members">​</a></h2>
<p>You may have noticed them working on and reviewing code in our repositories, but
we'd like to formally welcome Joshua Hendricks and Trent Blackburn as new
members of the psake core team!</p>
<p><strong>Joshua</strong> is our resident
<a href="https://mvp.microsoft.com/MVP/profile/f98b4f3e-12fd-40de-bdce-1467f04d430d" target="_blank" rel="noopener noreferrer">MVP</a>
who's well-known for presenting at PowerShell + DevOps Global Summit on building
beautiful docs and sending notifications. He's a developer at Milestone Systems
where he maintains their PowerShell module.</p>
<p><strong>Trent</strong> currently develops PowerShell automations at Tesla, previously
specialized in PowerShell at Amazon, and has also presented at the annual
PowerShell + DevOps Global Summit.</p>
<p>Both bring incredible expertise to the team, and we're excited to have them
aboard! If you're interested in contributing to psake, please consider opening
an issue or submitting a pull request—we'd love to hear from you.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="expanding-global-accessibility-with-localization">Expanding Global Accessibility with Localization<a href="https://psake.netlify.app/blog/new-releases-and-more#expanding-global-accessibility-with-localization" class="hash-link" aria-label="Direct link to Expanding Global Accessibility with Localization" title="Direct link to Expanding Global Accessibility with Localization">​</a></h2>
<p>psake has long had the framework in place for supporting localization (l10n),
but until now has only been available in English. One of our key goals is making
psake as accessible as possible for users worldwide.</p>
<p>To make community contributions easier, we've set up a
<a href="http://crowdin.com/project/psake" target="_blank" rel="noopener noreferrer">Crowdin project</a> that enables straightforward
translation requests and suggestions.</p>
<p>With the Crowdin project now live, we have a streamlined pipeline for
introducing new localized versions. We'd love your help in making psake
available in more languages - please consider contributing translations!</p>]]></content>
        <author>
            <name>Gilbert Sanchez</name>
            <uri>https://gilbertsanchez.com</uri>
        </author>
        <category label="Announcement" term="Announcement"/>
        <category label="Release" term="Release"/>
        <category label="psake" term="psake"/>
        <category label="PowerShell" term="PowerShell"/>
        <category label="Build Automation" term="Build Automation"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[First Blog Post]]></title>
        <id>https://psake.netlify.app/blog/first-blog-post</id>
        <link href="https://psake.netlify.app/blog/first-blog-post"/>
        <updated>2024-10-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[First blog post! I'll keep this short and sweet. This post is to announce that]]></summary>
        <content type="html"><![CDATA[<p>First blog post! I'll keep this short and sweet. This post is to announce that
deployment of <a href="https://psake.dev/" target="_blank" rel="noopener noreferrer">psake.dev</a>!</p>
<p>This first iteration is composed of the original docs on the psake repository.
I'll be slowly reviewing all the docs and updating them to make it easier for
folks to get started.</p>
<p>In the near future, I'll be looking at more common CI/CD workflows and making
sure we have good examples. Have suggestions? PR's are welcome!</p>]]></content>
        <author>
            <name>Gilbert Sanchez</name>
            <uri>https://gilbertsanchez.com</uri>
        </author>
    </entry>
</feed>