• PowerShell笔记


    本系列是一个重新学习PowerShell的笔记,内容引用自PowerShell中文博客

    处理函数的参数

    Powershell函数可以接受参数,并对参数进行处理。函数的参数有3个特性:

    1. 任意参数:内部变量(args 接受函数调用时接受的参数,)args是一个数组类型。
    2. 命名参数:函数的每一个参数可以分配一个名称,在调用时通过名称指定对应的参数。
    3. 预定义参数:函数在定义参数时可以指定默认值,如果调用时没有专门指定参数的值,就会保持默认值。

    万能参数$args

    (args 万能参数 给一个函数定义参数最简单的是使用)args这个内置的参数。
    它可以识别任意个参数。尤其适用哪些参数可有可无的函数。

    function sayHello
    {
        if($args.Count -eq 0)
        {
            "No argument!"
        }
        else
        {
            $args | foreach {"Hello,$($_)"}
        }
    }
    
    Write-Host -ForegroundColor "Red" "无参数调用"
    
    sayHello
    
    
    Write-Host -ForegroundColor "Red" "一个或多个参数调用"
    sayHello hua
    sayHello hua hua
    
    PS C:PowerShell>test.ps1                                                                                                                                                 无参数调用
    No argument!
    一个或多个参数调用
    Hello,hua
    Hello,hua
    Hello,hua
    

    指定参数名及默认值

    function Test($Str1 = "Hua",$str2 = "Hua") {
        $Str1 + $str2
    }
    Test
    Test -Str1 "h" -str2 "ua"
    
    PS C:PowerShell>test.ps1                                                                                                                                                 HuaHua
    hua
    

    指定参数类型

    
    function SetDate([DateTime]$Date,[int]$Days = 0,[string]$Description = "无") {   
        Write-Host -ForegroundColor "Green" $Date.Day
        $Date.AddDays($Days)
        Write-Host -ForegroundColor "Red" $Date.Day
        Write-Host -ForegroundColor "Red" $Description
    }
    
    SetDate '2020-01-01'
    SetDate '2020-11-01' -Days 6 -Description "HuaHua"
    #输入错误的日期
    SetDate '2020-15-01' -Days 6 -Description "HuaHua"
    
    PS C:PowerShell>test.ps1                                                                                                                                                 1
    
    2020年1月1日 0:00:00
    1
    无
    1
    2020年11月7日 0:00:00
    1
    HuaHua
    SetDate : Cannot process argument transformation on parameter 'Date'. Cannot convert value "2020-15-01" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
    At test.ps1:11 char:9
    

    Switch 参数

    Powershell函数最简单的参数类型为布尔类型,除了使用Bool类型,也可以使用Switch关键字。
    下面的函数逆转字符串,但是可以通过(try 参数进行控制,如果没有指定)try的值,默认值为$false

    function  tryReverse( [switch]$try , [string]$source )
    {
        [string]$target=""
        if($try)
        {
            for( [int]$i = $source.length -1; $i -ge 0 ;$i--)
            {
                $target += $source[$i]
            }
            return $target
        }
        return $source
    }
    tryReverse -source www.mossfly.com
    tryReverse -try $true -source www.mossfly.com
    
    PS C:PowerShell> test.ps1                                                                                                                                                 www.mossfly.com
    moc.ylfssom.www
    

    指定函数的返回值

    一个或多个返回值

    Powershell不像它编程语言,它的函数可以有多个返回值。如果你直接调用函数,返回值会在控制台输出。当然你也可以将结果存储在一个变量中进一步处理。
    下面的例子演示返回一个值:

    function GetDate() {   
     return Get-Date
    }
    GetDate
    $d = GetDate
    $d.GetType().FullName
    
    PS C:PowerShell> test.ps1                                                                                                                                                 
    2021年9月14日 15:27:28
    System.DateTime
    
    

    下面的例子演示返回多个值

    function GetDate() {   
        $v = Get-Date
        $v.Year
        $v.Month
        $v.Day
    }
    GetDate
    $d = GetDate
    $d.GetType().FullName
    $d.Count
    $d[0]
    
    PS C:PowerShell> test.ps1                                                                                                                                                 2021
    9
    14
    System.Object[]
    3
    2021
    
    

    总结一下,如果一个函数返回一个值,像其它编程语言一样,这个值包括她的类型信息会直接返回。但是如果遇到多个返回值,Powershell会将所有的返回值自动构造成一个Object数组。可以通过索引访问数组。

    Return语句

    Powershell会将函数中所有的输出作为返回值,但是也可以通过return语句指定具体的我返回值。
    Return 语句会将指定的值返回,同时也会中断函数的执行,return后面的语句会被忽略。

    function GetDate() {   
        $v = Get-Date
        $v.Year
      return  $v.Month
        $v.Day
    }
    GetDate
    $d = GetDate
    $d.GetType().FullName
    $d.Count
    
    #return 语句之后的Day没有返回被截断
    PS C:PowerShell> test.ps1                                                                                                                                                 2021
    9
    System.Object[]
    

    访问返回值

    一个函数返回了一个值还是多个值,是可以验证的。下面的例子会产生随机数,如果没有指定个数,默认会返回一个随机数,否则会返回指定个数的随机数。
    
    Function lottery([int]$number=1)
    {
    $rand = New-Object system.random
    For ($i=1; $i -le $number; $i++) {
    $rand.next(1,50)
    }
    }
    # 参数为空时,返回值不是数组:
    $result = lottery
    $result -is [array]
    # False
    # 如果指定多个随机数是,返回值是数组类型:
    $result = lottery 10
    $result -is [array]
    
    PS C:PowerShell> test.ps1                                                                                                                                                 False
    True
    

    从函数的返回值中消除输出

    函数默认会将函数中的所有输出作为函数的返回值返回,这样很方便。但有时可能会将不必要的输出误以为返回值。写脚本程序时,可能需要自定义一些函数,这个函数可能只需要一个返回值,但是为了提高函数的可读性,可能会在函数增加一些注释输出行。

    Function Test()
    {
        "Try to calculate."
        "3.1415926"
        "Done."
    }
     
    #保存在变量中输出,
    $value=Test
    $value
    # Try to calculate.
    # 3.1415926
    # Done.
     
    #如果要过滤注释,只输出,不作为返回值,
    #可以使用Write-Host命令
    Function Test()
    {
        Write-Host "Try to calculate."
        "3.1415926"
        Write-Host "Done."
    }
    # 在变量值中保存返回值,在控制台输出注释行
    $value=Test
    # Try to calculate.
    # Done.
     
    # 测试返回值
    $value
    # 3.1415926
    

    使用调试信息报告

    可能输出这些函数中临时提示信息,给函数的返回值造成干扰。要解决这个问题,除了上述的Write-Host,也可以使用Write-Debug命令。

    Function Test()
    {
        Write-Debug "Try to calculate."
        "3.1415926"
        Write-Debug "Done."
    }
    # Debug调试信息只会在调试模式下被输出
    $value=Test
    # 3.1415926
     
    #如果你想通过显示调试信息调试函数,可以开启调试模式
    $DebugPreference="Continue"
    $value=Test
    # 调试: Try to calculate.
    # 调试: Done.
     
    # 测试返回值
    $value
    # 3.1415926
     
    #如果关闭调试模式,这些调试信息自然不会输出
    $DebugPreference="SilentlyContinue"
    $value=Test
    

    使用Write-Debug有两个优势,首先调试信息会自动高亮显示,便于分析。其次,这些调试信息只会在调试模式开启时输出,控制起来更加方便。当然最重要的是这些临时信息无论什么时候也不会混淆在返回值。

    抑制错误信息

    函数中的错误信息,也有可能作为返回值的一部分,因为默认这些错误信息会直接输出。

    Function ErrorTest()
    {
        #该进程不存在
        Stop-Process -Name "www.mossfly.com"
    }
    ErrorTest
     
    Stop-Process : 找不到名为“www.mossfly.com”的进程。请验证该进程名称,然后再次调用 cmdlet。
    所在位置 C:UsersbaozhenDesktoptest.ps1:6 字符: 17
    +     Stop-Process <<<<  -Name "www.mossfly.com"
        + CategoryInfo          : ObjectNotFound: (www.mossfly.com:String) [Stop-P
       rocess], ProcessCommandException
        + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.
       Commands.StopProcessCommand
     
     很明显,类似这样的错误提示信息,对调试程序很重要,但如果你觉得它不重要,特意要隐藏,可以使用$ErrorActionPreference进行设置。
     
     Function ErrorTest()
    {
        #从这里开始隐藏所有的错误信息
        $ErrorActionPreference="SilentlyContinue"
        Stop-Process -Name "www.mossfly.com"
        #该进程不存在
    }
     
    #错误信息不会输出
    ErrorTest
    

    但是上面的做法并不明智,因为这样可能错过其它错误提示。所以最好的方式是处理完后,对$ErrorActionPreference进行复位。

    Function ErrorTest()
    {
        #从这里开始隐藏所有的错误信息
        $ErrorActionPreference="SilentlyContinue"
        Stop-Process -Name "www.mossfly.com"
        #该进程不存在
     
        #恢复$ErrorActionPreference,错误开始输出
        $ErrorActionPreference="Continue"
     
        2/0
    }
    ErrorTest
    试图除以零。
     
    所在位置 行:9 字符: 7
    + 2/ <<<< 0
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RuntimeException
    

    查看支持的函数

    Powershell已经提供了许多用户能够使用的预定义函数,这些函数可以通过Function:PSDrive虚拟驱动器查看。

    PS C:PowerShell> Get-ChildItem function: | Format-Table Name,Definition                                                                                                                     
    Name                      Definition
    ----                      ----------
    A:                        Set-Location $MyInvocation.MyCommand.Name
    B:                        Set-Location $MyInvocation.MyCommand.Name
    C:                        Set-Location $MyInvocation.MyCommand.Name
    cd..                      Set-Location ..
    cd                       Set-Location 
    Clear-Host                ...
    ConvertFrom-SddlString    ...
    D:                        Set-Location $MyInvocation.MyCommand.Name
    E:                        Set-Location $MyInvocation.MyCommand.Name
    F:                        Set-Location $MyInvocation.MyCommand.Name
    Format-Hex                ...
    G:                        Set-Location $MyInvocation.MyCommand.Name
    Get-FileHash              ...
    Get-Verb                  ...
    H:                        Set-Location $MyInvocation.MyCommand.Name
    help                      ...
    I:                        Set-Location $MyInvocation.MyCommand.Name
    Import-PowerShellDataFile ...
    ImportSystemModules
    J:                        Set-Location $MyInvocation.MyCommand.Name
    K:                        Set-Location $MyInvocation.MyCommand.Name
    L:                        Set-Location $MyInvocation.MyCommand.Name
    M:                        Set-Location $MyInvocation.MyCommand.Name
    mkdir                     ...
    more                      ...
    N:                        Set-Location $MyInvocation.MyCommand.Name
    New-Guid                  ...
    New-TemporaryFile         ...
    O:                        Set-Location $MyInvocation.MyCommand.Name
    oss                       ...
    P:                        Set-Location $MyInvocation.MyCommand.Name
    Pause                     $null = Read-Host 'Press Enter to continue...'
    prompt                    ...
    PSConsoleHostReadLine     ...
    Q:                        Set-Location $MyInvocation.MyCommand.Name
    R:                        Set-Location $MyInvocation.MyCommand.Name
    S:                        Set-Location $MyInvocation.MyCommand.Name
    T:                        Set-Location $MyInvocation.MyCommand.Name
    TabExpansion2             ...
    U:                        Set-Location $MyInvocation.MyCommand.Name
    V:                        Set-Location $MyInvocation.MyCommand.Name
    W:                        Set-Location $MyInvocation.MyCommand.Name
    X:                        Set-Location $MyInvocation.MyCommand.Name
    Y:                        Set-Location $MyInvocation.MyCommand.Name
    Z:                        Set-Location $MyInvocation.MyCommand.Name
    

    从这些结果不但能够看出函数的名称,还能通过Definition列查看函数的内容。如果你想深入查看函数的内部定义可以直接访问Function:

    PS C:PowerShell> $function:prompt                                                                                                                                                           
    "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";
    # .Link
    # https://go.microsoft.com/fwlink/?LinkID=225750
    # .ExternalHelp System.Management.Automation.dll-help.xml
    
    

    Powershell中的这些预定义的函数可以做很多重要的工作。

    Clear-Host 清除屏幕的缓存
    help,man 查看命令的帮助文档
    mkdir,md 通过new-Item创建子目录
    more 分屏输出管道结果
    prompt 返回提示文本
    TabExpansion Tab键的自动完成提示
    X: 调用Set-Location定位到指定的驱动器根目录
    如果你想查看当前Powershell环境中定义了多少个函数可以通过:

    PS C:PowerShell> (Dir function:).Count                                                                                                                                                      45
    

    自定义Prompt

    每次成功执行完一条命令,Powershell就会执行Prompt函数,提示用户进行下一步输入。
    默认设置中,prompt显示“PS” 和当前的工作目录。
    再接着是”>”或”>>”,具体情况要看当前Powershell控制台的的层数。
    当然你可以自定义prompt的,那就得覆盖prompt函数:

    PS C:PowerShell> pwd                                                                                                                                                                        
    Path
    ----
    C:PowerShell
    
    
    PS C:PowerShell> Function prompt{"Hua Hua"}                                                                                                                                                 Hua Hua                                                                                                                                                                                      Hua Huapwd                                                                                                                                                                                   
    Path
    ----
    C:PowerShell
    
    
    Hua Hua 
    

    这样的覆盖安全吗,显然安全,对预定义函数的重写,只会在当前控制台会话中有效,当你重新启动控制台时,自然会恢复如初。

    在控制台的任何位置输出文本(自定义光标的位置)
    因为控制台的内容存放在控制台屏幕的缓存中,因此你可以逐个访问内容的每一行或每一个字符。
    你甚至可以在控制台的屏幕的任何位置输出你想要输出的信息,接下来的函数会演示这个功能。
    要完成这个功能,需要使用$Host.UI.Rawui ,光标的位置通过屏幕的横坐标(X)和纵坐标(Y)确定,下面的函数会首先记住当前光标的位置,然后在横坐标上增加60个占位符,然后重置光标的位置至当前位置,最后通过prompt函数回复光标的原始位置。

    Hua H> function prompt
    >> {
    >>     $curPos = $host.ui.rawui.CursorPosition
    >>     $newPos = $curPos
    >>     $newPos.X+=60
    >>     $host.ui.rawui.CursorPosition = $newPos
    >>     Write-Host ("{0:D} {0:T}" -f (Get-Date)) -foregroundcolor Yellow
    >>     $host.ui.rawui.CursorPosition = $curPos
    >>     Write-Host ("PS " + $(get-location) +">") -nonewline -foregroundcolor Green
    >> " "
    >> }                                                                                                                                                                                         PS C:PowerShell>                                           2021年9月14日 16:57:04
    

    使用窗口标题栏

    在Windows控制台的标题栏有一部分空间,可以放置一些有用的信息,比如当前哪个用户登录在控制台,可以通过设置$host.UI.RawUI.WindowTitle来自定义控制台标题栏的文本。
    下面的例子就会演示设置标题栏文本,通过.NET方法获取当前用户信息,由于该方法会有几秒钟执行时间,为了效率考虑首先将用户信息保存在全局变量中,然后在Prompt函数中调用。

    $global:CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    function prompt
    {
    $host.ui.rawui.WindowTitle = "Line: " + $host.UI.RawUI.CursorPosition.Y + " " + $CurrentUser.Name + " " + $Host.Name + " " + $Host.Version
    Write-Host ("PS " + $(get-location) +">")  -nonewline -foregroundcolor Green
    return " "
    }
    

    执行以后在标题栏会显示:Line: 72 ComputerNameuser ConsoleHost 2.0
    如果你使用管理员权限运行控制台时,Prompt函数还可以给出警告。使用WindowsPrincipal 辨别当前用户是否使用了管理员权限,你不需要了解下面的.NET代码,它会在全局变量中将布尔值赋值给$Admin。

    $CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = new-object System.Security.principal.windowsprincipal($CurrentUser)
    $global:Admin = $principal.IsInRole( [System.Security.Principal.WindowsBuiltInRole]::Administrator)
    Function prompt
    {
        # 输出标准的提示信息:
        Write-Host ("PS " + $(get-location)) -nonewline
        # The rest depends on whether you have admin rights or not:
        If ($admin)
        {
            $oldtitle = $host.ui.rawui.WindowTitle
            # 将"Administrator: " 显示在标题栏
            If (!$oldtitle.StartsWith("Administrator: "))
            {
                $host.ui.rawui.WindowTitle ="Administrator: " + $oldtitle
            }
            #  Prompt结尾显示红色的尖括号
            Write-Host ">" -nonewline -foregroundcolor Red
         }
         Else
         {
            Write-Host ">" -nonewline
          }
         return " "
    }
    

    没有管理员权限时,标题栏文本:Windows Powershell
    有管理员权限时,标题栏文本:Administrator :管理员 : Windows Powershell

    Clear-Host:删除屏幕缓存

    很可能,你已经注意到了,cls可以删除屏幕的缓存。
    事实上,cls只是Clear-Host函数的别名,但是却看不到这个函数的内容。

    PS C:PowerShell> $function:Clear-Host
    At line:1 char:16
    + $function:Clear-Host
    +                ~~~~~
    Unexpected token '-Host' in expression or statement.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken
    

    在Powershell中短斜杠是个特殊字符,如果一个函数名中包含了特殊字符就应当把它放在花括号中。

    PS C:PowerShell> ${function:Clear-Host}                    
    
    $RawUI = $Host.UI.RawUI
    $RawUI.CursorPosition = @{X=0;Y=0}
    $RawUI.SetBufferContents(
        @{Top = -1; Bottom = -1; Right = -1; Left = -1},
        @{Character = ' '; ForegroundColor = $rawui.ForegroundColor; BackgroundColor = $rawui.BackgroundColor})
    # .Link
    # https://go.microsoft.com/fwlink/?LinkID=225747
    # .ExternalHelp System.Management.Automation.dll-help.xml
    

    盘符名预定义函数C:,D:,E:

    这些盘符名称可以作为单独的一个函数,是怎么做到的呢?

    PS C:PowerShell> $function:C:                              
    Set-Location $MyInvocation.MyCommand.Name
    

    函数过滤器、管道

    一个函数能够访问和进一步处理另外一条命令的结果吗?答案是肯定的,这被称为管道。管道有两种模式,一种是顺序处理模式,一种是流处理模式。

    低效率的顺序模式:$input

    在最简单的情况下,你的函数不是真正支持管道。只能对前一个命令执行后的结果处理。前一个命令执行的结果通过被自动保存在$input变量中,$input是一个数组,它可以包含许多元素,一个元素,甚至一个元素都没有,这取决于具体的环境。

    下面的例子,是一个函数,仅仅输出$input的内容。

    PS C:PowerShell> function OutPut {
    >>    $input
    >> }                                                                                                                    PS C:PowerShell> 1,2,3 | OutPut                                                                                        1
    2
    3
    
    PS C:PowerShell> "222",1 | OutPut                                                                                      222
    1
    PS C:PowerShell> dir | OutPut                                                                                          
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/14     13:51             58 test.txt
    

    到目前为止,这个函数只是仅仅输出了管道的结果,并没有其它比较强大的功能。
    在接下来的例子中,函数将会对管道的结果做进一步处理。函数名MarkEXE,将会检查Dir的结果,并高亮标记后缀名为EXE的文件名为红色。

    Function MarkEXE {
        # 保存控制台当前的前景色
        $oldcolor = $host.ui.rawui.ForegroundColor
        # 通过循环逐条检查管道的结果
        Foreach ($element in $input) {
            # 如果后缀名为.exe,设置为前景色为红色
            If ($element.name.toLower().endsWith(".exe")) {
                $host.ui.Rawui.ForegroundColor = "red"
            }
            Else {
                # 否则恢复默认的前景色
                $host.ui.Rawui.ForegroundColor = $oldcolor
            }
            # 输出数组元素
            $element
        }
        # 最后,重置控制台的前景色:
        $host.ui.Rawui.ForegroundColor = $oldcolor
    }
    
    Dir | MarkEXE
    
    PS C:PowerShell> New-Item test.exe                                                                                     
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/15     10:46              0 test.exe
    
    
    PS C:PowerShell> ls                                                                                                    
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/15     10:46              0 test.exe
    -a----        2021/9/14     13:51             58 test.txt
    
     PS C:PowerShell> test.ps1                                                                            
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/15     10:46              0 test.exe
    -a----        2021/9/14     13:51             58 test.txt
    

    过滤器:高效率 流模式

    管道的低效率顺序模式在处理大容量数据时很容易出现问题,其结果是巨大的内存占用和进程等待。
    如果你的函数支持高效率的流模式,在处理管道结果时仅占用很小的内存。
    事实上,针对之前MarkEXE函数,你只需要替换”function” 关键字 为 “filter”它就会开始流模式处理,这样你再也不用过分的担心忍受程序的无休止的响应和崩溃的危险。
    你也可以递归处理全盘目录,甚至处理极其庞大的数据。例如:

    PS C:PowerShell> Dir C:PowerShell -recurse | MarkEXE
    

    当MarkEXE每次被调用时,它只会对当前目录下的每个单独的元素进行处理。
    对于过滤器filters来说,$input 一直都是一个独立的元素。
    这也就是为什么在过滤器中$input一点用也没有的道理。
    此时,最好使用$_ 变量,因为它代表了当前处理的数据。
    这样还可以简化MarkExe,因为过滤器自身已经扮演了循环的角色了,你没有必要再写专门的循环处理了。

    Filter MarkEXE
    {
        # 记录当前控制台的背景色
        $oldcolor = $host.ui.rawui.ForegroundColor
        # 当前的管道元素保存在 $_ 变量中
        # 如果后缀名为 ".exe",
        # 改变背景色为红色:
        If ($_.name.toLower().endsWith(".exe"))
        {
            $host.ui.Rawui.ForegroundColor = "red"
        }
        Else
        {
            # 否则使用之前的背景色
            $host.ui.Rawui.ForegroundColor = $oldcolor
        }
        # 输出当前元素
        $_
        # 最后恢复控制台颜色:
        $host.ui.Rawui.ForegroundColor = $oldcolor
    }
    
    Dir | MarkEXE
    
    PS C:PowerShell> test.ps1                                                                            
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/15     10:46              0 test.exe
    -a----        2021/9/14     13:51             58 test.txt
    

    开发真正的管道函数

    过滤器在函数中属于高级应用,因为它可以立即处理管道结果的每一个元素。但是过滤器必须每次重复执行预定义命令的结果。
    对于MarkEXE 函数,每次执行的过程中要记录和更新控制台的背景颜色,也要花费资源和时间。
    事实上,过滤器只是特殊的函数。如果一个函数内部使用了管道,你就可以定义三个基础的任务区了:第一步,完成函数的初始化,完成函数执行的预备步骤;第二步处理递归调用所得的结果;最后进行收尾工作。
    这三个任务区分别可以使用begin,process,end 语句块。

    function MarkEXE {  
        
        begin {
            # 记录当前控制台的背景色
            $oldcolor = $host.ui.rawui.ForegroundColor
            
        }
        
        process {
            # 当前的管道元素保存在 $_ 变量中
            # 如果后缀名为 ".exe",
            # 改变背景色为红色:
            If ($_.name.toLower().endsWith(".exe")) {
                $host.ui.Rawui.ForegroundColor = "red"
            }
            Else {
                # 否则使用之前的背景色
                $host.ui.Rawui.ForegroundColor = $oldcolor
            }
            # 输出当前元素
            $_
        }
        
        end {
            # 最后恢复控制台颜色:
            $host.ui.Rawui.ForegroundColor = $oldcolor
        }
    }
    
    
    Dir | MarkEXE
    
    PS C:PowerShell> test.ps1                                                                            
    
        Directory: C:PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2021/9/15     10:46              0 test.exe
    -a----        2021/9/14     13:51             58 test.txt
    
  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/MerLin-LiuNian/p/15271780.html
Copyright © 2020-2023  润新知