PowerShell 技能连载 - 覆盖 Out-Default(第 3 部分)

高级的 PowerShell 用户常常发现他们在做以下三件事之一:

  • 他们运行前面的命令并添加 Get-Member,以了解产生的对象的更多信息
  • 他们运行前面的命令并添加 Select-Object * 来查看所有属性
  • 他们运行前面的命令并将其通过管道传输到 Out-GridView 来查看图形化结果

这三条都可以更容易地实现,并且在所有 PowerShell 中都可工作,包括控制台、PowerShell ISE,或 Visual Studio Code。只需要覆盖 Out-Default 并且监听按键。当按下特定按键及回车键时,Out-Default 将会自动为您执行以上额外任务:

  • 左方向键 + 回车按下时,对执行结果运行 Get-Member 并且将结果显示在网格视图中
  • 右方向键 + 回车按下时,将所有执行结果显示在一个网格试图窗口中,这样您可以接触到数据
  • TAB + 回车按下时,将对结果执行 Select-Object *,同时也将结果显示在网格视图中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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';Expression = { $_.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()
}

}
}

要移除这个覆盖函数,只需要运行:

1
PS C:\> del function:Out-Default
评论