<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carl C</title>
    <description>The latest articles on DEV Community by Carl C (@awsomesawce).</description>
    <link>https://dev.to/awsomesawce</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F461375%2F98b2b6c1-1a78-4d29-8f48-f427a149c481.jpeg</url>
      <title>DEV Community: Carl C</title>
      <link>https://dev.to/awsomesawce</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/awsomesawce"/>
    <language>en</language>
    <item>
      <title>PowerShell completions installed by Scoop</title>
      <dc:creator>Carl C</dc:creator>
      <pubDate>Thu, 10 Sep 2026 20:05:58 +0000</pubDate>
      <link>https://dev.to/awsomesawce/powershell-completions-installed-by-scoop-1pnd</link>
      <guid>https://dev.to/awsomesawce/powershell-completions-installed-by-scoop-1pnd</guid>
      <description>&lt;h2&gt;
  
  
  Finding Scoop's Hidden Completion Scripts with PowerShell
&lt;/h2&gt;

&lt;p&gt;I like &lt;a href="https://scoop.sh/" rel="noopener noreferrer"&gt;Scoop&lt;/a&gt;. It's a clean, no-admin-required package manager for Windows, and it stays out of your way. One thing I ran into, though: some apps ship a tab-completion script alongside the binary, and there's currently no built-in way to know it's there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The itch
&lt;/h2&gt;

&lt;p&gt;Some Scoop packages bundle a completion script alongside the binary. Once installed, that script just sits on disk. There's no &lt;code&gt;scoop completions&lt;/code&gt; subcommand and nothing in &lt;code&gt;scoop info&lt;/code&gt; that points to it — reasonable, since Scoop's job is installing packages, not indexing every file inside them. But it does mean that unless you already know to go looking, you won't stumble onto it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where they actually live
&lt;/h2&gt;

&lt;p&gt;Scoop installs every app under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="n"&gt;\scoop\apps\&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;app-name&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;\&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a &lt;code&gt;current&lt;/code&gt; folder symlinked to whichever version is active. Completion scripts that ship with a package end up somewhere inside that per-app tree, and by convention they're named with a leading underscore — &lt;code&gt;_appname.ps1&lt;/code&gt; — the same convention PowerShell's own completion ecosystem uses.&lt;/p&gt;

&lt;p&gt;Once I knew the naming pattern and roughly where to look, the rest was a filesystem search problem, not a Scoop problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking this against prior art
&lt;/h2&gt;

&lt;p&gt;Before writing this up, I looked around for existing solutions. The "scoop completion" PowerShell modules that already exist solve a &lt;em&gt;different&lt;/em&gt; problem: they add tab-completion for the &lt;code&gt;scoop&lt;/code&gt; command itself (&lt;code&gt;scoop ins&amp;lt;Tab&amp;gt;&lt;/code&gt; cycling to &lt;code&gt;install&lt;/code&gt;), not for discovering completion scripts bundled with the apps Scoop installs.&lt;/p&gt;

&lt;p&gt;There's also a &lt;a href="https://github.com/ScoopInstaller/Scoop/discussions/4803" rel="noopener noreferrer"&gt;2022 GitHub Discussion&lt;/a&gt; on the Scoop repo where someone asks this same question — how to set up completions for an app they were packaging for Scoop. The maintainers' answer, paraphrased: Scoop's job is extracting the archive and adding the bin path, and it doesn't do anything with Windows completions beyond that, so there's no centralized place completion files land — users source the files themselves. A linked issue floated adding first-class completion support to Scoop core (a &lt;code&gt;~\scoop\completions&lt;/code&gt; folder with per-shell subfolders, populated at install time), but that's a design change on Scoop's side, and it doesn't look like it shipped.&lt;/p&gt;

&lt;p&gt;That lines up with what I found: a real gap, reasonable given Scoop's scope, and one I haven't seen a user-side tool address yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Get-ScoopCompletions&lt;/code&gt; walks the apps directory looking for that pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Get-ScoopCompletions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CmdletBinding&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="s2"&gt;\scoop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Write-Warning&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Scoop home not found: &lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nv"&gt;$appsRoot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps"&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;Get-ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$appsRoot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Filter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"_*.ps1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Recurse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Depth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;silentlycontinue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few deliberate choices here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-Filter&lt;/code&gt; over &lt;code&gt;-Include&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;-Filter&lt;/code&gt; is handled by the provider itself rather than PowerShell's pipeline, so it's noticeably faster on a directory tree with hundreds of app folders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-Depth 5&lt;/code&gt;&lt;/strong&gt; — bounds the recursion instead of walking arbitrarily deep. Scoop's structure is predictable enough that this is generous headroom without being unbounded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-ea silentlycontinue&lt;/code&gt;&lt;/strong&gt; — apps directories can have permission quirks or half-installed packages; I'd rather skip those than have the whole scan die on one bad folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing I'm still going back and forth on: Scoop's &lt;code&gt;current&lt;/code&gt; symlink means the same completion script is technically reachable through two paths — the versioned folder and the &lt;code&gt;current&lt;/code&gt; alias. Right now &lt;code&gt;Get-ScoopCompletions&lt;/code&gt; returns both. I could filter with &lt;code&gt;Where-Object { $null -eq $_.Directory.LinkType }&lt;/code&gt; to only keep the "real" versioned path and drop the symlinked duplicate, but I haven't decided if that's worth the extra complexity yet.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Enable-ScoopCompletions&lt;/code&gt; then just dot-sources whatever comes back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Enable-ScoopCompletions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CmdletBinding&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="s2"&gt;\scoop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nv"&gt;$scripts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-ScoopCompletions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ScoopHome&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ScoopHome&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$scripts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Write-Verbose&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"No Scoop completion scripts found."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="kr"&gt;foreach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$scripts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$script&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FullName&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;Write-Verbose&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Scoop completions loaded."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop &lt;code&gt;Enable-ScoopCompletions&lt;/code&gt; in your &lt;code&gt;$PROFILE&lt;/code&gt;, and every completion script that came bundled with your Scoop apps gets wired up automatically — no more hunting through app folders by hand after installing something new.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who actually ships these
&lt;/h2&gt;

&lt;p&gt;A handful of everyday CLI tools are exactly why this was worth automating. &lt;code&gt;bat&lt;/code&gt;, &lt;code&gt;fd&lt;/code&gt;, &lt;code&gt;lsd&lt;/code&gt;, and &lt;code&gt;rg&lt;/code&gt; (ripgrep) all install a &lt;code&gt;complete&lt;/code&gt; directory alongside the binary, with a &lt;code&gt;_*.ps1&lt;/code&gt; script sitting right inside it — precisely the pattern &lt;code&gt;Get-ScoopCompletions&lt;/code&gt; is looking for.&lt;/p&gt;

&lt;p&gt;Not every tool works this way, though. Some don't ship a static completion script at all — instead they expose a flag that &lt;em&gt;generates&lt;/em&gt; one on demand (something like &lt;code&gt;tool.exe --generate-completion powershell&lt;/code&gt; or &lt;code&gt;tool.exe completions pwsh&lt;/code&gt;, naming varies by tool). For those, you'd capture the output and dot-source it, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;tool.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;generate-completion&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;powershell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invoke-Expression&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a different problem than &lt;code&gt;Get-ScoopCompletions&lt;/code&gt; solves — it's discovery for scripts that already exist on disk, not generation on the fly — but it's worth knowing both patterns exist if you're chasing down completions for a tool that isn't in the &lt;code&gt;bat&lt;/code&gt;/&lt;code&gt;fd&lt;/code&gt;/&lt;code&gt;lsd&lt;/code&gt;/&lt;code&gt;rg&lt;/code&gt; camp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why filesystem discovery over parsing manifests
&lt;/h2&gt;

&lt;p&gt;Scoop tracks installed apps via JSON manifests, so an alternative approach would be reading each app's manifest and checking for a declared completion script field. I went with filesystem discovery instead, for a simple reason: not every completion script is guaranteed to be declared consistently in the manifest, but the &lt;code&gt;_*.ps1&lt;/code&gt; naming convention on disk is. Searching the filesystem finds what's actually there rather than trusting what's &lt;em&gt;supposed&lt;/em&gt; to be there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Import-Module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ScoopCompletions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Enable-ScoopCompletions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it — the completions Scoop already gave you, actually usable.&lt;/p&gt;

&lt;p&gt;I have included this module as a part of my powershell configuration repository &lt;a href="https://github.com/awsomesawce/Powershell-Config/tree/main/MyModules/ScoopCompletions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>shell</category>
      <category>ux</category>
      <category>automation</category>
      <category>completions</category>
    </item>
    <item>
      <title>Piping arbitrary Powershell variables into NodeJS</title>
      <dc:creator>Carl C</dc:creator>
      <pubDate>Fri, 20 Aug 2021 22:18:49 +0000</pubDate>
      <link>https://dev.to/awsomesawce/piping-arbitrary-powershell-variables-into-nodejs-45oe</link>
      <guid>https://dev.to/awsomesawce/piping-arbitrary-powershell-variables-into-nodejs-45oe</guid>
      <description>&lt;p&gt;So yea I just learned how to pipe a powershell variable into a nodejs script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Carl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;➜&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;my-pwsh-deps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'./README.md'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Carl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;➜&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;my-pwsh-deps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sh"&gt;@"
&amp;gt;&amp;gt; const path = require('path')
&amp;gt;&amp;gt; let s = &lt;/span&gt;&lt;span class="se"&gt;``&lt;/span&gt;&lt;span class="nv"&gt;$str&lt;/span&gt;&lt;span class="se"&gt;``&lt;/span&gt;&lt;span class="sh"&gt;
&amp;gt;&amp;gt; console.log(path.parse(path.resolve(s)))
&amp;gt;&amp;gt; "@&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;root:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\\'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;dir:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\\Users\\Carl\\gitstuff\\my-pwsh-deps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="kr"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'README.md'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ext:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.md'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'README'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's kind of similar to when you see a slice of &lt;code&gt;perl&lt;/code&gt; code inside a &lt;code&gt;bash&lt;/code&gt; script.  Pretty cool.&lt;/p&gt;

</description>
      <category>powershell</category>
      <category>shell</category>
      <category>justfoundout</category>
    </item>
    <item>
      <title>System.IO.Path Class Methods in Powershell</title>
      <dc:creator>Carl C</dc:creator>
      <pubDate>Fri, 20 Aug 2021 00:57:17 +0000</pubDate>
      <link>https://dev.to/awsomesawce/system-io-path-class-methods-in-powershell-1093</link>
      <guid>https://dev.to/awsomesawce/system-io-path-class-methods-in-powershell-1093</guid>
      <description>&lt;p&gt;There are a lot of great path-related functions and methods available to the &lt;code&gt;[System.IO.Path]&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Here is an example for writing a small function that changes the value of &lt;code&gt;$env:PSModulePath&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Set-PSModulePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;#
&lt;/span&gt;&lt;span class="cs"&gt;.Synopsis&lt;/span&gt;&lt;span class="cm"&gt;
Set-PSModulePath [path]
&lt;/span&gt;&lt;span class="cs"&gt;.Description&lt;/span&gt;&lt;span class="cm"&gt;
Adjust the PSModulePath env variable to your liking
&lt;/span&gt;&lt;span class="cs"&gt;.Notes&lt;/span&gt;&lt;span class="cm"&gt;
Add integration with other modules so they can add their own dir
to the psmodulepath!
#&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mandatory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$Path&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Cross-platform path-separator value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# On Windows it is `;`, on Unix-like systems it is `:`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$sep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.IO.Path&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;PathSeparator&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ForegroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Yellow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Adjusting PSModulePath
Adding &lt;/span&gt;&lt;span class="nv"&gt;$Path&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;env:PSModulePath"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Write-Verbose&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Setting old path to &lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;oldPSModulePath"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$oldPSModulePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;PSModulePath&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;PSModulePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;${Path}${sep}$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;PSModulePath&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-fore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Yellow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;env:PSModulePath is now &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;PSModulePath&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Write-Error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You did not write a Path"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>powershell</category>
      <category>crossplatform</category>
      <category>quickcoding</category>
    </item>
  </channel>
</rss>
