2

假设我有一个 PowershellFormat-Table字符串,例如:

ls | Format-Table Name, @{expression={$_.Length / 1024}; label='KB'}

我对从中获得的输出感到满意,但我不想每次使用它时都输入它。我希望能够用一个简单的单词命令来调用它,例如:

ls | Format-KiloBytes

我认为我应该为此定义一个函数,因为别名无法指定参数。但是,如果我定义类似:

function kilobytes {format-table Name, @{expression={$_.Length / 1024}; label='KB'}}

那么它没有任何效果:

PS> ls | format-table Name, @{expression={$_.Length / 1024}; label='KB'}
   ... Produces the formatted output

PS> ls | kilobytes
   ... Produces output with unchanged formatting, the same as 'ls'

编辑:看来我很困惑。在试验时,我已经创建了一个别名kilobytesFormat-Table. 我忘记了这一点,但这意味着创建函数kilobytes成功而没有任何警告,但随后调用kilobytes的不是调用新创建的函数而是调用现有别名。

4

3 回答 3

4

首先你可以尝试:

function kilobytes {$input | format-table Name, @{expression={$_.Length / 1024}; label='KB'}}

你可以$inputabout_Functions中找到解释。当您在管道中使用函数时,通过管道传递给该函数的对象将分配给 $input 自动变量。

于 2013-11-15T10:49:46.390 回答
2

这是一个有效的过滤器版本:

filter kilobytes {$_ | select Name,@{expression={$_.Length / 1024}; label='KB'}}

或者:

filter kilobytes {[PSCustomObject]@{Name=$_.name;KB=$_.length/1024}}
于 2013-11-15T11:32:34.813 回答
0

代理函数提供了一种绑定一个或多个参数的好方法,同时仍以自然的方式支持原始命令。在 Bing 上搜索“powershell 代理功能”会提供很多很好的细节。

下面是一个代理功能,它完全符合您的要求。你可以看到你仍然有像 -AutoSize 这样的 Format-Table 参数,但是没有 -Property 参数,因为它已经被硬编码了。

此代理的更智能版本实际上可能支持向硬编码的属性添加其他属性。

function Format-Kilobytes
{
    [CmdletBinding(HelpUri='http://go.microsoft.com/fwlink/?LinkID=113303')]
    param(
        [switch]${AutoSize},
        [switch]${HideTableHeaders},
        [switch]${Wrap},
        [System.Object]${GroupBy},
        [string]${View},
        [switch]${ShowError},
        [switch]${DisplayError},
        [switch]${Force},
        [ValidateSet('CoreOnly','EnumOnly','Both')]
        [string]${Expand},
        [Parameter(ValueFromPipeline=$true)]
        [psobject]${InputObject})

begin
{
    try {
        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Format-Table',
            [System.Management.Automation.CommandTypes]::Cmdlet)
        $properties = "Name",@{expression={$_.Length / 1024}; label='KB'}
        $scriptCmd = {& $wrappedCmd @PSBoundParameters -Property $properties }
        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}
process { try { $steppablePipeline.Process($_) } catch { throw } }
end { try { $steppablePipeline.End() } catch { throw } }
<#
.ForwardHelpTargetName Format-Table
.ForwardHelpCategory Cmdlet
#>
}
于 2013-11-15T15:52:19.197 回答