Get-Command not returning data when using Wildcards in -Name parameter

OK, time to stop beating my head against a rock and see if someone here can tell me what’s going wrong and if/how I can fix it. I’m trying to get some information for cmdlets via Invoke-Command, including the ConfirmImpact value. As a test I’m trying to get some information for all cmdlets from all modules that Get-Command can see.

The following is part of an overall script, and eventually module, that I’m trying to create and is the part that’s not working right. As a test, I’ve manually set $Name, $Module, and $Computer.

$Name = '*'
$Module = '*'
$Computer = 'localhost'
$GCScriptBlock = {
                   $ConfirmImpactLevelExpr = @{
                                                Name = 'ConfirmImpactLevel';
                                                Expression = {$_.ImplementingType.GetCustomAttributes($True).ConfirmImpact}
                                              }
                   Get-Command -Name Stop-* -CommandType Cmdlet -Module $Using:Module | Select-Object -Property Name,CommandType,ModuleName,$ConfirmImpactLevelExpr
                 }
$ImpactLevelData = Invoke-Command -ComputerName $Computer -ScriptBlock $GCScriptBlock -ErrorAction Stop

If I run the above, some cmdlets do show a value for ConfirmImpactLevel, but most do not. It seems to be consistent as to which ones have values for that property and which do not.

PS C:> $ImpactLevelData | sort ConfirmImpactLevel -Descending | ft name,co*,psc*

Name CommandType ConfirmImpactLevel PSComputerName ModuleName


Write-Warning Cmdlet Medium localhost Microsoft.PowerShell.Utility
Show-Command Cmdlet Medium localhost Microsoft.PowerShell.Utility
Import-Csv Cmdlet Medium localhost Microsoft.PowerShell.Utility

Clear-Recyclebin Cmdlet localhost Microsoft.PowerShell.Management

Stop-Process Cmdlet localhost Microsoft.PowerShell.Management
Stop-Service Cmdlet localhost Microsoft.PowerShell.Management

In the above example, Stop-Process & Stop-Service, as examples, for some reason, do not return a value for ConfirmImpactLevel. Their values should say “Medium”, while for Clear-RecycleBin the output should say “High”.

If I run similar code (see below), locally on the same machine, I get similar, though slightly different results (i.e. Some cmdlets that via Invoke-Command didn’t show a value for ConfirmImpactLevel now do, while others that did have a value via Invoke-Command no longer do. Most cmdlets still don’t have a value).

Code run locally on same machine (i.e. not via Invoke-Command):

$Name = '*'
$Module = '*'
$Computer = 'localhost'
$ConfirmImpactLevelExpr = @{
                             Name = 'ConfirmImpactLevel';
                             Expression = {$_.ImplementingType.GetCustomAttributes($True).ConfirmImpact}
                                              }
Get-Command -Name $Name -CommandType Cmdlet -Module $Module | Select-Object -Property Name,CommandType,ModuleName,$ConfirmImpactLevelExpr

If I put a specific value for the cmdlet name (Ex: Clear-RecycleBin), either via the Invoke-Command code or the code run locally, then the ConfirmImpactLevel seems to always return the correct value.

Get-Command -Name Clear-RecycleBin -CommandType Cmdlet -Module * | Select-Object -Property Name,CommandType,ModuleName,$ConfirmImpactLevelExpr

Name             CommandType ModuleName                      ConfirmImpactLevel
----             ----------- ----------                      ------------------
Clear-RecycleBin      Cmdlet Microsoft.PowerShell.Management               High

When I look at the help information for Get-Command, it says the following for the -Name parameter. the “Accept wildcard characters?” value indicates it doesn’t accept wildcard values, but the text describing the parameter says that wildcards are permitted.

-Name
Specifies an array of names. This cmdlet gets only commands that have the specified name. Enter a name or name pattern. Wildcard characters are permitted.

To get commands that have the same name, use the All parameter. When two commands have the same name, by default, Get-Command gets the command that runs when you type the command name.

Required?                    false
Position?                    0
Default value                None
Accept pipeline input?       True (ByPropertyName, ByValue)
Accept wildcard characters?  false

Thoughts?

I found a workaround, but I’m hoping someone has something better. It involves calling Get-Command twice.

Workaround:

$computer = 'localhost'
$name = '*'
$module = '*'
$GCScriptBlock = {
                   $ConfirmImpactLevelExpr = @{
                                                Name = 'ConfirmImpactLevel';
                                                Expression = {$_.ImplementingType.GetCustomAttributes($True).ConfirmImpact}
                                              }
                   Get-Command -Name $Using:Name -CommandType Cmdlet -Module $Using:Module | Select-Object Name |
                   ForEach-Object{Get-Command -Name $_.Name -CommandType Cmdlet |
                   Select-Object -Property Name,CommandType,ModuleName,$ConfirmImpactLevelExpr}
                 }
$ImpactLevelData = Invoke-Command -ComputerName $Computer -ScriptBlock $GCScriptBlock -ErrorAction Stop

The only problem is that I get the following errors saying two cmdlets (always the same two) couldn’t be found when the Invoke-Command code is running.

The term ‘Add-ClusteriSCSITargetServerRole’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (Add-ClusteriSCSITargetServerRole:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
+ PSComputerName : localhost

The term ‘Block-GPInheritance’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (Block-GPInheritance:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
+ PSComputerName : localhost

If I manually look for them, Get-Command finds them. What’s going on? Any way to work around this second problem?

PS C:> Get-Command -CommandType Cmdlet | Where{($.Name -eq “Add-ClusteriSCSITargetServerRole”) -or ($.Name -eq “Block-GPInheritance”)}

CommandType Name Version Source


Cmdlet Add-ClusteriSCSITargetServerRole 2.0.0.0 IscsiTarget
Cmdlet Block-GPInheritance 1.0.0.0 GroupPolicy