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

This topic contains 1 reply, has 1 voice, and was last updated by  Kevyn 3 months, 2 weeks ago.

  • Author
    Posts
  • #78611

    Kevyn
    Participant

    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?

  • #78616

    Kevyn
    Participant

    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

You must be logged in to reply to this topic.