当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 按您的方式使用 PowerShell

作者:精品下载站 日期:2024-12-14 08:07:18 浏览:14 分类:玩电脑

按您的方式使用 PowerShell


我经常告诉人们,我每天都在 PowerShell 提示符下度过。我几乎一整天都在使用 PowerShell。我在 Github 上分享了我每天使用的许多工具。今天,我想分享另一种让 PowerShell 以我需要的方式工作的方式,并且只需付出最少的努力。此特定任务以文件和文件夹为中心。

正如您所料,我不断地创建、编辑和管理文件。我在 PowerShell 提示符下完成所有这些操作。我很少使用开始菜单来查找要启动的程序。我的挑战一直是找到我最近使用的文件和文件夹。 Get-ChildItem 自然是首选的 PowerShell 工具,但我终于开始让它按照需要的方式工作。

Get-ChildItem 默认值

Get-ChildItem 的默认行为始终是按名称排序。

[玩转系统] 按您的方式使用 PowerShell

首先列出目录,按名称排序,然后列出文件,也按名称排序。通常,我试图记住我正在使用的文件夹,但这个输出对我来说并不容易。我需要的是按 LastWriteTime 属性进行排序。但我仍然希望首先列出文件夹,然后列出文件。

创建新命令

我无法使用自定义格式视图,因为这不会进行排序。此外,我想让这个过程变得简单。我知道我可以运行这样的 PowerShell 表达式来获得所需的结果。

Get-ChildItem | Sort-Object -Property { -Not $_.psiscontainer }, LastWritetime

[玩转系统] 按您的方式使用 PowerShell

Sort-Object 对两个属性的管道输入进行排序。第一个是由脚本块动态定义的自定义属性。该脚本块查看 PSIContainer 属性,这是一个布尔值。文件的值为 True,文件夹的值为 False。我希望首先显示文件夹,因此我使用 -Not 运算符来反转该值。项目按此属性排序后,将按 LastWriteTime 排序。这让我的生活变得更加轻松。但我很懒。我不想记住输入所有这些,即使通过 PSReadline 自动完成也是如此。

一个函数怎么样?

Function Get-MyFolderItem {
    [cmdletbinding()]
    [alias("dl")]
    Param(
        [Parameter(Position = 0)]
        [string]$Path,
        [Parameter(Position = 1)]
        [string]$Flter,
        [switch]$File,
        [switch]$Directory,
        [string[]]$Exclude,
        [string[]]$Include,
        [switch]$Recurse
    )
    #Run Get-Childitem with whatever parameters are specified.
    Get-ChildItem @psboundparameters | Sort-Object -Property { -Not $_.psiscontainer }, LastWritetime
}

该函数只不过是 Get-ChildItem 的包装器。我的函数参数反映了 Get-ChildItem 的参数。我将 $PSBoundParameters 分配给 Get-ChildItem,然后执行排序。

[玩转系统] 按您的方式使用 PowerShell

$PSBoundParameters 是一个内在变量。它是一个专门的哈希表,其中包含每个带有值的参数。我还为我的函数添加了一个别名,以使其更易于使用。我可以将此函数放入我的 PowerShell 配置文件脚本中,然后就可以了。

通过代理列出

但我还有另一种方法可以创建此命令。我可以做一个代理功能。这是一种特殊类型的函数。代理函数经常取代原始命令。通常,您使用代理函数来添加或删除参数或自定义命令的行为。您经常会看到带有 Just Enough Administration (JEA) 部署的代理功能。但我可以使用基于 Get-ChildItem 构建的代理函数。

最简单的入门方法是使用 PSScriptTools 模块中的 Copy-Command。

Copy-Command Get-Childitem -AsProxy -UseForwardHelp -IncludeDynamic

在 VS Code 集成编辑器中运行此命令,它将加载一个新文件到编辑器中。

如果您正在构建代理功能,请注意您的 PowerShell 版本。我在PowerShell 7中创建了我的文件。幸运的是,Windows PowerShell中的参数没有变化,因此我可以在两个版本中使用我的代理功能。但情况可能并非总是如此。

这是添加了一项的代理功能。

#requires -version 5.1

<#
This is a copy of:

CommandType Name          Version Source
----------- ----          ------- ------
Cmdlet      Get-ChildItem 7.0.0.0 Microsoft.PowerShell.Management

Created: 06 June 2022
Author : Jeff Hicks

Created with Copy-Command from the PSScriptTools module
https://github.com/jdhitsolutions/PSScriptTools

Copy-Command Get-Childitem -AsProxy -UseForwardHelp -IncludeDynamic

#>


Function Get-ChildItem {
    <#
.ForwardHelpTargetName Microsoft.PowerShell.Management\Get-ChildItem
.ForwardHelpCategory Cmdlet

#>
    [CmdletBinding(DefaultParameterSetName = 'Items', SupportsTransactions = $true, HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=113308')]
    Param(

        [Parameter(ParameterSetName = 'Items', Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]]$Path,

        [Parameter(ParameterSetName = 'LiteralItems', Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('PSPath')]
        [string[]]$LiteralPath,

        [Parameter(Position = 1)]
        [string]$Filter,

        [switch]$File,

        [switch]$Directory,

        [string[]]$Include,

        [string[]]$Exclude,

        [Alias('s')]
        [switch]$Recurse,

        [uint32]$Depth,

        [switch]$Force,

        [switch]$Name
    )

    Begin {

        Write-Verbose "[BEGIN  ] Starting $($MyInvocation.Mycommand)"
        Write-Verbose "[BEGIN  ] Using parameter set $($PSCmdlet.ParameterSetName)"
        Write-Verbose ($PSBoundParameters | Out-String)

        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)
            #sort the output with directories first and then sorted by last write time
            $scriptCmd = { & $wrappedCmd @PSBoundParameters | Sort-Object -Property { -Not $_.psiscontainer }, LastWritetime }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        }
        catch {
            throw
        }

    } #begin

    Process {

        try {
            $steppablePipeline.Process($_)
        }
        catch {
            throw
        }


    } #process

    End {

        try {
            $steppablePipeline.End()
        }
        catch {
            throw
        }
        Write-Verbose "[END    ] Ending $($MyInvocation.Mycommand)"

    } #end

} #end function Get-ChildItem

代理功能也是“包装”Get-ChildItem。

 $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)

我所做的就是对输出进行排序。

$scriptCmd = { & $wrappedCmd @PSBoundParameters | Sort-Object -Property { -Not $_.psiscontainer }, LastWritetime }

我所要做的就是对代理函数脚本进行点源。从现在开始,每当我运行 Get-Childitem 时,它将使用我的代理版本。

[玩转系统] 按您的方式使用 PowerShell

在我的代理函数中,我没有对底层命令 Get-ChildItem 的运行方式进行任何更改。我所做的只是添加排序。我可以像往常一样继续使用 Get-Childitem。但现在,在文件系统中,我得到了所需的输出。

概括

Get-Command 确认我正在运行 Get-Childitem 的自定义版本。

[玩转系统] 按您的方式使用 PowerShell

老实说,我不确定我会长期使用哪种方法。现在,我正在使用 dl 别名加载包装函数,并在 PowerShell 配置文件脚本中加载代理函数。我必须看看代理功能是否有任何我尚未考虑到的限制。

如果您需要调整 PowerShell 命令来满足的需求,我希望我的示例可以作为解决方案的模板。

更新

使用代理功能一段时间后,我意识到我忽略了包含动态参数 -File 和 -Directory。我更新了代码示例。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯