1
+ <#
2
+ Check (and recurse) current directory .\CheckSignature.ps1
3
+ Find and check directory of Azure PowerShell modules .\CheckSignature.ps1 -AzurePowerShell
4
+ Check directory of MSI-installed modules .\CheckSignature.ps1 -MsiInstall
5
+ Check directory of gallery-installed modules .\CheckSignature.ps1 -GalleryInstall
6
+ Check files in provided path .\CheckSignature.ps1 -CustomPath $Path
7
+ #>
8
+ [CmdletBinding (DefaultParameterSetName = " CurrentDirectory" )]
9
+ Param
10
+ (
11
+ [Parameter (ParameterSetName = " AzurePowerShell" , Mandatory = $true )]
12
+ [switch ]$AzurePowerShell ,
13
+ [Parameter (ParameterSetName = " MsiInstall" , Mandatory = $true )]
14
+ [switch ]$MsiInstall ,
15
+ [Parameter (ParameterSetName = " GalleryInstall" , Mandatory = $true )]
16
+ [switch ]$GalleryInstall ,
17
+ [Parameter (ParameterSetName = " CustomPath" , Mandatory = $true )]
18
+ [string ]$CustomPath
19
+ )
20
+
21
+ function Check-StrongName {
22
+ [CmdletBinding ()]
23
+ param ([Parameter (ValueFromPipeline = $true )][string ]$path )
24
+ $output = & " sn.exe" - vf $path
25
+ $length = $output.Length - 1
26
+ if (-not $output [$length ].Contains(" is valid" )) {
27
+ Write-Output " $path has an invalid strong name."
28
+ }
29
+ }
30
+
31
+ function Check-AuthenticodeSignature {
32
+ [CmdletBinding ()]
33
+ param ([Parameter (ValueFromPipeline = $true )][string ]$path )
34
+ $output = Get-AuthenticodeSignature $path
35
+ if (-not ($output.Status -like " Valid" )) {
36
+ Write-Output " $path has an invalid authenticode signature. Status is $ ( $output.Status ) "
37
+ }
38
+ }
39
+
40
+ function Check-All {
41
+ [CmdletBinding ()]
42
+ param ([Parameter ()][string ]$path )
43
+
44
+ if (! (Get-Command " sn.exe" - ErrorAction SilentlyContinue))
45
+ {
46
+ Write-Error " Unable to find sn.exe; please ensure that the Windows SDK is installed and found in the PATH environment variable."
47
+ return
48
+ }
49
+
50
+ $invalidList = @ ()
51
+
52
+ $files = Get-ChildItem $path \* - Include * .dll - Recurse | Where-Object { $_.FullName -like " *Azure*" }
53
+ Write-Host " Checking the strong name signature of $ ( $files.Count ) files (.dll)" - ForegroundColor Yellow
54
+
55
+ $invalidStrongNameList = @ ()
56
+
57
+ for ($idx = 0 ; $idx -lt $files.Length ; $idx ++ ) {
58
+ $percent = (100 * $idx ) / $files.Length
59
+ Write-Progress - Activity " Validating strong name signature of $ ( $files [$idx ]) " - Status " $percent % Complete" - PercentComplete $percent
60
+ $invalidStrongNameList += Check- StrongName - path $files [$idx ]
61
+ }
62
+
63
+ if ($invalidStrongNameList.Length -gt 0 ) {
64
+ $invalidList += $invalidStrongNameList
65
+ Write-Host " Found $ ( $invalidStrongNameList.Count ) files with an invalid strong name signature." - ForegroundColor Red
66
+ }
67
+ else {
68
+ Write-Host " All files (.dll) have a strong name signature." - ForegroundColor Green
69
+ }
70
+
71
+ # -------------------------------------
72
+
73
+ $files = Get-ChildItem $path \* - Include * .dll, * .ps1, * .psm1 - Recurse | Where-Object { $_.FullName -like " *Azure*" }
74
+ $files = $files | Where-Object { ($_.FullName -notlike " *Newtonsoft.Json*" ) -and `
75
+ ($_.FullName -notlike " *AutoMapper*" ) -and `
76
+ ($_.FullName -notlike " *Security.Cryptography*" ) -and `
77
+ ($_.FullName -notlike " *BouncyCastle.Crypto*" )}
78
+ Write-Host " Checking the authenticode signature of $ ( $files.Count ) files (.dll, .ps1, .psm1)" - ForegroundColor Yellow
79
+
80
+ $invalidAuthenticodeList = @ ()
81
+
82
+ for ($idx = 0 ; $idx -lt $files.Length ; $idx ++ ) {
83
+ $percent = (100 * $idx ) / $files.Length
84
+ Write-Progress - Activity " Validating authenticode signature of $ ( $files [$idx ]) " - Status " $percent % Complete" - PercentComplete $percent
85
+ $invalidAuthenticodeList += Check- AuthenticodeSignature - path $files [$idx ]
86
+ }
87
+
88
+ if ($invalidAuthenticodeList.Length -gt 0 ) {
89
+ $invalidList += $invalidAuthenticodeList
90
+ Write-Host " Found $ ( $invalidAuthenticodeList.Count ) files with an invalid authenticode signature." - ForegroundColor Red
91
+ }
92
+ else {
93
+ Write-Host " All files (.dll, .ps1, .psd1) have a valid authenticode signature." - ForegroundColor Green
94
+ }
95
+
96
+ if ($invalidList.Length -gt 0 ) {
97
+ Write-Output ($invalidList )
98
+ throw " Strong name signature check and/or authenticode signature check failed. Please see the above errors."
99
+ }
100
+ }
101
+
102
+ $path = " .\"
103
+
104
+ if ($PSCmdlet.ParameterSetName -eq " AzurePowerShell" )
105
+ {
106
+ $ProfileModule = Get-Module - Name AzureRM.Profile - ListAvailable
107
+ if (! ($ProfileModule ))
108
+ {
109
+ Write-Error " Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
110
+ return
111
+ }
112
+
113
+ if ($ProfileModule.Count -gt 1 )
114
+ {
115
+ Write-Error " Mulitple versions of Azure PowerShell were found. Please use the -MsiInstall and -GalleryInstall switches to select the installed version you want to check."
116
+ return
117
+ }
118
+
119
+ $ModulePath = $ProfileModule.Path
120
+ if ($ModulePath -like " *Microsoft SDKs\Azure\PowerShell*" )
121
+ {
122
+ $EndIdx = $ModulePath.IndexOf (" PowerShell\ResourceManager" , [System.StringComparison ]::OrdinalIgnoreCase) + " PowerShell" .Length
123
+ }
124
+ elseif ($ModulePath -like " *Modules\AzureRM.Profile*" )
125
+ {
126
+ $EndIdx = $ModulePath.IndexOf (" Modules\AzureRM.Profile" , [System.StringComparison ]::OrdinalIgnoreCase) + " Modules" .Length
127
+ }
128
+
129
+ $path = $ModulePath.Substring (0 , $EndIdx )
130
+ Write-Host " Found AzureRM module - checking all (Azure) files in $path " - ForegroundColor Yellow
131
+ }
132
+ elseif ($PSCmdlet.ParameterSetName -eq " MsiInstall" )
133
+ {
134
+ $ProfileModule = Get-Module - Name AzureRM.Profile - ListAvailable
135
+ if (! ($ProfileModule ))
136
+ {
137
+ Write-Error " Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
138
+ return
139
+ }
140
+
141
+ $SearchString = " Microsoft SDKs\Azure\PowerShell"
142
+
143
+ $ModulePath = $ProfileModule.Path
144
+
145
+ if ($ProfileModule.Count -gt 1 )
146
+ {
147
+ $ModulePath = $ProfileModule | Where-Object { $_.Path -like " *$ ( $SearchString ) *" }
148
+ if (! ($ModulePath ))
149
+ {
150
+ Write-Error " Unable to find path of MSI-installed modules from multiple locations found in PSModulePath."
151
+ return
152
+ }
153
+ }
154
+ else
155
+ {
156
+ if ($ModulePath -notlike " *$ ( $SearchString ) *" )
157
+ {
158
+ Write-Error " Modules installed on the current machine were not from MSI. Consider using the -GalleryInstall switch."
159
+ return
160
+ }
161
+ }
162
+
163
+ $EndIdx = $ModulePath.IndexOf (" PowerShell\ResourceManager" , [System.StringComparison ]::OrdinalIgnoreCase) + " PowerShell" .Length
164
+ $path = $ModulePath.Substring (0 , $EndIdx )
165
+ Write-Host " Installed Azure PowerShell from MSI - checking all (Azure) files in $path " - ForegroundColor Yellow
166
+ }
167
+ elseif ($PSCmdlet.ParameterSetName -eq " GalleryInstall" )
168
+ {
169
+ $ProfileModule = Get-Module - Name AzureRM.Profile - ListAvailable
170
+ if (! ($ProfileModule ))
171
+ {
172
+ Write-Error " Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
173
+ return
174
+ }
175
+
176
+ $SearchString = " WindowsPowerShell\Modules"
177
+
178
+ $ModulePath = $ProfileModule.Path
179
+
180
+ if ($ProfileModule.Count -gt 1 )
181
+ {
182
+ $ModulePath = $ProfileModule | Where-Object { $_.Path -like " *$ ( $SearchString ) *" }
183
+ if (! ($ModulePath ))
184
+ {
185
+ Write-Error " Unable to find path of gallery-installed modules from multiple locations found in PSModulePath."
186
+ return
187
+ }
188
+ }
189
+ else
190
+ {
191
+ if ($ModulePath -notlike " *$ ( $SearchString ) *" )
192
+ {
193
+ Write-Error " Modules installed on the current machine were not from the gallery. Consider using the -MsiInstall switch."
194
+ return
195
+ }
196
+ }
197
+
198
+ $EndIdx = $ModulePath.IndexOf (" Modules\AzureRM.Profile" , [System.StringComparison ]::OrdinalIgnoreCase) + " Modules" .Length
199
+ $path = $ModulePath.Substring (0 , $EndIdx )
200
+ Write-Host " Installed Azure PowerShell from the gallery - checking all (Azure) files in $path " - ForegroundColor Yellow
201
+ }
202
+ elseif ($PSCmdlet.ParameterSetName -eq " CustomPath" )
203
+ {
204
+ $path = $CustomPath
205
+ Write-Host " Custom path provided - checking all (Azure) files in $path " - ForegroundColor Yellow
206
+ }
207
+ else
208
+ {
209
+ Write-Host " No switch parameter set - checking all files in current directory" - ForegroundColor Yellow
210
+ }
211
+
212
+ Check- All $path
0 commit comments