关于签名

简短说明

介绍如何对脚本进行签名,使其符合 PowerShell 执行策略。

详细说明

受限执行策略不允许运行任何脚本。 AllSignedRemoteSigned 执行策略阻止 PowerShell 运行没有数字签名的脚本。

本主题说明如何在执行策略为 RemoteSigned 的情况下运行未签名的选定脚本,以及如何为脚本签名以供自己使用。

有关 PowerShell 执行策略的详细信息,请参阅 about_Execution_Policies

允许运行已签名脚本

首次在计算机上启动 PowerShell 时, 受限 执行策略 (默认) 可能生效。

受限策略不允许运行任何脚本。

若要在计算机上查找有效的执行策略,请键入:

Get-ExecutionPolicy

若要运行在本地计算机上编写的未签名脚本和其他用户的签名脚本,请使用“以管理员身份运行”选项启动 PowerShell,然后使用以下命令将计算机上的执行策略更改为 RemoteSigned

Set-ExecutionPolicy RemoteSigned

有关详细信息,请参阅 cmdlet 的 Set-ExecutionPolicy 帮助主题。

(远程签名的执行策略) 运行未签名的脚本

如果 PowerShell 执行策略为 RemoteSigned,Windows PowerShell将不会运行从 Internet 下载的未签名脚本,包括通过电子邮件和即时消息程序收到的未签名脚本。

如果尝试运行下载的脚本,PowerShell 将显示以下错误消息:

The file <file-name> cannot be loaded. The file <file-name> is not digitally
signed. The script will not execute on the system. Please see "Get-Help
about_Signing" for more details.

在运行脚本之前,请查看代码以确保信任它。 脚本与任何可执行程序具有相同的效果。

若要运行未签名的脚本,请使用 Unblock-File cmdlet 或使用以下过程。

  1. 在计算机上保存脚本文件。
  2. 单击“开始”,单击“我的电脑”,并找到保存的脚本文件。
  3. 右键单击脚本文件,然后单击“属性”。
  4. 单击“解除阻止”。

如果从 Internet 下载的脚本经过数字签名,但尚未选择信任其发布者,PowerShell 将显示以下消息:

Do you want to run software from this untrusted publisher?
The file <file-name> is published by CN=<publisher-name>. This
publisher is not trusted on your system. Only run scripts
from trusted publishers.

[V] Never run  [D] Do not run  [R] Run once  [A] Always run
[?] Help (default is "D"):

如果信任发布者,请选择“运行一次”或“始终运行”。如果不信任发布者,请选择“永不运行”或“不运行”。如果选择“永不运行”或“始终运行”,PowerShell 将不会再次提示你输入此发布者。

为脚本签名的方法

可以对编写的脚本以及从其他源获取的脚本进行签名。 在对任何脚本进行签名之前,请检查每个命令以验证它是否可安全运行。

有关代码签名的最佳做法,请参阅 代码签名最佳做法

有关如何对脚本文件进行签名的详细信息,请参阅 Set-AuthenticodeSignature

New-SelfSignedCertificate在 PowerShell 3.0 的 PKI 模块中引入的 cmdlet 创建适用于测试的自签名证书。 有关详细信息,请参阅 New-SelfSignedCertificate cmdlet 的帮助主题。

若要向脚本添加数字签名,必须使用代码签名证书对其进行签名。 两种类型的证书适用于对脚本文件进行签名:

  • 证书颁发机构创建的证书:收费后,公共证书颁发机构会验证你的身份并为你提供代码签名证书。 从信誉良好的证书颁发机构购买证书时,你可以与运行 Windows 的其他计算机上的用户共享脚本,因为这些计算机信任证书颁发机构。

  • 创建的证书:可以创建自签名证书,计算机是创建证书的颁发机构。 此证书是免费的,可用于在计算机上编写、签名和运行脚本。 但是,由自签名证书签名的脚本不会在其他计算机上运行。

通常,只能使用自签名证书来签署你为自己使用而编写的脚本,并签署你从已验证为安全的其他源获取的脚本。 它不适用于将共享的脚本,即使在企业中也是如此。

如果创建自签名证书,请确保在证书上启用强私钥保护。 这可以防止恶意程序代表你对脚本进行签名。 本主题末尾包含说明。

创建自签名证书

若要在 中创建自签名证书,请使用 PKI 模块中的 New-SelfSignedCertificate cmdlet。 此模块在 PowerShell 3.0 中引入,包含在Windows 8和Windows Server 2012中。 有关详细信息,请参阅 New-SelfSignedCertificate cmdlet 的帮助主题。

若要在早期版本的 Windows 中创建自签名证书,请使用证书创建工具 (MakeCert.exe) 。 此工具包含在 Microsoft .NET Framework SDK (1.1 及更高版本) 和 Microsoft Windows SDK 中。

有关 MakeCert.exe 工具的语法和参数说明的详细信息,请参阅 证书创建工具 (MakeCert.exe)

若要使用 MakeCert.exe 工具创建证书,请在 SDK 命令提示符窗口中运行以下命令。

注意:第一个命令为计算机创建本地证书颁发机构。 第二个命令从证书颁发机构生成个人证书。

注意:可以完全按照命令显示的方式复制或键入命令。 无需替换,但可以更改证书名称。

makecert -n "CN=PowerShell Local Certificate Root" -a sha1 `
-eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer `
-ss Root -sr localMachine

makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 `
-eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

MakeCert.exe 工具会提示输入私钥密码。 密码可确保未经你的同意,任何人都无法使用或访问证书。 Create并输入可记住的密码。 稍后将使用此密码检索证书。

若要验证是否已正确生成证书,请使用以下命令获取计算机上的证书存储中的证书。 (在文件系统目录中找不到证书文件。)

在 PowerShell 提示符处,键入:

Get-ChildItem cert:\CurrentUser\my -codesigning

此命令使用 PowerShell 证书提供程序查看有关证书的信息。

如果已创建证书,输出会显示在类似于以下内容的显示器中标识证书的指纹:

Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject
----------                                -------
4D4917CB140714BA5B81B96E0B18AAF2C4564FDF  CN=PowerShell User ]

为脚本签名

创建自签名证书后,可以对脚本进行签名。 如果使用 AllSigned 执行策略,则对脚本进行签名将允许您在计算机上运行该脚本。

以下示例脚本 Add-Signature.ps1 对脚本进行签名。 但是,如果使用 AllSigned 执行策略,则必须对 Add-Signature.ps1 脚本进行签名,然后才能运行该脚本。

若要使用此脚本,请将以下文本复制到文本文件中,并将其命名为 Add-Signature.ps1。

## Signs a file
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature $file $cert

若要对 Add-Signature.ps1 脚本文件进行签名,请在 PowerShell 命令提示符处键入以下命令:

$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature add-signature.ps1 $cert

脚本签名后,可以在本地计算机上运行它。 但是,该脚本不会在 PowerShell 执行策略需要受信任颁发机构的数字签名的计算机上运行。 如果尝试,PowerShell 将显示以下错误消息:

The file C:\remote_file.ps1 cannot be loaded. The signature of the
certificate cannot be verified.
At line:1 char:15
+ .\ remote_file.ps1 <<<<

如果 PowerShell 在运行未写入的脚本时显示此消息,请像对待任何未签名脚本一样处理文件。 查看代码以确定是否可以信任该脚本。

为证书启用强私钥保护

如果计算机上有专用证书,则恶意程序可能能够代表你对脚本进行签名,从而授权 PowerShell 运行这些脚本。

若要防止代表你自动签名,请使用证书管理器 (Certmgr.exe) 将签名证书导出到 .pfx 文件。 证书管理器包含在 Microsoft .NET Framework SDK、Microsoft Windows SDK以及 Internet Explorer 5.0 及更高版本中。

导出证书:

  1. 启动证书管理器。
  2. 选择 PowerShell 本地证书根颁发的证书。
  3. 单击“导出”启动证书导出向导。
  4. 选择“是,导出私钥”,然后单击“下一步”。
  5. 选择“启用强保护”。
  6. 键入密码,然后再次键入以确认。
  7. 键入文件扩展名为 .pfx 的文件名。
  8. 单击“完成”。

若要重新导入证书,请执行以下操作:

  1. 启动证书管理器。
  2. 单击“导入”以启动证书导入向导。
  3. 打开在导出过程中创建的 .pfx 文件的位置。
  4. 在“密码”页上,选择“启用强私钥保护”,然后输入在导出过程中分配的密码。
  5. 选择“个人”证书存储。
  6. 单击“完成”。

防止签名过期

脚本中的数字签名在签名证书过期之前有效,或者只要时间戳服务器可以在签名证书有效时验证脚本是否已签名。

由于大多数签名证书的有效期仅为一年,因此使用时间戳服务器可确保用户可在多年后使用脚本。

另请参阅

about_Execution_Policies

about_Profiles

Get-ExecutionPolicy

Set-ExecutionPolicy

Set-AuthenticodeSignature

代码签名简介