你是否需要确保没有人修改您的脚本并将其传递为原始脚本?如果是这样,那么您需要学会如何签署 PowerShell 脚本。签署会将发布者的身份添加到脚本中,以便用户可以决定是否信任脚本的来源。
在本文中,了解如何通过学习如何签署 PowerShell 脚本来确保只有受信任的脚本在您的环境中运行。
先决条件
如果您要按照本文中的示例操作,您需要以下内容。
- A computer running on a recent version of the Windows operating system. This article uses Windows 10 version 20H2.
- Windows PowerShell 5.1 或 PowerShell 6+。本文中的示例将使用PowerShell v7.1.3。
- A sample PowerShell script for signing. Feel free to create a script with any name and in any folder you want. This article will use a sample script called C:\ATA\myscript.ps1 that contains the code below.
获取代码签名证书
在学习如何签署 PowerShell 脚本之前,您首先需要获取代码签名证书。在 Microsoft 的世界中,代码签名证书也被称为Authenticode证书。
A code signing certificate is one type of digital certificate whose purpose for signing files. Signing a file or code with a code signing certificate adds proof that the file came from the publisher who signed it.
您从哪里获取代码签名证书取决于您打算部署或分发已签名脚本的位置。而且,成本也一如既往地是一个重要因素。
- 全球 / 公共 – 您需要一张由全球信任的证书颁发机构(CA)颁发的证书。此类CA的示例包括GeoTrust和DigiCert。这些证书并非免费。例如,截至本文撰写时,DigiCert Authenticode证书的年费为474美元。
- 内部 / 本地内部网 – 如果您拥有内部证书颁发机构(CA)服务器,您可以从内部CA服务器请求并下载签名证书。
- 个人 / 开发 – 对于个人测试或开发用途,自签名证书就足够了。本文中将使用这种类型的签名证书。
为代码签名创建自签名证书
在前一节中,您已经了解到在学习如何签署PowerShell脚本时,首先需要一张代码签名证书。由于本教程中您只会进行个人测试,因此自签名证书就足够了。那么,您应该从哪里获取它呢?
正如其名称所示,自签名意味着您的本地计算机将向自己颁发代码签名证书。要生成自签名证书,请按照以下步骤操作。
1. 在您的计算机上以管理员身份打开 PowerShell。
2. 复制下面的命令并在 PowerShell 中运行。此命令使用 New-SelfSignedCertificate
cmdlet 来创建一个新的代码签名证书。证书的名称是 ATA Authenticode,存储在本地计算机的个人证书存储区中。
New-SelfSignedCertificate
cmdlet 仅支持在当前用户的个人证书存储区(cert:\CurrentUser\My)或本地计算机的个人证书存储区(cert:\LocalMachine\My)中创建证书。cert:\LocalMachine\My 中的证书可在整个计算机上使用。
该命令还将证书对象存储到 $authenticode
变量中,以供下一步使用。
3. 接下来,为了使您的计算机信任您创建的新证书,将自签名证书添加到计算机的 受信任的根证书颁发机构 和 受信任的发布者 证书存储区。为此,请复制下面的代码并在 PowerShell 中运行。
将自签名证书安装到三个不同的证书存储中有三个主要原因。
- 在个人证书存储中创建的证书将用作代码签名证书。
- 将相同的证书复制到受信任的发布者存储确保本地计算机信任签署脚本的发布者。PowerShell 在此存储中检查证书以验证脚本的签名。
- 最后,将自签名证书添加到受信任的根证书颁发机构,确保您的本地计算机信任个人和受信任的发布商存储中的证书。
4. 确认具有主题ATA Authenticode的证书是否位于个人、根和受信任的发布商证书存储中,请在PowerShell中运行以下命令。

5. 要以图形界面查看证书,打开证书管理器,并在个人、受信任的根证书颁发机构和受信任的发布商证书存储中查找您创建的证书。

如何签署 PowerShell 脚本
现在,您已经创建并安装了代码签名证书到三个证书存储库中,您可以开始使用它来签署您的示例 PowerShell 脚本。当您需要签署脚本时,Set-AuthenticodeSignature
cmdlet 是主角。
要签署 PowerShell 脚本,请在 PowerShell 中运行以下代码。第一条命令从本地计算机的个人证书存储库获取代码签名证书。第二条命令向 PowerShell 脚本文件添加数字签名。
大多数值得信赖的证书提供商都有一个时间戳服务器,您可以在这些提供商的网站上找到。例如,DigiCert的时间戳服务器是 http://timestamp.digicert.com,而Comodo的时间戳服务器是 http://timestamp.comodoca.com。
在签署脚本之后,您应该看到类似下面截图的输出。

检查 PowerShell 脚本的数字签名
到目前为止,您已经使用您创建的自签名证书对 PowerShell 脚本进行了签名。但是,您如何知道脚本是否确实具有数字签名呢?
打开代码
确认脚本的数字签名的一种方法是打开脚本并在文本编辑器中查看代码。就像下面的示例一样,已签名的脚本在代码末尾有一个签名块。签名块以# SIG # Begin signature block
开头,以# SIG # End signature block
结尾。

从脚本代码中删除数字签名块将使脚本恢复为非签名状态。
打开脚本的文件属性
检查脚本的数字签名的另一种方法是在Windows资源管理器中打开脚本的文件属性。操作步骤如下:
- 在Windows资源管理器中,导航到PowerShell脚本的位置。在这个示例中,脚本位于C:\ATA\myscript.ps1。
- 右键单击脚本,然后点击属性。
- 在文件属性窗口中,点击数字签名选项卡,您应该在签名列表下看到一个数字签名。

使用Get-AuthenticodeSignature
您会惊讶地发现您也可以在PowerShell中检查脚本的签名吗?可能不会。您可以调用的cmdlet以检索文件签名的是Get-AuthenticodeSignature
。
要获取脚本的数字签名,请运行以下命令。此命令获取C:\ATA\myscript.ps1文件的签名。Select-Object -Property *
cmdlet显示签名的所有详细信息。
运行命令后,您应该看到类似下面截图的结果。正如您所见,SignerCertificate
属性显示签名证书的详细信息。而TimerStamperCertificate
属性显示时间戳服务器的证书。

运行已签名的PowerShell脚本
到此为止,您已签署了一个PowerShell脚本并确认数字签名存在。但是,确认您是否已正确执行所有步骤的最终测试是执行脚本并确认其是否运行。
PowerShell具有一项安全功能,可防止用户意外运行脚本。这个安全功能称为执行策略。根据执行策略的不同,PowerShell可能会阻止或允许脚本运行。
要了解不同的执行策略以及它们对脚本执行的影响,请参阅PowerShell执行策略:理解和管理。
要运行已签名的PowerShell脚本,请按照以下步骤操作。
首先,将执行策略更改为AllSigned以确保只有已签名的脚本才能运行。如果不执行此步骤,则无法准确测试已签名脚本的运行情况。为此,请在PowerShell中以管理员身份运行以下命令,调用Set-ExecutionPolicy
cmdlet。
接下来,执行已签名的PowerShell脚本。
脚本应该会运行,而且没有错误或警告,正如下面的结果所示。

但是,如果脚本没有正确签名或者根本没有签名,你将会收到类似下面图片所示的错误。在这种情况下,请重新检查你的步骤,并尝试重新签名脚本。

如果你最终更新了你的脚本会怎样?数字签名还会有效吗?答案是否定的。对已签名脚本的任何修改都会使脚本的数字签名失效。运行修改后的脚本将会失败并显示错误。
按照以下步骤测试修改后的已签名脚本。
1. 在代码或文本编辑器中打开已签名的 myscript.ps1 脚本。
2. 修改代码以添加一个字符,例如在此示例中添加一个下划线。不要改变其他任何内容。

3. 修改代码后保存脚本。
4. 最后,通过运行以下命令在 PowerShell 中执行修改后的脚本。
由于你修改了已签名的脚本,执行脚本将导致下面显示的错误。你需要重新签名脚本以更新和修复其数字签名。

A digital signature does not guarantee that nobody modified the script from its original version. Any PowerShell script with malicious code may be digitally signed, too. Always practice caution when running scripts from sources you do not fully trust.
结论
通过本文,你了解了为什么签名 PowerShell 脚本可能是必要的,这取决于执行策略。你还学会了如何区分已签名和未签名的脚本。最后,你学会了如何对 PowerShell 脚本进行数字签名以及如何测试和运行它们。
现在你知道如何签署 PowerShell 脚本了,你会在分发或部署之前开始签署脚本吗?
Source:
https://adamtheautomator.com/how-to-sign-powershell-script/