about_Scripts

適用於: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0

主題

about_Scripts

簡短描述

描述如何在 Windows PowerShell® 中執行並撰寫指令碼。

詳細描述

指令碼是內含一或多個 Windows PowerShell 命令的純文字檔。Windows PowerShell 指令碼的副檔名是 .ps1。

執行指令碼與執行 Cmdlet 非常類似。您可輸入指令碼路徑和檔名,並使用參數來送出資料和設定選項。您可以在您的電腦上或不同電腦上的遠端工作階段中執行指令碼。

撰寫指令碼可儲存命令供日後使用,也能讓您輕鬆地與其他人共用。最重要的是,您只需要輸入指令碼路徑和檔名就可以執行命令。指令碼可以很簡單如檔案中的單一命令,也可以是複雜完整的程式。

指令碼還有其他功能,例如 #Requires 特殊註解、使用參數、支援資料區段,以及安全性數位簽章等。您也可以撰寫指令碼和指令碼中任何函式的「說明」主題。

如何執行指令碼

您必須先變更預設的 Windows PowerShell 執行原則才能執行指令碼。預設執行原則是「限制」,表示所有指令碼都無法執行,包括您在本機電腦撰寫的指令碼。如需詳細資訊,請參閱 about_Execution_Policies。

執行原則會儲存在登錄中,因此您只需在每部電腦上變更一次即可。

若要變更執行原則,請使用下列程序。

  • 1. 使用 [以系統管理員身分執行] 選項,啟動 Windows PowerShell。

  • 2. 在命令提示字元中輸入:

                Set-ExecutionPolicy AllSigned
    

    - 或者 -

                Set-ExecutionPolicy RemoteSigned
    

變更會立即生效

若要執行指令碼,請輸入指令檔的完整名稱和完整路徑。於此處插入區段主體。

例如,若要執行 C:\Scripts 目錄中的 Get-ServiceLog.ps1 指令碼,請輸入:

        C:\Scripts\Get-ServiceLog.ps1

若要執行目前目錄中的指令碼,請輸入目前目錄的路徑,或是使用點來代表目前的目錄,後面再加上路徑反斜線 (.\)。

例如,若要執行本機目錄中的 ServicesLog.ps1 指令碼,請輸入:

        .\Get-ServiceLog.ps1

如果指令碼有參數,請於指令碼檔案名稱後面輸入參數和參數值。

例如,下列命令會使用 Get-ServiceLog 指令碼的 ServiceName 參數來要求 WinRM 服務活動的記錄。

        .\Get-ServiceLog.ps1 -ServiceName WinRM

當您按兩下檔案總管中的指令碼圖示,或是輸入不含完整路徑的指令碼名稱時,即使指令碼位於目前的目錄,Windows PowerShell 也不會執行指令碼,這是一項安全性功能。如需在 Windows PowerShell 中執行命令和指令碼的詳細資訊,請參閱 about_Command_Precedence。

用 POWERSHELL 執行

從 Windows PowerShell 3.0 開始,您可以從檔案總管 (或舊版 Windows 的 Windows 檔案總管) 執行指令碼。

若要使用 [用 PowerShell 執行] 功能:

在檔案總管 (或 Windows 檔案總管) 中,以滑鼠右鍵按一下指令碼檔案名稱,然後選取 [用 PowerShell 執行]。

[用 PowerShell 執行] 功能的設計目的是用來執行不含必要參數的指令碼,且不會將輸出傳回至命令提示字元。

如需詳細資訊,請參閱 about_Run_With_PowerShell。

在其他電腦上執行指令碼

若要在一或多部遠端電腦上執行指令碼,請使用 Invoke-Command Cmdlet 的 FilePath 參數。

請輸入指令碼的路徑和檔名,做為 Filepath 參數的值。指令碼必須位於本機電腦上,或在本機電腦可以存取的目錄中。

下列命令會在 Server01 和 Server02 遠端電腦執行 Get-ServiceLog.ps1 指令碼。

        Invoke-Command -ComputerName Server01, Server02 -FilePath C:\Scripts\Get-ServiceLog.ps1

取得指令碼的說明

Get-Help Cmdlet 會取得指令碼、Cmdlet 和其他命令類型的說明主題。若要取得指令碼的說明,請輸入 Get-Help 後接指令碼的路徑和檔名。如果指令碼路徑是在 Path 環境變數中,您就可以省略路徑。

例如,若要取得 ServicesLog.ps1 指令碼的說明,請輸入:

        get-help C:\admin\scripts\ServicesLog.ps1

如何撰寫指令碼

指令碼可以包含任何有效的 Windows PowerShell 命令,包括單一命令、使用管線的命令、函式以及控制結構,例如 If 陳述式和 For 迴圈。

若要撰寫指令碼,請啟動文字編輯器 (例如 [記事本]),或指令碼編輯器 (例如 Windows PowerShell 整合式指令碼環境 (ISE))。請輸入命令,並將這些命令儲存在檔名有效且副檔名為 .ps1 的檔案中。

下列範例是一個簡單的指令碼,它會取得目前系統所執行的服務,並將這些服務儲存到記錄檔。記錄檔名稱是從目前的日期開始建立。

        $date = (get-date).dayofyear
        get-service | out-file "$date.log"

若要建立此指令碼,請開啟文字編輯器或指令碼編輯器,輸入這些命令,然後將它們儲存在名為 ServiceLog.ps1 的檔案中。

指令碼中的參數

若要在指令碼中定義參數,請使用 Param 陳述式。除了註解和任何 #Requires 陳述式以外,Param 陳述式必須是指令碼中的第一個陳述式。

指令碼參數的功能與函式參數類似。參數值可供指令碼中的所有命令使用。函式參數 (包括 Parameter 屬性及其具名引數) 的所有功能在指令碼中也都有效。

執行指令碼時,指令碼使用者可在指令碼名稱後面輸入參數。

下列範例會示範具有 ComputerName 參數的 Test-Remote.ps1 指令碼。以下兩個指令碼函式都可以存取 ComputerName 參數值。

        param ($ComputerName = $(throw "ComputerName parameter is required."))

        function CanPing {
           $error.clear()
           $tmp = test-connection $computername -erroraction SilentlyContinue

           if (!$?) 
               {write-host "Ping failed: $ComputerName."; return $false}
           else
               {write-host "Ping succeeded: $ComputerName"; return $true}
        }

        function CanRemote {
            $s = new-pssession $computername -erroraction SilentlyContinue

            if ($s -is [System.Management.Automation.Runspaces.PSSession])
                {write-host "Remote test succeeded: $ComputerName."}
            else
                {write-host "Remote test failed: $ComputerName."}
        }

        if (CanPing $computername) {CanRemote $computername}

若要執行此指令碼,請在指令碼名稱後面輸入參數名稱。例如:

        C:\PS> .\test-remote.ps1 -computername Server01

        Ping succeeded: Server01
        Remote test failed: Server01

如需 Param 陳述式與函式參數的詳細資訊,請參閱 about_Functions 和 about_Functions_Advanced_Parameters。

撰寫指令碼的說明

您可以使用下列兩種方法之一來撰寫指令碼的說明主題:

  • -- 以註解為基礎的指令碼說明

    您可以在註解中使用特殊的關鍵字來建立「說明」主題。若要建立以註解為基礎的指令碼說明,註解必須放在指令檔的開頭或結尾處。如需以註解為基礎之「說明」的詳細資訊,請參閱 about_Comment_Based_Help。

  • -- 以 XML 為基礎的指令碼說明

    您可以建立以 XML 為基礎的「說明」主題,例如通常會為 Cmdlet 所建立的說明類型。如果您要將「說明」主題翻譯成多種語言,就必須使用以 XML 為基礎的「說明」。

    若要將指令碼與 XML 為基礎的「說明」主題相關聯,請使用 ExternalHelp 「說明」註解的關鍵字。如需 ExternalHelp 關鍵字的詳細資訊,請參閱 about_Comment_Based_Help。如需以 XML 為基礎之說明的詳細資訊,請參閱 MSDN (Microsoft Developer Network) 文件庫中的<如何撰寫 Cmdlet 說明>,網址為 https://go.microsoft.com/fwlink/?LinkID=123415。

指令碼範圍和 (.) 來源檔

每個指令碼都是在其個別的範圍內執行。在指令碼中建立的函式、變數、別名和磁碟機都只存在指令碼範圍內,而且您不能在指令碼執行的範圍內存取這些項目或其值。

若要在不同的範圍中執行指令碼,您可以指定範圍 (例如「全域」或「本機」),或是在指令碼前加點。於此處插入區段主體。

(.) 來源檔功能可以讓您在目前的範圍 (而不是在指令碼範圍) 中執行指令碼。當您執行指令碼前加點的指令碼時,指令碼中命令執行的方式就像在命令提示字元輸入命令一樣。指令碼建立函式、變數、別名和磁碟機時,都會在您所使用的範圍內建立。指令碼執行完成之後,您可以在自己的工作階段中使用其建立的項目並存取這些項目的值。

若要在指令碼前加點,請在指令碼路徑前面輸入點 (.) 和空格。

例如:

        . C:\scripts\UtilityFunctions.ps1

- 或者 -

        . .\UtilityFunctions.ps1

UtilityFunctions 指令碼執行完成之後,指令碼所建立的函式和變數便會新增到目前的範圍中。

例如,UtilityFunctions.ps1 指令碼會建立 New-Profile 函式和 $ProfileName 變數。

        #In UtilityFunctions.ps1

        function New-Profile
        {
            Write-Host "Running New-Profile function"
            $profileName = split-path $profile -leaf

            if (test-path $profile)
               {write-error "There is already a $profileName profile on this computer."}
            else
       {new-item -type file -path $profile -force }
        }

如果您在 UtilityFunctions.ps1 指令碼本身的範圍內執行此 UtilityFunctions.ps1 指令碼,New-Profile 函式和 $ProfileName 變數只於指令碼執行期間存在。如下列範例所示,當指令碼結束時,便會移除此函式和變數。

        C:\PS> .\UtilityFunctions.ps1

        C:\PS> New-Profile
        The term 'new-profile' is not recognized as a cmdlet, function, operable
        program, or script file. Verify the term and try again.
        At line:1 char:12
        + new-profile <<<< 
           + CategoryInfo          : ObjectNotFound: (new-profile:String) [], 
           + FullyQualifiedErrorId : CommandNotFoundException

        C:\PS> $profileName
        C:\PS>

當您在指令碼前加點並執行指令碼時,指令碼便會在您的工作階段和範圍中建立 New-Profile 函式和 $ProfileName 變數。指令碼執行完成之後,您即可在自己的工作階段中使用 New-Profile 函式,如下列範例所示。

        C:\PS> . .\UtilityFunctions.ps1

        C:\PS> New-Profile


            Directory: C:\Users\juneb\Documents\WindowsPowerShell


            Mode    LastWriteTime     Length Name                                                                   
            ----    -------------     ------ ----                                                                   
            -a---   1/14/2009 3:08 PM      0 Microsoft.PowerShellISE_profile.ps1                                    


        C:\PS> $profileName
        Microsoft.PowerShellISE_profile.ps1

如需範圍的詳細資訊,請參閱 about_Scopes。

模組中的指令碼

模組是一組相關、可以當做一個單位一起散發的 Windows PowerShell 資源。您可以使用模組來組織指令碼、函式和其他資源。您也可以使用模組將程式碼散發給其他人,以及從信任的來源取得程式碼。

您可以將指令碼包含在模組中,或是建立指令碼模組,也就是完全或主要是由指令碼與輔助資源所組成的模組。指令碼模組只是一個副檔名為 .psm1 的指令碼。

如需有關模組的詳細資訊,請參閱 about_Modules。

其他指令碼功能

Windows PowerShell 具有許多實用的功能,可供您在指令碼中使用。

  • #Requires
    您可以使用 #Requires 陳述式,要求必須有指定的模組或嵌入式管理單元以及指定的 Windows PowerShell 版本時,才能執行指令碼。如需詳細資訊,請參閱 about_Requires。
  • $PSCommandPath
    包含正在執行之指令碼的完整路徑和名稱。這個參數在所有指令碼中皆有效。這個自動變數是在 Windows PowerShell 3.0 中引進。
  • $PSScriptRoot
    包含要從中執行指令碼的目錄。在 Windows PowerShell 2.0 中,此變數只在指令碼模組 (.psm1) 中有效。從 Windows PowerShell 3.0 開始,此變數在所有指令碼中皆有效。
  • $MyInvocation
    $MyInvocation 自動變數包含目前指令碼的相關資訊,包括指令碼的啟動或叫用方法。您可以使用這個變數及其屬性,在指令碼正在執行時,取得其相關資訊。例如,$MyInvocation.MyCommand.Path 變數包含指令碼的路徑和檔名。$MyInvocation.Line 包含啟動指令碼的命令,包括所有參數和值。

    從 Windows PowerShell 3.0 開始,$MyInvocation 具有兩個新屬性,可提供呼叫或叫用目前指令碼的指令碼相關資訊。只有當啟動程式或呼叫端是指令碼時才會填入這些屬性的值。

    • -- PSCommandPath 包含呼叫或叫用目前指令碼的指令碼完整路徑和名稱。

    • -- PSScriptRoot 包含呼叫或叫用目前指令碼的指令碼目錄。

    $MyInvocation 變數的 PSCommandPath 和 PSScriptRoot 屬性包含呼叫或叫用目前指令碼的指令碼相關資訊,因此與 $PSCommandPath 和 $PSScriptRoot 自動變數不同,該自動變數包含目前指令碼的相關資訊。

  • Data 區段
    您可以使用 Data 關鍵字在指令碼中將資料與邏輯分開。Data 區段也可以讓當地語系化變得更加容易。如需詳細資訊,請參閱 about_Data_Sections 和 about_Script_Localization。
  • 指令碼簽署
    您可以為指令碼加上數位簽章。根據執行原則而定,您可以使用數位簽章,在指令碼可能包含不安全的命令時,限制不得執行指令碼。如需詳細資訊,請參閱 about_Execution_Policies 和 about_Signing。

另請參閱

about_Command_Precedence

about_Comment_Based_Help

about_Execution_Policies

about_Functions

about_Modules

about_Profiles

about_Requires

about_Run_With_PowerShell

about_Scopes

about_Script_Blocks

about_Signing

Invoke-Command