September 2025 PowerShell Roundup
In this issue:
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
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

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

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

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.

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

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

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.

PowerShell is a terrific tool for making your own tools.
PSConfEU MiniCon 2025
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.