about_Scripts
介绍如何在 PowerShell 中运行和编写脚本。
脚本是包含一个或多个 PowerShell 命令的纯文本文件。
PowerShell 脚本具有 .ps1
文件扩展名。
运行脚本非常类似于运行 cmdlet。 键入脚本的路径和文件名,并使用参数提交数据和设置选项。 可以在计算机上或在另一台计算机上的远程会话中运行脚本。
编写脚本可保存命令供以后使用,并便于与他人共享。 最重要的是,只需键入脚本路径和文件名即可运行命令。 脚本可以像文件中的单个命令一样简单,也可以像复杂程序一样广泛。
脚本具有其他功能,例如 #Requires
特殊注释、参数的使用、对数据部分的支持以及用于安全性的数字签名。
还可以为脚本和脚本中的任何函数编写帮助主题。
在 Windows 上运行脚本之前,需要更改默认的 PowerShell 执行策略。 执行策略不适用于非 Windows 平台上运行的 PowerShell。
默认执行策略 Restricted
会阻止所有脚本运行,包括在本地计算机上编写的脚本。 有关更多信息,请参阅 about_Execution_Policies。
执行策略保存在注册表中,因此只需在每台计算机上更改一次。
若要更改执行策略,请使用以下过程。
在命令提示符下,键入:
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
作为一项安全功能,即使脚本位于当前目录中,PowerShell 也不会在文件资源管理器中双击脚本图标或键入脚本名称而不使用完整路径时运行脚本。 有关在 PowerShell 中运行命令和脚本的详细信息,请参阅 about_Command_Precedence。
从 PowerShell 3.0 开始,可以从文件资源管理器运行脚本。
若要使用“通过 PowerShell 运行”功能,请执行以下操作:
运行文件资源管理器,右键单击脚本文件名,然后选择“使用 PowerShell 运行”。
“使用 PowerShell 运行”功能旨在运行没有所需参数的脚本,并且不会将输出返回到命令提示符。
有关详细信息,请参阅 about_Run_With_PowerShell。
若要在一个或多个远程计算机上运行脚本,请使用 cmdlet 的 Invoke-Command
参数。
输入脚本的路径和文件名作为 FilePath 参数的值。 该脚本必须驻留在本地计算机或本地计算机可以访问的目录中。
以下命令在名为 Server01 和 Server02 的远程计算机上运行 Get-ServiceLog.ps1
脚本。
$invokeCommandSplat = @{
ComputerName = 'Server01', 'Server02'
FilePath = 'C:\Scripts\Get-ServiceLog.ps1'
}
Invoke-Command @invokeCommandSplat
Get-Help cmdlet 可获取脚本以及 cmdlet 和其他类型命令的帮助主题。 若要获取脚本的帮助主题,请键入 Get-Help
后跟脚本的路径和文件名。 如果脚本路径位于 Path
环境变量中,则可以省略该路径。
例如,若要获取 ServicesLog.ps1 脚本的帮助,请键入:
Get-Help C:\admin\scripts\ServicesLog.ps1
脚本可以包含任何有效的 PowerShell 命令,包括单个命令、使用管道、函数和控件结构的命令,例如 If 语句和 For 循环。
若要编写脚本,请在文本编辑器中打开一个新文件,键入命令,并使用具有 .ps1
文件扩展名的有效文件名将其保存在文件中。
以下示例是一个简单的脚本,用于获取当前系统上运行的服务并将其保存到日志文件。 日志文件名是从当前日期创建的。
$date = (Get-Date).DayOfYear
Get-Service | Out-File "$date.log"
若要创建此脚本,请打开文本编辑器或脚本编辑器,键入这些命令,然后将其保存在名为 ServiceLog.ps1
的文件中。
若要在脚本中定义参数,请使用 Param 语句。
Param
语句必须是脚本中的第一个语句,注释和任何 #Require
语句除外。
脚本参数的工作方式类似于函数参数。 参数值可用于脚本中的所有命令。 函数参数的所有功能(包括 Parameter 属性及其命名参数)在脚本中也有效。
运行脚本时,脚本用户键入脚本名称后的参数。
以下示例演示具有 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 的帮助的详细信息,请参阅 如何编写 Cmdlet 帮助。
默认情况下,脚本在脚本结束时不返回退出状态。 必须使用 exit
语句从脚本返回退出代码。 默认情况下,exit
语句返回 0
。 可以提供一个数值来返回不同的退出状态。 非零退出代码通常表示失败。
在 Windows 上,允许 [int]::MinValue
和 [int]::MaxValue
之间的任意数字。
在 Unix 上,只允许 [byte]::MinValue
(0)和 [byte]::MaxValue
(255)之间的正数。
-1
到 -255
范围内的负数通过添加 256 自动转换为正数。例如,-2
转换为 254
。
在 PowerShell 中,exit
语句设置 $LASTEXITCODE
变量的值。 在 Windows Command Shell(cmd.exe)中,exit 语句设置 %ERRORLEVEL%
环境变量的值。
非数值或超出平台特定范围的任何参数都会转换为 0
的值。
每个脚本在其自己的范围内运行。 脚本中创建的函数、变量、别名和驱动器仅存在于脚本范围内。 无法在运行脚本的作用域中访问这些项或其值。
要在不同的作用域内运行脚本,可以指定作用域,例如全局或本地,也可以点源脚本。
通过点源功能,可以在当前作用域而不是脚本作用域中运行脚本。 运行以点为源的脚本时,脚本中的命令会像在命令提示符处键入一样运行。 脚本创建的函数、变量、别名和驱动器是在正在使用的作用域中创建的。 运行脚本后,可以使用创建的项并在会话中访问其值。
若要对脚本进行脚本点源,请在脚本路径前键入点 (.) 和空格。
例如:
. C:\scripts\UtilityFunctions.ps1
或
. .\UtilityFunctions.ps1
运行 UtilityFunctions.ps1
脚本后,脚本创建的函数和变量将添加到当前范围。
例如,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 "Profile $profileName already exists on this computer."}
else
{New-Item -Type file -Path $PROFILE -Force }
}
如果在自己的脚本范围内运行 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。
模块是一组可以作为单元分发的相关 PowerShell 资源。 可以使用模块来组织脚本、函数和其他资源。 还可以使用模块将代码分发给其他人,以及从受信任的源获取代码。
可以在模块中包含脚本,也可以创建一个脚本模块,这是一个模块,它完全或主要是由脚本和支持的资源组成。 脚本模块只是扩展名为 .psm1 的脚本。
有关模块的详细信息,请参阅 about_Modules。
PowerShell 具有许多可用于脚本的有用功能。
#Requires
- 可以使用#Requires
语句来防止脚本在没有指定的模块或管理单元和指定版本的 PowerShell 的情况下运行。 有关详细信息,请参阅 about_Requires。$PSCommandPath
- 包含正在运行的脚本的完整路径和名称。 此参数在所有脚本中均有效。 PowerShell 3.0 中引入了此自动变量。$PSScriptRoot
- 包含运行脚本的目录。 在 PowerShell 2.0 中,此变量仅在脚本模块(.psm1
)中有效。 从 PowerShell 3.0 开始,它在所有脚本中都有效。$MyInvocation
-$MyInvocation
自动变量包含有关当前脚本的信息,包括有关如何启动或“调用”的信息。可以使用此变量及其属性在运行脚本时获取有关脚本的信息。 例如,$MyInvocation
。MyCommand.Path 变量包含脚本的路径和文件名。$MyInvocation
。Line 包含启动脚本的命令,包括所有参数和值。从 PowerShell 3.0 开始,
$MyInvocation
有两个新属性,提供有关调用当前脚本的脚本的信息。 仅当调用者或调用方是脚本时,才会填充这些属性的值。PSCommandPath 包含调用当前脚本的那个脚本的完整路径和名称。
PSScriptRoot 包含调用或引入当前脚本的脚本的目录。
与包含当前脚本信息的
$PSCommandPath
和$PSScriptRoot
自动变量不同,PSCommandPath 和$MyInvocation
属性包含有关调用当前脚本的脚本的信息。数据部分 - 可以使用
Data
关键字将数据与脚本中的逻辑分开。 数据部分还可以简化本地化。 有关详细信息,请参阅 about_Data_Sections 和 about_Script_Internationalization。脚本签名 - 可以向脚本添加数字签名。 根据执行策略,可以使用数字签名来限制可能包含不安全命令的脚本的运行。 有关详细信息,请参阅 about_Execution_Policies 和 about_Signing。