Overriding Out-Default (Part 3)

by Jul 9, 2019

Advanced PowerShell users often find themselves doing one of three things:

  • They run a previous command and add Get-Member to learn more about the objects emitted
  • They run a previous command and add Select-Object * to see all properties
  • They run a previous command and pipe it to Out-GridView to keep the results in reach

All three can now be accomplished much more easily, and works in any PowerShell, including the console, PowerShell ISE, or Visual Studio Code. Simply override Out-Default and listen to key presses. When certain keys are pressed while ENTER was pressed to execute your code, Out-Default will automatically do the above extra tasks for you:

  • LEFT Arrow + ENTER runs Get-Member on the results and displays the result in a grid view
  • RIGHT Arrow + ENTER echoes all results in a grid view window so you keep the data in reach
  • TAB + ENTER runs Select-Object * on the results and again displays the result in a grid view:
cls
Write-Host ([PSCustomObject]@{
  'Left Arrow + ENTER' = 'Show Member'
  'Right Arrow + ENTER' = 'Echo results'
  'Tab + ENTER' = 'Show all properties'
} | Format-List | Out-String)

function Out-Default
{
  param(
    [switch]
    ${Transcript},

    [Parameter(ValueFromPipeline=$true)]
    [psobject]
  ${InputObject})

  begin
  {
    $scriptCmd = {& 'Microsoft.PowerShell.Core\Out-Default' @PSBoundParameters }
    $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
    $steppablePipeline.Begin($PSCmdlet)
    Add-Type -AssemblyName WindowsBase
    Add-Type -AssemblyName PresentationCore
    $showGridView = [System.Windows.Input.Keyboard]::IsKeyDown([System.Windows.Input.Key]::Right)
    $showAllProps = [System.Windows.Input.Keyboard]::IsKeyDown([System.Windows.Input.Key]::Tab)
    $showMember = [System.Windows.Input.Keyboard]::IsKeyDown([System.Windows.Input.Key]::Left)
    
    if ($showGridView)
    {
      $cmd = {& 'Microsoft.PowerShell.Utility\Out-GridView' -Title (Get-Date -Format 'HH:mm:ss')  }
      $out = $cmd.GetSteppablePipeline()
      $out.Begin($true)
      
    }
    if ($showMember)
    {
      
      $cmd = {& 'Microsoft.PowerShell.Utility\Get-Member' | Select-Object -Property @{Name = 'Type' = { $_.TypeName }}, Name, MemberType, Definition | Sort-Object -Property Type, {
        if ($_.MemberType -like '*Property')
        { 'B' }
        elseif ($_.MemberType -like '*Method')
        { 'C' }
        elseif ($_.MemberType -like '*Event')
        { 'A' }
        else
        { 'D' }
      }, Name | Out-GridView -Title Member  }
      $outMember = $cmd.GetSteppablePipeline()
      $outMember.Begin($true)
      
    }
    
  }

  process
  {
    $isError = $_ -is [System.Management.Automation.ErrorRecord]
    
    if ($showMember -and (-not $isError))
    {
      $outMember.Process($_)
    }
    if ($showAllProps -and (-not $isError))
    {
      $_ = $_ | Select-Object -Property *
    }
    if (($showGridView) -and (-not $isError))
    {
      $out.Process($_)
    }
    $steppablePipeline.Process($_)
  }

  end
  {
    $steppablePipeline.End()
    if ($showGridView)
    {
      $out.End()
    }
    if ($showMember)
    {
      $outMember.End()
    }
    
  }
}

To remove the override, simply run:

 
PS C:\> del function:Out-Default 
 

Twitter This Tip! ReTweet this Tip!