Category Archives: PowerShell

Bringing Up PowerToys Command Not Found

PowerToys v0.77.0 made its debut earlier this week. A cool new facility also showed up — namely, Command Not Found. This nifty PowerShell module “detects an error thrown by a command and suggests a relevant winget package to install, if available.” You can see that capsule summary in the screencap shown above. What I have learned is that Command Not Found requires installation, but also carries some dependencies as well. Thus, Bringing up PowerToys “Command Not Found” tool involves a little more work than other new items added in the past. It’s all good, though…

Steps in Bringing Up PowerToys Command Not Found

As you can see in the intro graphic above, Command Not Found (CNF) must be manually installed before it does anything inside PowerShell. This is simply a matter of clicking the install button shown at mid-right in that image.

And there are a couple of buts (pre-requisites, really):
1. Right now, CNF works only with PowerShell v7.4.0 or higher. If it’s not installed and running, that must be fixed.
2. CNF also relies on a PowerShell Gallery module named WinGet Client Module (ID: Microsoft.Winget.Client). Interestingly winget does not install PS Gallery items, but there’s a button in the PowerToys console shown above that will handle this for you. After it’s installed, you can check the CNF install logs or use the Get-InstalledModule cmdlet (another PS Gallery item).

Bringing Up PowerToys Command Not Found.winget-client

The Get-InstalledModule cmdlet displays all PS Gallery items in your profile.

If you’ve not yet defined a PS profile, this installer will report its absence. But don’t worry: running the CNF installer creates one for you. Thus, once you get past the pre-requisities (dependencies) and install CNF, it’s almost ready to use. You’ll need to refresh the current PS profile so it brings CNF into the runtime environment for Windows Terminal/PowerShell. The easiest way to do that is to close Windows Terminal, then open it again. When you type an unknown command into the prompt, PS will offer to install it for you as long as it can find a valid source. That’s what you see in the next graphic:Bringing Up PowerToys Command Not Found.vimcheck

The vim utility is uninstalled on this PC, so CNF shows potential install strings. [Click image for full-sized view.]

Note: Demitrius Denelon used vim as his example in touting this new capability for PS users, so I had to find out what it was. As its name led me to suspect, it’s a modified version of the ancient “vi” text editor that you can run inside PS. Use winget show vim.vim to see more info.

Cool New Tool

This is a great new addition to PowerShell. This heightens my willingness to experiment with and learn about new cmdlets. Now I know if I bang on an uninstalled PS Gallery item, this facility will tell me how to install it so I can use it right away. Mmmm good!

 

Facebooklinkedin
Facebooklinkedin

Winget Show URLs Are Live

Wow! I got a great, unsolicited tip from Demitrius Nelon yesterday (he’s the winget team lead at MS, and a great communicator). It explains a way to grab the download for any package that winget can find. It came up in the context of updating the package named Microsoft.PowerShell, but it will work for any package by name. He informed me that if you run winget show, it will include an installer URL. I knew that. What I didn’t know and am jazzed to learn, is that you can CTRL-click the link and it will fire up your default browser and download it. That’s what “Winget Show URLs are live” means.

Because Winget Show URLs Are Live, Use Them!

This comes up in the context of PowerShell reasonably often for me, because I run PowerShell as my default shell inside Windows Terminal. Alas, when some new PowerShell updates pop up, winget can’t install them because their “install technology” changes. That’s because winget is inherently conservative when updating, and won’t make big changes on its own. Thus, for example, when an install technology change hits PowerShell, one must then download the new version from GitHub and run the installer to make the update.

Look near the bottom of the lead-in screengrab, which shows the output for “Winget show MIcrosoft.PowerShell.” It’s the section that starts with “Installer:” at left. 2 lines down the label reads “Installer Url” with the actual github download link to its right. If you hold the CTRL key down and click on that URL, download will commence.

This is about as handy as updates get when winget won’t do them for you automatically. Shoot! It makes a pretty good alternative to winget install <package-name>, too. Thanks, Demetrius: this tip makes a snazzy stocking stuffer. Happy holidays!

Facebooklinkedin
Facebooklinkedin

Recurring PowerShell Update Issue Easily Fixed

Deja vu! With the introduction of version 7.4.0, MS once again changed the PowerShell (PS) installer. That means Winget won’t update PS directly; one must visit the GitHub PS page and grab a new installer from there. Afterward, as shown in the lead-in graphic, old(er) version(s) of PS still show up when WinGet upgrade is run. Fortunately this recurring PowerShell update issue is easily fixed. Let me explain…

Fixing This Recurring PowerShell Update Issue

Take a look at the lead-in graphic. It shows a single upgrade to PowerShell, from version 7.3.10 to 7.4.0 is available. But when I try to use winget to do the job, it reports a change in installer methods and won’t handle this task. This requires a trip to GitHub (the whole process is described in my November 17 post) to grab and install PS using its Microsoft Installer (.MSI) file instead.

But there’s a catch: as you can see in the Apps portion of the lead-in graphic, the PS installer does NOT clean up older versions. Thus, not just one, but two older versions of PS show up therein — namely 7.3.10 and a 10/25/2023 Preview version. Winget will report that the 7.3.10 version needs an update because 7.4.0 is available. Thus, you need to uninstall that version to stop this warning.

So that’s just what I did. And because I’m not using the PS Preview any more, either, I uninstalled it too. Problem solved. But here’s a request to the PowerShell team: please add a check for older stable versions (e.g. 7.3.10 in this case) and offer to uninstall it during the new stable version install process. It would make life ever so much easier, thanks!

Fingers crossed that they agree. I’ll be sure to copy this to the winget and PowerShell teams leads when I tweet this item out later this morning, too. That said, the new PS window notification does instruct users to “uninstall the package and install the newer version” so maybe they’re not interested in tackling this job. We’ll see…

Recurring PowerShell Update Issue.notification

I can’t say MS doesn’t warn users. I can say I didn’t see it right away, though…

Facebooklinkedin
Facebooklinkedin

PowerShell Out-GridView Grants Output Insights

OK, then. I’m taking Matt Hester’s fabulous Learning PowerShell course over at LinkedIn. Right now, I’m into the third of three modules. I have to say: it’s been great! Yesterday, among lots of other incredibly useful nuggets, I learned about the Out-GridView cmdlet. To say that PowerShell Out-Gridview grants output insights for most cmdlets is like saying “The Grand Canyon is Big.” But that makes it no less true or interesting — to me, at least. Let me explain…

What PowerShell Out-Gridview Grants Output Insights Means

PowerShell cmdlets manipulate data objects. These have named properties. When you output them, you can see the values associated with all properties for an object instance (rows). You can also see the values associated with individual properties for all instances (columns).

Simply put, what Out-Gridview does is to grab the values associated with each instance’s properties and throw them up in a window like the one you see in the lead-in graphic. As you can see in the top line of that window this shows the results of the get-service cmdlet, from which the resulting objects’ Name, Status and RequiredServices property values are all shown. This is cool and helpful all by itself, but there’s more: a LOT more.

Working the GridView Window

Let’s call the windowed output from Out-Gridview a “GridView Window.” It’s actually an output from the Interactive Script Editor (ISE) that’s part of the overall PowerShell runtime environment.

In this GridView Window, you can click on any column head therein to sort the data by the values in that column. By default it comes sorted on whatever shows up in column 1 (aka “alphabetical order, by Name”). But you can also sort on Status, or RequiredServices as well.

Wait! There’s still more:

  • You can add all kinds of filters to the output shown in the Window
  • Types of filters include
    • contains (string or value partial matching anywhere)
    • does not contain (string or value absent)
    • starts with (initial string character matching)
    • equals (string or value exact match)
    • does not equal (string or value not matched or equal)
    • ends with (ending string character matching)
    • is empty (property has no value defined or is null)
    • is not empty (property has a value defined or is not null)
  • You can add as many filters as you like, change them as you go, and the GridView Window’s contents change dynamically to keep up
  • Data shows up as you type

Overall, this is a great way to examine data from cmdlet outputs in PowerShell. It means you don’t have to scroll up and down in the command window, nor do you have to save the data to a file and open it using your favorite editor. The gridview data is, however, evanescent (when you close the window, the data is gone). It doesn’t do away with piping output into files: it’s just a (temporary) alternative, but a darned good one!

Facebooklinkedin
Facebooklinkedin

Learning to Hurdle Terminal Chat Gotchas

When I was a kid we lived in Kendall Park, NJ in 1962 and 1963. The barbershop where my Mom took me for haircuts was interesting. It was long and narrow and lined with mirrors on both sides. That created what I have forever since called “the hall of mirrors” effect. There a poor man’s infinity is born as those parallel mirrors reflect each other forever and ever. I remembered that hall as I read the MS November 17 Windows Command Line blog Terminal Chat in Windows Terminal Canary. Since it came out, I’ve been figuring out how to hurdle Terminal Chat gotchas in similar wise. Let me explain…

Pre-reqs Precede Hurdle Terminal Chat Gotchas

If you look at the lead-in graphic (it comes from the afore-linked Command Line blog, a personal fave) it shows a “Welcome to Terminal Chat” message inside a PowerShell/Windows Terminal session. I’ve been trying to get to the point where I can bring that message up myself on a test or production PC, but I’ve yet to surmount the hurdles in my way. Let me enumerate them:

1. In Windows Terminal team lead Chris Nguyen’s words “Terminal Chat only supports Azure OpenAI Service for now.” That means one needs an Azure OpenAI Service endpoint and key.

2. To obtain said endpoint and key, one must create and deploy an Azure OpenAI service resource.

3. To create and deploy an Azure OpenAI service resource, one needs an Azure OPen AI Service enabled Azure account. This requires setting up monthly billling for consumption of Azure resources with an OpenAI rider added. (For pricing info, start with Plan to manage costs for Azure OpenAI Service for the OpenAI piece, then check out Understand Cost Management Data for the underlying Azure piece). It’s daunting!

Only when you have all the pieces in place, and then create and deploy a valid Azure OpenAI service resource, can you install and use Terminal Chat. I’m not there yet. In fact, I’m thinking hard whether or not minimum monthly charges of at least US$50-150 are commensurate with the joy of using Terminal Chat.

Enough … or Too Much?

This subtitle comes courtesy of William Blake’s Proverbs of Heaven and Hell. I’m inclined to bow more to the infernal side of that dichotomy when it comes to putting all the pieces in place. All I wanted to do, really, was to see what kind of advice Terminal Chat could dispense at the command line. I’ve already got Copilot ready to advise me on PowerShell and Command Prompt input with some basic ability to plop it onto a command line.

Why so many hoops and hurdles? I’m sure there’s an answer. I’m reaching out to the author of the blog post to see what I can learn. Should be interesting… Stay tuned!

Facebooklinkedin
Facebooklinkedin

PowerShell Install Method Changes

When a new version of PowerShell comes along, it’s always interesting to see whether or not winget can field that update correctly. This time around — with version 7.4.0 — it reports a “different install technology” as you can see in the lead-in graphic. When the PowerShell install method changes, winget won’t handle the update without an uninstall/reinstall maneuver. So I CTRL-clicked the link shown above the WT pane (from the GitHub link that’s helpfully provided) and used the MSI file to update PowerShell instead.

When PowerShell Install Method Changes, Use GitHub

That Microsoft Installer File is under 65MB in size. On my test PC, that takes less than 10 seconds to download. That opens the “SuperHero” PS installer (see next screencap), after which install takes half-a-dozen mouse-clicks to configure as I like it. Another minute or so, and the job is done. MS is doing better at getting new versions of PowerShell to circulate. I like it!

PowerShell Install Method Changes.installer

The only time you actually see the PS superhero avatar is when the installer runs.

Watching Out for Certain Winget Shenanigans

So, I’m learning to be wary of three specific installs when using winget inside Windows Terminal and PowerShell — namely:

  • winget itself: if the tool doing the updating gets updated, interesting things can — and do — sometimes happen. This is another case when I’ve sometimes seen the “Cancelled” error message that really reports a loss of interaction with the updater (the update actually succeeds, but can’t report success).
  • Windows Terminal: same principal as before, write large when the entire Windows Terminal runtime has to change. When this occurs, WT usually writes a message into the active terminal window to say “Restart the window/session to run the changed version.” Good -oh!
  • PowerShell: and again, if PowerShell is updating itself it must be ready to handle those changes. As we see in this particular case, something has changed that requires an uninstall/reinstall. My preference: using the GitHub installer instead. Easy-peasey.

And that, dear Readers, is how I often keep myself entertained, here in Windows-World. Great fun…

Facebooklinkedin
Facebooklinkedin

PowerShell Update Twofer Strikes

Whoa! No sooner had I updated PowerShell from version 7.3.9 to 7.3.10 than came the 7.4.0 in-window notification. You can see all this in the lead-in graphic, as a rare but not unheard-of PowerShell Update twofer strikes my local Windows 10 and 11 desktops.

When PowerShell Update Twofer Strikes, Keep Going

I had to chuckle after I patted myself on the back for updating PowerShell inside Command Prompt (the best way to avoid odd update behavior that can occur when PowerShell attempts to update itself). The very next thing I saw in a new PS window was the “black text against white background” notification shown in the lead-in graphic.

That notification reads:

A new PowerShell stable version is available: v7.4.0
Upgrade now, or check out the release page at
https://aka.ms/PowerShell-Release?tag-v7.4.0

That URL links to the named release page at GitHub, where one can download an installer that matches OS, architecture and so forth. I ran the file named PowerShell-7.4.0-win-x64.msi. It worked like a charm!

And unlike other, earlier attempts at running the MSI installer to move up a PowerShell version, this one successfully cleaned out the just-updated 7.3.10 version without difficulties. Looks like the PowerShell team is getting its act together…

This does raise the question: when will winget update start targeting v7.4.0 instead of v7.3.10? Looks like that’s already taken care of. Look at this output from winget upgrade from a Windows 11 test machine: it literally got fixed while I was writing this blog post. LOL!

PowerShell Update Twofer Strikes.winget-check

Winget now knows it needs to target v7.4.0 as the current PS version. [Click image for full-sized view.]

As you can see, winget upgrade is not recommending 7.3.10 anymore. Now it’s aware of, and ready to upgrade to, 7.4.0. Good-oh!

 

Facebooklinkedin
Facebooklinkedin

Happy 17th Birthday PowerShell

In reading about the run-up to the MS Ignite conference — getting underway in Seattle — I learned this morning that November 14 is the anniversary date for PowerShell. That’s why I expressed the sentiment in the title — namely “Happy 17th Birthday PowerShell!”

Why Say: Happy 17th Birthday PowerShell?

Since its inception in 2006, PowerShell (PS) has slowly and steadily taken over the lead role at the command line for Windows admins and enthusiasts. Probably more importantly, PS became open-source and cross-platform in August 2016 with the debut of PowerShell Core. According to Wikipedia, as of Windows 10 Build 14971 (November 2016) PS took over the default role as primary command line shell for Windows.

What makes PS worth getting to know? Unlike the Command Prompt (which traces all the way back to DOS days) it’s a fully featured runtime environment. Thus it handles task automation and configuration management. And it does so in an environment that’s got most of the capabilities of a full-blown programming environment. Shoot: you can create interactive scripts using PS, and you can embed PS within other applications. Then, too, PS supports an extensive library of built-in cmdlets (“commandlets”) to support all kinds of specialized, focused operations. It also works both locally and remotely. IMO, it’s more fun than a barrel of monkeys!

The Journey to PS Nerdvana

I’ve been working with PS increasingly since it initially became available around the same time that Windows Vista appeared. But it’s only in the last 3-4 years I’ve really started working with it more extensively. It is very much the case that the more I’ve used it, the more I’ve come to like PowerShell.

Indeed, I’ve got a TekkiGurus story coming sometime soon that provides a PS script to show how I customize Windows Terminal and PS on my PCs. (I’ll link to it when it goes live.) It includes:

  • Download, installing and configuring OhMyPosh, along with a Nerd Font is uses for prompt customization in PowerShell
  • Download, install, and add a ColorTool to the PS environment
  • Install and use Winfetch to show off current WT/PS look and feel

So again: happy birthday, PowerShell. You’ve made my job in setting up and taking care of Windows images and installations much, much easier. Thanks a bunch!

Facebooklinkedin
Facebooklinkedin

Sussing Out Doubled-Up PowerShell

Here’s an interesting one. After running winget upgrade on Friday afternoon, I noticed something interesting. Even though I’d already upgraded that particular PC to PowerShell version 7.3.9, it still showed a version of 7.3.8 in need of an upgrade. Immediately, I started sussing out doubled-up PowerShell. As you can see in the lead-in graphic it was a case of “parallel versions.” Even though 7.3.9.0 is clearly installed (PowerShell 7-x64), so is 7.3.8 (PowerShell 7.3.8.0).

After Sussing Out Doubled-Up PowerShell,
Bye-Bye 7.3.8!

Turns out that 7.3.9 has some install changes. That means winget won’t simply upgrade the software. One must run winget uninstall, then winget install to do this particular round of the PowerShell upgrade dance. You can see this at work in the next screencap, which shows:

(a) notification from PowerShell that a new stable release is ready for download (white background against black text up top)
(b) notification from winget that “install technology is different” for new PowerShell release, so uninstall/install maneuver is needed

Sussing Out Doubled-Up PowerShell.winget-info

PowerShell is pretty clear that winget upgrade can’t handle this without extra maneuvers.

Thus, one approach here would be to run this sequence of wingets:

winget uninstall Microsoft.Powershell
winget install Microsoft.Powershell

The first removes the old version and the second installs the current (new) one. Easy-peasey, right?

Take the Long Way Home

The way I see things, there’s another choice when this kind of thing happens. The PowerShell installer file at GitHub (or the equivalent link shown at the top of the screencap: https://aka.ms/PowerShell-Release?tag=v7.3.9) not only installs the new PowerShell version, it also removes the old one. So I went ahead and ran PowerShell-7.3.9-win-x64.msi on the same machine where I captured the preceding screencap. I closed PS manually, instead of having the installer do it. Then I ran winget upgrade again. And sure enough, the doubled-up version once again appears!

It gets more interesting. I ran winget uninstall MIcrosoft.PowerShell –version 7.3.9.0 to remove the older version. This time, I let the (un)installer attempt to close PowerShell. It failed, and showed an “uninstallation abandoned error” (see next screencap).

Winget drops the ball trying to uninstall the newer version from inside that version! [Click image for full-sized view.]

Go with What Works

OK, I want to run the new version. But I also want to remove the older one. That cycles me back to the original screecap at the head of this blog post. If you go to Settings → Apps → Installed apps, you can easily excise older PowerShell versions from there. So that’s what I did. And presto: no more winget notifications that 7.3.8.0 needs an upgrade to 7.3.9.0.

One more thing: on another test machine (one running a preview version of PowerShell) I successfully used winget to uninstall 7.3.8.0 and then follow up with a successful 7.3.9.0 install. I think this worked because PowerShell 7.3.9.0 didn’t attempt to uninstall or install itself. That said, I did also have to manually install a new profile so I could make 7.3.9.0 my default PS selection afterwards. It’s always something, right?

Note added November 1: Do It From Command Prompt

On another test PC just now, I opened Windows Terminal. Then after opening a Command Prompt tab, I closed the open (default) PowerShell 7.3.8.0 tab. After that I was able to use winget to uninstall the older PS version and install the new one. This required no  new profile shenanigans. It’s my recommended approach until the PS team gets this fixed (I got confirmation from an MS contact yesterday that yes, this is a known thing and they’re working on it).

Facebooklinkedin
Facebooklinkedin

Syntax Errors Derail PowerShell JSON Edits

I’ve just completed a fascinating project for TekkiGurus: a five-part series on customizing and extending Windows Terminal. For the 5th and final part, I decided to build PowerShell scripting that would handle such customizations I use as don’t fall under the settings.json umbrella. Ironically, one of those tasks involved editing that very file to change the default font. That’s when I saw syntax erors derail PowerShell JSON edits, as shown in the lead-in graphic. Let me explain…

How Did Syntax Errors Derail PowerShell JSON Edits?

I started off my project by asking Copilot to present me with some initial PowerShell commands to handle the following tasks:

1. Download, install and set up Jan DeDobbeleer’s outstanding OhMyPosh prompt customization tool. This turns out to be a more complex task than it might seem, because it requires downloading, unzipping and copying Nerd Fonts into C:\Windows\Fonts, adding an invocation to the PowerShell Profile script, dealing with OhMyPosh, and then selecting a Nerd Font as the WT default.

2. Download, install and add the colortool executable to a default Windows path. Colortool is a GitHub project that provides information about Windows Terminal color assignments for text and text backgrounds. This one was pretty straightforward.

3. Install the winfetch utility that shows WT color schemes, system info, text colors, and a few other odds’n’ends. This required only one line of code, so easy-peasey.

The error showed up at the end of my PS sequence for the OhMyPosh tasks (I’ll refer to this as OMP from now on). Seems that Copilot’s code included two errors that it took me some time to find. First, the object sequence for the default font that OMP required turned out to be the string “.profiles.defaults.font.face” rather than the truncated version that Copilot provided (“.profiles.defaults.font”). Also, it used an alias for the default Nerd Font I chose rather than its full name — that is “CaskaydiaCove NF” instead of “CaskaydiaCove Nerd Font”. Interestingly, this alias worked in Windows 10, but not in Windows 11 (there, only the full name would do).

Errors Found Are Easily Fixed

It took me a while to figure this out because I couldn’t find exact documentation to match my problems precisely. I figured out the object sequence by examining the json.settings file from another Windows PC that had the default already set and following the sequence of the object name hierarchy in use in that file. In other words, I noticed a face property in that file that was missing from my rewritten json.settings file. No wonder it wouldn’t save.

Once I made that change, I got another error message (from Windows 11) that reported it couldn’t find a font named “CaskaydiaCove NF.” I so looked in C:\Windows\Fonts, and sure enough the font name in Explorer is actually “CaskaydiaCove Nerd Font.” And again, once I made that change things worked properly.

As the old saying goes: “It’s always easy when you know how.” It took me a while to get to the last detail in the “how” part, but indeed, it was dead easy after that. Things go that way a lot in Windows-World, especially when writing code or command line instructions. I’m just glad it’s working now!

One More Thing: Replacing Munged JSON File

On the machine where I made the object reference error, settings.json remained munged. It kept throwing errors each time I started up WT or PowerShell. So I  researched the topic and learned that if you open settings.json in a text editor, then delete the whole thing, WT will rebuild that file from programmed defaults when an empty file gets saved. That put my WT and PowerShell environments back to rights, and I was then able to get the corrected script to run to completion on that PC.

I’ll observe that if you’re going to edit settings.json in PowerShell on a Windows PC, it’s a good idea to have a backup at hand to replace that file. I’m learning that it’s kind of like working on the registry, where changes can have even more serious and dire side effects. Cheers!

Facebooklinkedin
Facebooklinkedin