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