PowerShell:终极版Get-Childitem输出彩色显示技巧

50

编辑: 此帖底部有原始解决方案。获得更实时的解决方案,请查看由Thraka发布的已接受答案。

给Get-Childitem(即dirls)上色并不是一个新想法,但我一直没有找到任何理想的方法来给Powershell中的输出上色。编写颜色-ls函数有两种常见方法:

  • 拦截Get-Childitem的输出,并使用Write-Host和-ForegroundColor参数将其重新输出为文本。这种方法允许尽可能精细地处理输出,但会将Get-Childitem的输出减少为文本。正如大多数powershell用户所知道的那样,Get-Childitem不输出文本,而是输出对象。具体来说,是FileInfo和DirectoryInfo对象的列表。这允许在处理Get-Childitem输出时具有很大的灵活性。

  • 通过Invoke-Expression将Get-Childitem的输出传递到ForEach-Object,然后在输出每个对象之前更改控制台前景色。这种方法保留了Get-Childitem输出的类型,是更好的选择。

以下是一种后者方法的示例,由Tim Johnson's Powershell Blog提供。
function color-ls
{
    $regex_opts = ([System.Text.RegularExpressions.RegexOptions]::IgnoreCase `
          -bor [System.Text.RegularExpressions.RegexOptions]::Compiled)
    $fore = $Host.UI.RawUI.ForegroundColor
    $compressed = New-Object System.Text.RegularExpressions.Regex(
          '\.(zip|tar|gz|rar|jar|war)$', $regex_opts)
    $executable = New-Object System.Text.RegularExpressions.Regex(
          '\.(exe|bat|cmd|py|pl|ps1|psm1|vbs|rb|reg)$', $regex_opts)
    $text_files = New-Object System.Text.RegularExpressions.Regex(
          '\.(txt|cfg|conf|ini|csv|log|xml|java|c|cpp|cs)$', $regex_opts)

    Invoke-Expression ("Get-ChildItem $args") | ForEach-Object {
        if ($_.GetType().Name -eq 'DirectoryInfo') 
        {
            $Host.UI.RawUI.ForegroundColor = 'Magenta'
            echo $_
            $Host.UI.RawUI.ForegroundColor = $fore
        }
        elseif ($compressed.IsMatch($_.Name)) 
        {
            $Host.UI.RawUI.ForegroundColor = 'darkgreen'
            echo $_
            $Host.UI.RawUI.ForegroundColor = $fore
        }
        elseif ($executable.IsMatch($_.Name))
        {
            $Host.UI.RawUI.ForegroundColor = 'Red'
            echo $_
            $Host.UI.RawUI.ForegroundColor = $fore
        }
        elseif ($text_files.IsMatch($_.Name))
        {
            $Host.UI.RawUI.ForegroundColor = 'Yellow'
            echo $_
            $Host.UI.RawUI.ForegroundColor = $fore
        }
        else
        {
            echo $_
        }
    }
}

这段代码基于文件扩展名分配不同的颜色,但几乎任何指标都可以替换以区分文件类型。上述代码产生以下输出:

Colored get-childitem example

这几乎是完美的,但有一个小缺陷:前3行输出(目录路径、列标题和水平分隔符)采用列表中第一项的颜色。Tim Johnson 在他的博客中评论道:
“我希望顶部的标题不总是与第一项相同的颜色,但我想不到任何方法。”
可惜,我也想不出。这就是 Stack Overflow 和它的 PowerShell 大师发挥作用的地方:我正在寻找一种在保留 cmdlet 输出类型的同时为 Get-Childitem 输出着色的方法,而不会破坏标题的颜色。我已经尝试过一些方法,但还没有成功,因为第一个单独的 echo 调用会输出整个标题和第一项。
欢迎提出任何问题、评论或更好的解决方案。
解决方案:感谢 Jon Z 和其他提供思路的人。

Jon Z提供了完美的解决方案,我稍微修改了一下以适应我的原始问题。对于任何感兴趣的人,这里是代码。请注意,这需要来自Powershell Cookbook的New-CommandWrapper cmdlet相关cmdlet已添加到本帖底部。所有这些代码都放在您的个人资料中。

function Write-Color-LS
    {
        param ([string]$color = "white", $file)
        Write-host ("{0,-7} {1,25} {2,10} {3}" -f $file.mode, ([String]::Format("{0,10}  {1,8}", $file.LastWriteTime.ToString("d"), $file.LastWriteTime.ToString("t"))), $file.length, $file.name) -foregroundcolor $color 
    }

New-CommandWrapper Out-Default -Process {
    $regex_opts = ([System.Text.RegularExpressions.RegexOptions]::IgnoreCase)

     
    $compressed = New-Object System.Text.RegularExpressions.Regex(
        '\.(zip|tar|gz|rar|jar|war)$', $regex_opts)
    $executable = New-Object System.Text.RegularExpressions.Regex(
        '\.(exe|bat|cmd|py|pl|ps1|psm1|vbs|rb|reg)$', $regex_opts)
    $text_files = New-Object System.Text.RegularExpressions.Regex(
        '\.(txt|cfg|conf|ini|csv|log|xml|java|c|cpp|cs)$', $regex_opts)

    if(($_ -is [System.IO.DirectoryInfo]) -or ($_ -is [System.IO.FileInfo]))
    {
        if(-not ($notfirst)) 
        {
           Write-Host
           Write-Host "    Directory: " -noNewLine
           Write-Host " $(pwd)`n" -foregroundcolor "Magenta"           
           Write-Host "Mode                LastWriteTime     Length Name"
           Write-Host "----                -------------     ------ ----"
           $notfirst=$true
        }

        if ($_ -is [System.IO.DirectoryInfo]) 
        {
            Write-Color-LS "Magenta" $_                
        }
        elseif ($compressed.IsMatch($_.Name))
        {
            Write-Color-LS "DarkGreen" $_
        }
        elseif ($executable.IsMatch($_.Name))
        {
            Write-Color-LS "Red" $_
        }
        elseif ($text_files.IsMatch($_.Name))
        {
            Write-Color-LS "Yellow" $_
        }
        else
        {
            Write-Color-LS "White" $_
        }
        
    $_ = $null
    }
} -end {
    write-host ""
}

这将产生以下截图所示的输出: enter image description here 如果您想在底部添加总文件大小行,请添加以下代码:
Remove-Item alias:ls
Set-Alias ls LS-Padded

function LS-Padded
{
    param ($dir)
    Get-Childitem $dir
    Write-Host
    getDirSize $dir
}

function getDirSize
{
    param ($dir)
    $bytes = 0

    Get-Childitem $dir | foreach-object {

        if ($_ -is [System.IO.FileInfo])
        {
            $bytes += $_.Length
        }
    }

    if ($bytes -ge 1KB -and $bytes -lt 1MB)
    {
        Write-Host ("Total Size: " + [Math]::Round(($bytes / 1KB), 2) + " KB")   
    }

    elseif ($bytes -ge 1MB -and $bytes -lt 1GB)
    {
        Write-Host ("Total Size: " + [Math]::Round(($bytes / 1MB), 2) + " MB")
    }

    elseif ($bytes -ge 1GB)
    {
        Write-Host ("Total Size: " + [Math]::Round(($bytes / 1GB), 2) + " GB")
    }    

    else
    {
        Write-Host ("Total Size: " + $bytes + " bytes")
    }
}

正如评论中所指出的那样,PoshCode New-CommandWrapper链接已失效。以下是完整的相关cmdlet:

##############################################################################
##
## New-CommandWrapper
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Adds parameters and functionality to existing cmdlets and functions.

.EXAMPLE

New-CommandWrapper Get-Process `
      -AddParameter @{
          SortBy = {
              $newPipeline = {
                  __ORIGINAL_COMMAND__ | Sort-Object -Property $SortBy
              }
          }
      }

This example adds a 'SortBy' parameter to Get-Process. It accomplishes
this by adding a Sort-Object command to the pipeline.

.EXAMPLE

$parameterAttributes = @'
          [Parameter(Mandatory = $true)]
          [ValidateRange(50,75)]
          [Int]
'@

New-CommandWrapper Clear-Host `
      -AddParameter @{
          @{
              Name = 'MyMandatoryInt';
              Attributes = $parameterAttributes
          } = {
              Write-Host $MyMandatoryInt
              Read-Host "Press ENTER"
         }
      }

This example adds a new mandatory 'MyMandatoryInt' parameter to
Clear-Host. This parameter is also validated to fall within the range
of 50 to 75. It doesn't alter the pipeline, but does display some
information on the screen before processing the original pipeline.

#>

param(
    ## The name of the command to extend
    [Parameter(Mandatory = $true)]
    $Name,

    ## Script to invoke before the command begins
    [ScriptBlock] $Begin,

    ## Script to invoke for each input element
    [ScriptBlock] $Process,

    ## Script to invoke at the end of the command
    [ScriptBlock] $End,

    ## Parameters to add, and their functionality.
    ##
    ## The Key of the hashtable can be either a simple parameter name,
    ## or a more advanced parameter description.
    ##
    ## If you want to add additional parameter validation (such as a
    ## parameter type,) then the key can itself be a hashtable with the keys
    ## 'Name' and 'Attributes'. 'Attributes' is the text you would use when
    ## defining this parameter as part of a function.
    ##
    ## The Value of each hashtable entry is a scriptblock to invoke
    ## when this parameter is selected. To customize the pipeline,
    ## assign a new scriptblock to the $newPipeline variable. Use the
    ## special text, __ORIGINAL_COMMAND__, to represent the original
    ## command. The $targetParameters variable represents a hashtable
    ## containing the parameters that will be passed to the original
    ## command.
    [HashTable] $AddParameter
)

Set-StrictMode -Version Latest

## Store the target command we are wrapping, and its command type
$target = $Name
$commandType = "Cmdlet"

## If a function already exists with this name (perhaps it's already been
## wrapped,) rename the other function and chain to its new name.
if(Test-Path function:\$Name)
{
    $target = "$Name" + "-" + [Guid]::NewGuid().ToString().Replace("-","")
    Rename-Item function:\GLOBAL:$Name GLOBAL:$target
    $commandType = "Function"
}

## The template we use for generating a command proxy
$proxy = @'

__CMDLET_BINDING_ATTRIBUTE__
param(
__PARAMETERS__
)
begin
{
    try {
        __CUSTOM_BEGIN__

        ## Access the REAL Foreach-Object command, so that command
        ## wrappers do not interfere with this script
        $foreachObject = $executionContext.InvokeCommand.GetCmdlet(
            "Microsoft.PowerShell.Core\Foreach-Object")

        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
            '__COMMAND_NAME__',
            [System.Management.Automation.CommandTypes]::__COMMAND_TYPE__)

        ## TargetParameters represents the hashtable of parameters that
        ## we will pass along to the wrapped command
        $targetParameters = @{}
        $PSBoundParameters.GetEnumerator() |
            & $foreachObject {
                if($command.Parameters.ContainsKey($_.Key))
                {
                    $targetParameters.Add($_.Key, $_.Value)
                }
            }

        ## finalPipeline represents the pipeline we wil ultimately run
        $newPipeline = { & $wrappedCmd @targetParameters }
        $finalPipeline = $newPipeline.ToString()

        __CUSTOM_PARAMETER_PROCESSING__

        $steppablePipeline = [ScriptBlock]::Create(
            $finalPipeline).GetSteppablePipeline()
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}

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

end
{
    try {
        __CUSTOM_END__
        $steppablePipeline.End()
    } catch {
        throw
    }
}

dynamicparam
{
    ## Access the REAL Get-Command, Foreach-Object, and Where-Object
    ## commands, so that command wrappers do not interfere with this script
    $getCommand = $executionContext.InvokeCommand.GetCmdlet(
        "Microsoft.PowerShell.Core\Get-Command")
    $foreachObject = $executionContext.InvokeCommand.GetCmdlet(
        "Microsoft.PowerShell.Core\Foreach-Object")
    $whereObject = $executionContext.InvokeCommand.GetCmdlet(
        "Microsoft.PowerShell.Core\Where-Object")

    ## Find the parameters of the original command, and remove everything
    ## else from the bound parameter list so we hide parameters the wrapped
    ## command does not recognize.
    $command = & $getCommand __COMMAND_NAME__ -Type __COMMAND_TYPE__
    $targetParameters = @{}
    $PSBoundParameters.GetEnumerator() |
        & $foreachObject {
            if($command.Parameters.ContainsKey($_.Key))
            {
                $targetParameters.Add($_.Key, $_.Value)
            }
        }

    ## Get the argumment list as it would be passed to the target command
    $argList = @($targetParameters.GetEnumerator() |
        Foreach-Object { "-$($_.Key)"; $_.Value })

    ## Get the dynamic parameters of the wrapped command, based on the
    ## arguments to this command
    $command = $null
    try
    {
        $command = & $getCommand __COMMAND_NAME__ -Type __COMMAND_TYPE__ `
            -ArgumentList $argList
    }
    catch
    {

    }

    $dynamicParams = @($command.Parameters.GetEnumerator() |
        & $whereObject { $_.Value.IsDynamic })

    ## For each of the dynamic parameters, add them to the dynamic
    ## parameters that we return.
    if ($dynamicParams.Length -gt 0)
    {
        $paramDictionary = `
            New-Object Management.Automation.RuntimeDefinedParameterDictionary
        foreach ($param in $dynamicParams)
        {
            $param = $param.Value
            $arguments = $param.Name, $param.ParameterType, $param.Attributes
            $newParameter = `
                New-Object Management.Automation.RuntimeDefinedParameter `
                $arguments
            $paramDictionary.Add($param.Name, $newParameter)
        }
        return $paramDictionary
    }
}

<#

.ForwardHelpTargetName __COMMAND_NAME__
.ForwardHelpCategory __COMMAND_TYPE__

#>

'@

## Get the information about the original command
$originalCommand = Get-Command $target
$metaData = New-Object System.Management.Automation.CommandMetaData `
    $originalCommand
$proxyCommandType = [System.Management.Automation.ProxyCommand]

## Generate the cmdlet binding attribute, and replace information
## about the target
$proxy = $proxy.Replace("__CMDLET_BINDING_ATTRIBUTE__",
    $proxyCommandType::GetCmdletBindingAttribute($metaData))
$proxy = $proxy.Replace("__COMMAND_NAME__", $target)
$proxy = $proxy.Replace("__COMMAND_TYPE__", $commandType)

## Stores new text we'll be putting in the param() block
$newParamBlockCode = ""

## Stores new text we'll be putting in the begin block
## (mostly due to parameter processing)
$beginAdditions = ""

## If the user wants to add a parameter
$currentParameter = $originalCommand.Parameters.Count
if($AddParameter)
{
    foreach($parameter in $AddParameter.Keys)
    {
        ## Get the code associated with this parameter
        $parameterCode = $AddParameter[$parameter]

        ## If it's an advanced parameter declaration, the hashtable
        ## holds the validation and / or type restrictions
        if($parameter -is [Hashtable])
        {
            ## Add their attributes and other information to
            ## the variable holding the parameter block additions
            if($currentParameter -gt 0)
            {
                $newParamBlockCode += ","
            }

            $newParamBlockCode += "`n`n    " +
                $parameter.Attributes + "`n" +
                '    $' + $parameter.Name

            $parameter = $parameter.Name
        }
        else
        {
            ## If this is a simple parameter name, add it to the list of
            ## parameters. The proxy generation APIs will take care of
            ## adding it to the param() block.
            $newParameter =
                New-Object System.Management.Automation.ParameterMetadata `
                    $parameter
            $metaData.Parameters.Add($parameter, $newParameter)
        }

        $parameterCode = $parameterCode.ToString()

        ## Create the template code that invokes their parameter code if
        ## the parameter is selected.
        $templateCode = @"

        if(`$PSBoundParameters['$parameter'])
        {
            $parameterCode

            ## Replace the __ORIGINAL_COMMAND__ tag with the code
            ## that represents the original command
            `$alteredPipeline = `$newPipeline.ToString()
            `$finalPipeline = `$alteredPipeline.Replace(
                '__ORIGINAL_COMMAND__', `$finalPipeline)
        }
"@

        ## Add the template code to the list of changes we're making
        ## to the begin() section.
        $beginAdditions += $templateCode
        $currentParameter++
    }
}

## Generate the param() block
$parameters = $proxyCommandType::GetParamBlock($metaData)
if($newParamBlockCode) { $parameters += $newParamBlockCode }
$proxy = $proxy.Replace('__PARAMETERS__', $parameters)

## Update the begin, process, and end sections
$proxy = $proxy.Replace('__CUSTOM_BEGIN__', $Begin)
$proxy = $proxy.Replace('__CUSTOM_PARAMETER_PROCESSING__', $beginAdditions)
$proxy = $proxy.Replace('__CUSTOM_PROCESS__', $Process)
$proxy = $proxy.Replace('__CUSTOM_END__', $End)

## Save the function wrapper
Write-Verbose $proxy
Set-Content function:\GLOBAL:$NAME $proxy

## If we were wrapping a cmdlet, hide it so that it doesn't conflict with
## Get-Help and Get-Command
if($commandType -eq "Cmdlet")
{
    $originalCommand.Visibility = "Private"
}

你好。这里是一些相关链接:https://dev59.com/ql3Ua4cB1Zd3GeqP9h5V#8088587 - Animesh
这篇博客对该方法进行了一些修改:http://avinmathew.com/coloured-directory-listings-in-powershell/ - John Fouhy
1
遗憾的是,poshcode.org网站似乎已经关闭。 - KERR
你是否看过并评估了MS powershellgallery.com中的模块? Find-Module -Name '*color*'。这似乎就像你正在尝试做他们已经完成的事情? - postanote
你看过并评估了这个问题被提出的日期吗?那个网站在当时还不存在,Find-Module cmdlet 也是如此。也许你可以在那里寻找解决方案并将其发布为答案? - Fopedush
显示剩余3条评论
6个回答

35

我刚安装并使用了https://github.com/Davlind/PSColor,这是很容易的。它支持 PSGet,因此您可以使用 Install-Module PSColor 轻松安装。

注意:有一个更新的PSColor分支可用,名为 Colorhttps://www.powershellgallery.com/packages/Color/2.1.0(感谢 @HackSlash),使用 Install-Module Color 来获取它。

这些对象没有被转换,因此它们仍然支持管道操作。(它正在使用上面提到的 New-CommandWrapper

它还支持其他一些功能,如 select-string。

PowerShell Color


5
这可能应该成为被接受的答案。与其他回答不同(虽然我没有尝试过joon的),对我来说,它可以直接使用而无需修改(其他所有答案都会出现多个语法错误),并且不会使ls运行变得非常缓慢。 - stijn
1
我不知道如何让这个工具运行起来。我去了项目主页,阅读了那里的说明,然后执行了 Install-Module PSColor 命令。但是没有任何反应。我关闭并重新打开了控制台,但仍然没有反应。我复制了主页上的 $global 设置,并将其放入我的 $profile 中,然后再次关闭并重新打开了控制台。但仍然没有反应。你能否说明一下我们应该如何配置这个工具? - YorSubs
我认为你需要第一次以管理员身份运行来安装该模块。 - Thraka
3
不要忘记在您的配置文件中调用Import-Module PSColor。 - Thraka
我将这个答案改为被接受的答案,因为它比之前的方法更现代化、更简单。值得一提的是,我确实仍在使用Jon Z发布的解决方案! - Fopedush
显示剩余8条评论

14
修改Out-Default绝对是正确的方法。以下是一个例子(虽然有点随意)。 我正在使用《PowerShell Cookbook》中的New-CommandWrapper
New-CommandWrapper Out-Default `
    -Process {
        if(($_ -is [System.IO.DirectoryInfo]) -or ($_ -is [System.IO.FileInfo]))
        {if(-not ($notfirst)) {
           Write-Host "    Directory: $(pwd)`n"           
           Write-Host "Mode                LastWriteTime     Length Name"
           Write-Host "----                -------------     ------ ----"
           $notfirst=$true
           }
           if ($_ -is [System.IO.DirectoryInfo]) {
           Write-host ("{0,-7} {1,25} {2,10} {3}" -f $_.mode, ([String]::Format("{0,10}  {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.length, $_.name) -foregroundcolor "yellow" }
           else {
           Write-host ("{0,-7} {1,25} {2,10} {3}" -f $_.mode, ([String]::Format("{0,10}  {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.length, $_.name) -foregroundcolor "green" }
           $_ = $null
        }
} 

Example Directory Listing


这看起来像是答案。我会稍微试一下后再回来确认。 - Fopedush
是的,这绝对是答案。我有一些格式问题要处理,但没有我无法解决的。谢谢! - Fopedush
这里有一个想法 - 是否有一种简单的方法在输出末尾添加换行符?(或者,例如,在底部添加总文件大小行?)我不知道如何编程地检查一个条目是否是最后一个。编辑:我想我可以编写一个调用LS然后写入换行符的函数,并将该函数别名化。没什么大不了的。 - Fopedush
只需在结尾添加“-end {write-host“”}”。 - jon Z
另外,还可以查看此博主对此解决方案的扩展:http://avinmathew.com/coloured-directory-listings-in-powershell/,但请注意,您可能希望将正则表达式移到每个函数评估之外,以避免非常恶劣的缓慢。 - jhclark
显示剩余2条评论

4

3
我有另一种解决方案。您可以使用自定义的 .format.ps1xml 文件,并进行一些调整以使着色成为可能。
我在 github.com 上拥有我的个人 .format.ps1xml 格式文件:https://github.com/ecsousa/PSUtils/blob/master/CustomPSUtils.format.ps1xml 要使用它,您只需要执行以下操作:
Update-FormatData -Prepend CustomPSUtils.format.ps1xml

此外,为了确保在执行Get-ChildItem命令后能够回到原始的控制台颜色,您需要覆盖prompt函数。可以参考以下示例代码:
function prompt {
    if($global:FSFormatDefaultColor) {
        [Console]::ForegroundColor = $global:FSFormatDefaultColor
    }

    "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}

0

我无法使主帖工作(尝试了大约一个小时,试图让组件正常工作,但没有成功 - 可能需要更新解决方案或更改为更高效的解决方案?)PSColor看起来是一个不错的解决方案,但我继续寻找,并最终找到了一个更好的整体解决方案,包括精心制定的颜色设置和无缝的图标支持。 我已经构建了一个脚本来执行所有所需的安装步骤(只需将这些行投入任何管理员PowerShell控制台中,然后您只需要记住Set-ConsoleFont "LiterationMono NF"Set-TerminalIconsColorTheme -Name DevBlackOps在任何控制台中激活(或将这些行保留在$profile中):

### Install Terminal-Icons (get LiterationMono NF Nerd font, install, add required Console registry key, then install required Modules)
$url = 'https://github.com/haasosaurus/nerd-fonts/raw/regen-mono-font-fix/patched-fonts/LiberationMono/complete/Literation%20Mono%20Nerd%20Font%20Complete%20Mono%20Windows%20Compatible.ttf'
$name = "LiterationMono NF"
$file = "$($env:TEMP)\$($name).ttf"
# Install-Module BitsTransfer   # Could be required on PS v2
Start-BitsTransfer -Source $url -Destination $file   # Download the font

$Install = $true  # $false to uninstall (or 1 / 0)
$FontsFolder = (New-Object -ComObject Shell.Application).Namespace(0x14)   # Must use Namespace part or will not install properly
$filename = (Get-ChildItem $file).Name
$filepath = (Get-ChildItem $file).FullName
$target = "C:\Windows\Fonts\$($filename)"

If (Test-Path $target -PathType Any) { Remove-Item $target -Recurse -Force } # UnInstall Font

If ((-not(Test-Path $target -PathType Container)) -and ($Install -eq $true)) { $FontsFolder.CopyHere($filepath, 16) }   # Following action performs the install, requires user to click on yes

$key = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont'   # Need to set this for console
Set-ItemProperty -Path $key -Name '000' -Value $name

Write-Host "Install-Module Terminal-Icons (Advanced Coloured dir / ls / gci listings with icons)" -ForegroundColor Yellow -BackgroundColor Black
Write-Host "   Add-TerminalIconsColorTheme, Add-TerminalIconsIconTheme, Format-TerminalIcons,"
Write-Host "   Get-TerminalIconsColorTheme, Get-TerminalIconsIconTheme, Get-TerminalIconsTheme,"
Write-Host "   Set-TerminalIconsColorTheme, Set-TerminalIconsIconTheme, Show-TerminalIconsTheme"
Write-Host "View Module Contents: " -NoNewLine ; Write-Host "get-command -module terminal-icons" -ForegroundColor Yellow

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force   # Always need this, required for all Modules
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted   # Set Microsoft PowerShell Gallery to 'Trusted'
Install-Module Terminal-Icons -Scope CurrentUser
Import-Module Terminal-Icons
Install-Module WindowsConsoleFonts
Set-ConsoleFont $name
Set-TerminalIconsColorTheme -Name DevBlackOps   # After the above are setup, can add this to line to $Profile to always load

0
这些天还不错,powershell 7.3.8。在OSX中,目录名称几乎无法阅读(蓝色背景),所以:
$psstyle.fileinfo.directory = $psstyle.background.brightcyan

所有的选项和基本颜色选择都在$psstyle中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接