1. <dd id="erndk"></dd>
                1. PowerShell筆記 - 8.函數

                  互聯網 2021/9/16 7:07:47

                  本系列是一個重新學習PowerShell的筆記,內容引用自PowerShell中文博客 處理函數的參數 Powershell函數可以接受參數,并對參數進行處理。函數的參數有3個特性:任意參數:內部變量\(args 接受函數調用時接受的參數,\)args是一個數組類型。 命名參數:函數的每一個參數可…

                  本系列是一個重新學習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
                  
                  隨時隨地學軟件編程-關注百度小程序和微信小程序
                  關于找一找教程網

                  本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
                  本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
                  [PowerShell筆記 - 8.函數]http://www.yachtsalesaustralia.com/tech/detail-228809.html

                  贊(0)
                  關注微信小程序
                  程序員編程王-隨時隨地學編程

                  掃描二維碼或查找【程序員編程王】

                  可以隨時隨地學編程啦!

                  技術文章導航 更多>
                  国产在线拍揄自揄视频菠萝

                        1. <dd id="erndk"></dd>