-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sign-Script.ps1
83 lines (74 loc) · 4.1 KB
/
Sign-Script.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
####################################################################################
#.SYNOPSIS
# Digitally signs PowerShell scripts.
#
#.DESCRIPTION
# If you have a code signing certificate, this script will sign one or
# more PowerShell scripts for the sake of AppLocker or PowerShell's
# execution policy restrictions. Note that this script will not create
# or enroll for a code signing certificate itself; a code signing certificate
# and private key must be obtained first. PSD1 and CAT files can also be signed.
#
#.PARAMETER Path
# Path to a single .ps1, .psd1 or .cat file, or the path to a folder which
# contains one or more .ps1, .psd1 or .cat files. All matching files will be
# signed. Any non-ps1/psd1/cat files will be ignored.
#
#.PARAMETER Recurse
# Switch to recurse through subdirectories of the given path. Only
# *.ps1, *.psd1 and *.cat files will be signed.
#
#.PARAMETER Thumbprint
# Optional hash of the code-signing certificate to use if the user has
# more than one available certificate with that purpose.
#
#.PARAMETER DoNotAskWhichCertificateToUse
# Avoid compelling the user to enter a thumbprint when the user has
# multiple code-signing certificates. This switch will simply use
# the first code-signing certificate it finds.
#
#.PARAMETER ListCodeSigningCertificates
# Show a list of the user's code-signing certificates, if any, and then
# exit. No files will be signed.
#
#.EXAMPLE
# .\Sign-Script.ps1 -Path onescript.ps1
#.EXAMPLE
# .\Sign-Script.ps1 -Path c:\folder\*many*.ps1
#.EXAMPLE
# .\Sign-Script.ps1 -Path c:\folder -recurse
#.EXAMPLE
# .\Sign-Script.ps1 foo.ps1 -Thumprint 4342368F1339CB59010AE3720ED5672B73E94CD4
#.EXAMPLE
# .\Sign-Script.ps1 -Path script.ps1 -DoNotAskWhichCertificateToUse
#
#.NOTES
# Author: Jason Fossen, Enclave Consulting LLC (http://www.sans.org/sec505)
# Version: 1.2
# Updated: 18.Mar.2017
# Legal: 0BSD.
####################################################################################
Param ( $Path, [Switch] $Recurse, $Thumbprint = "blank" , [Switch] $DoNotAskWhichCertificateToUse, [Switch] $ListCodeSigningCertificates )
# Check for -ListCodeSigningCertificates and exit.
if ($ListCodeSigningCertificates){ dir cert:\currentuser\my -codesigningcert ; exit }
# Expand path of script(s) to sign.
if (-not $Path) { "`nError, you must enter the path to one or more files to sign; wildcards are permitted, exiting.`n" ; exit }
if ($Recurse) { $Path = dir -Path $Path -force -recurse -file -include *.ps1,*.psd1,*.cat } else { $Path = dir -path $Path -force -file -include *.ps1,*.psd1,*.cat }
if ($Path -eq $null) { "`nError, invalid argument to -Path parameter, exiting.`n" ; exit }
# Get the current user's code-signing cert(s), if any.
$certs = @(dir cert:\currentuser\my -codesigningcert)
# Check for zero, one or multiple code-signing certificates.
if ($certs.count -eq 0) { "`nYou have no code-signing certificates, exiting.`n" ; exit }
elseif ($Thumbprint -ne "blank") { $signingcert = ($certs | where { $_.Thumbprint -match "$Thumbprint" }) }
elseif ($certs.count -ge 1 -or $DoNotAskWhichCertificateToUse) { $signingcert = $certs[0] }
elseif ($Thumbprint -eq "blank") { "`nYou have multiple code-signing certificates. Run the script again, but enter the thumbprint of the one you wish to use as the argument to the -Thumbprint parameter (or use -DoNotAskWhichCertificateToUse to simply use the first certificate available).`n" ; $certs | format-list Thumbprint,Issuer,Subject,SerialNumber,NotAfter,FriendlyName ; exit }
else { "`nError, should not have gotten here, exiting.`n" ; exit }
# Quick check that we actually got a cert to use...
if ($certs -notcontains $signingcert)
{
"`nError, an invalid certificate choice was made, exiting.`n"
if ($Thumbprint -ne "blank") { "Did you enter the correct thumbprint hash value without`n any spaces, colons or other delimiters?`n" }
exit
}
# Sign each script.
foreach ($file in $Path) { Set-AuthenticodeSignature -FilePath $file.fullname -Certificate $signingcert }