Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
September 30, 2025

September 2025 PowerShell Roundup

In this issue:

  • PoshBytes
  • PowerShell v2
    • Windows Client
    • Windows Server
  • Invoke-PSRunSelector
  • PSConfEU MiniCon 2025
  • Scripting Challenge
  • Summary

Well, this month flew by! I think we covered a lot of interesting content this month. I hope you continue to find ways to incorporate PowerShell into your daily work and reap the benefits. If there is a topic or concept that you think would help you in your work, please let me know.

In the mean time, here is a potpourri of PowerShell content that you might find interesting as well as a new scripting challenge.

PoshBytes

poshbytes

Some of you may recognize PowerShell MVP Matthew Dowst. He is the author of Practical Automation with PowerShell and writes a weekly PowerShell roundup. His latest contribution is a series of short videos called PoshBytes. These are very short videos, typically around 2 minutes, that cover a very specific PowerShell concept or technique. I highly recommend checking them out.

PowerShell v2

If you have been following the PowerShell news lately, you may have read the PowerShell v2 will no longer be enabled or offered on Windows 11 and Windows Server 2025. There is no reason you should every need this feature. If for some reason you have code that only works in PowerShell v2, you should be updating that code to work in the current version of PowerShell.

It is very easy to check if PowerShell v2 is enabled on desktops and servers. You may already have tools like Group Policy that can help you manage this feature. But if you need to handle this on your own, here are a few tips.

Windows Client

On Windows 10 and Windows 11, you can check if PowerShell v2 is enabled by running the following command in an elevated PowerShell session:

PS C:\> Get-WindowsOptionalFeature -online -FeatureName MicrosoftWindowsPowerShellV2

FeatureName      : MicrosoftWindowsPowerShellV2
DisplayName      : Windows PowerShell 2.0 Engine
Description      : Adds or Removes Windows PowerShell 2.0 Engine
RestartRequired  : Possible
State            : Enabled
CustomProperties :

If it is enabled, it is simple to disable.

PS C:\> Disable-WindowsOptionalFeature -online -FeatureName MicrosoftWindowsPowerShellV2 -NoRestart

Path          :
Online        : True
RestartNeeded : False

Unfortunately, Disable-WindowsOptionalFeature does not support the -WhatIf parameter, so if you are building a PowerShell script around it, you will need to add your own WhatIf logic.

Windows Server

On server platforms, you can use the Get-WindowsFeature cmdlet to check if PowerShell v2 is enabled.

Get-WindowsFeature -Name PowerShell-V2
Get PowerShellv2 Feature
figure 1

The feature object has a property called Installed that will be $True if the feature is enabled. This makes it easy to test and disable if needed.

Get-WindowsFeature -Name PowerShell-V2 | Where Installed | Remove-WindowsFeature
Remove PowerShellv2 Feature
figure 2

If you can do it for one, you can do it for many.

$computers = "SRV1","SRV2","DOM1"
$cred = Get-Credential company\artd
Invoke-Command {
    Get-WindowsFeature -Name PowerShell-V2 | Where Installed | Remove-WindowsFeature
} -ComputerName $computers -Credential $cred
Multiple removals
figure 3

Invoke-PSRunSelector

In the past, I've demonstrated techniques for creating an interactive object selector using the pwshSpectreConsole module. I've also written in the past about the PowerShellRun module. While PowerShellRun is primarily designed as a launcher or dashboard, you can also use it to create an interactive selector with Invoke-PSRunSelector.

The concept is to pipe your collection of objects to the command.

Selecting numbers
figure 4

Use the arrow keys to navigate the list. Pressing Enter will write the selected object to the pipeline. Use Esc to cancel.

Of course, you are likely to want to select more complex objects as well as multiple objects. Use the -DescriptionProperty parameter to specify the property to display. Use the -MultiSelection switch to allow multiple selections.

dir c:\work\*.ps1 | Invoke-PSRunSelector -DescriptionProperty FullName -MultiSelection
Multiple object selection
figure 5

Use the Tab key to make your selections which are then written to the pipeline.

PS C:\> dir c:\work\*.ps1 | Invoke-PSRunSelector -DescriptionProperty FullName -MultiSelection

    Directory: C:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           7/29/2025  3:04 PM          27755 demo.ps1
-a---           3/23/2023  6:24 PM          27698 demo2.ps1
-a---           7/29/2025  3:05 PM          25857 demo3.ps1

You can customize the appearance with a customized SelectorOption object.

$PSRunOption = [PowerShellRun.SelectorOption]::new()
#add a custom prompt
$PSRunOption.Prompt = "$($PSStyle.Italic)Select one or more files from the list$($PSStyle.Reset)"
#use a backspace to exit without selecting
$PSRunOption.QuitWithBackspaceOnEmptyQuery = $True
#adjust colors
$PSRunOption.theme.PromptForegroundColor = 'BrightGreen'
$pSRunOption.theme.SearchBarBorderForegroundColor = 'BrightYellow'

The command's -Expression parameter is interesting. It is a cross-between splatting and a script block. You can use this to dynamically display objects as you scroll through the list.

$sb = {
    @{
        Name        = $_.Name
        Description = '[{0}] {1}' -f $_.Mode, $_.LastWriteTime
        Preview     = Get-Item $_ | Out-String
    }
}
Get-ChildItem c:\work -File |
Invoke-PSRunSelector -MultiSelection -Option $PSRunOption -Expression $sb
Using a selection expression
figure 6

I hope that for a few of the wheels are spinning with possibilities. As with the pwshSpectreConsole examples I shared, you will likely want to wrap this in a function to make it easier to use.

#requires -version 7.4
#requires -module PowerShellRun

function Get-SelectedFile {
    [cmdletbinding()]
    [Alias('gsf')]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.IO.FileInfo]$InputObject,
        [switch]$AllowMultiSelection
    )

    begin {
        $PSRunOption = [PowerShellRun.SelectorOption]::new()
        if ($AllowMultiSelection) {
            $PSRunOption.Prompt= 'Select one or more files using the tab key from the list'
        }
        else {
            $PSRunOption.Prompt= 'Select a single file from the list.'
        }

        $PSRunOption.QuitWithBackspaceOnEmptyQuery = $True
        $PSRunOption.theme.PromptForegroundColor = 'BrightGreen'
        $PSRunOption.theme.SearchBarBorderForegroundColor = 'BrightYellow'
        $PSRunOption.Theme.PreviewForegroundColor = "#27F5F5"

        $files = [System.Collections.Generic.List[System.IO.FileInfo]]::New()
    } #begin
    process {
        $files.Add($_)
    } #process
    end {
        $files | Invoke-PSRunSelector -MultiSelection:$AllowMultiSelection -Option $PSRunOption -Expression {
            @{
                Name        = $_.Name
                Description = '[{0}] {1}' -f $_.Mode, $_.LastWriteTime
                Preview     = if ($_.extension -match 'ps(dm)?1|txt|md|csv|json|xml') { Get-Content $_} else { Get-Item $_ | Out-String}
            } }
    } #end
}

The preview pane will show the file contents if the extension matches one of the patterns. Otherwise, it shows the file item.

Get-SelectedFile
figure 7

PowerShell is a terrific tool for making your own tools.

PSConfEU MiniCon 2025

tickets

I've mentioned this in the past, but the PSConfEU MiniCon is coming up on October 14, 2025. This is a free, online event that features some of the best PowerShell speakers in the world. I am thrilled to say that I will be presenting. You can view the schedule at https://ti.to/synedgy/psconfeu-minicon-2025. Even though this is a free event, you still need to register.You can register for the event at https://ti.to/synedgy/psconfeu-minicon-2025

Scripting Challenge

Your scripting challenge for this month is relatively straightforward. Enumerate all WMI/CIM namespaces on a computer. The output should show the namespace, the namespace name, and the computer name. The namespace object is its own class that can be nested inside a namespace. Your code should be able to query for all namespaces on a local or remote computer.

For the ambitious crowd, write code that includes the number of classes within each namespace that are NOT system classes, ie __ACE. For extra bonus work, include custom formatting to present the output in a table.

Remember, what matters is the journey you take to arrive at a solution, not necessarily the final result. You welcome to post comments in the online archive with links to your solution. Otherwise, I'll share my solution in a few weeks.

Summary

Thanks for hanging out with me this month. If you are a free subscriber, please consider becoming a premium member to support my work and expand your knowledge. Monthly subscriptions are available and you can cancel at any time.

Keep at it and find ways to experience PowerShell daily.

(c) 2022-2025 JDH Information Technology Solutions, Inc. - all rights reserved
Don't miss what's next. Subscribe to Behind the PowerShell Pipeline:
Start the conversation:
GitHub Bluesky LinkedIn Mastodon https://jdhitsoluti…
Powered by Buttondown, the easiest way to start and grow your newsletter.