forked from Sleepw4lker/TameMyCerts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.ps1
224 lines (171 loc) · 8.54 KB
/
install.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#Requires -PSEdition Desktop -Version 5.1
<#
.SYNOPSIS
Install script for the TameMyCerts policy module.
Installs the module, configures the registry and activates the module.
.PARAMETER PolicyDirectory
Installs the module and configures it to use the specified directory for policy definition.
Also call this for updates or reinstalations.
.PARAMETER Uninstall
Call this if you want to uninstall the module.
#>
[cmdletbinding()]
param(
[ValidateScript({Test-Path -Path $_})]
[Parameter(
ParameterSetName="Install",
Mandatory=$True
)]
[String]
$PolicyDirectory,
[Parameter(
ParameterSetName="Uninstall",
Mandatory=$False
)]
[Switch]
$Uninstall
)
begin {
New-Variable -Option Constant -Name BUILD_NUMBER_WINDOWS_2012 -Value 9200
New-Variable -Option Constant -Name PolicyModuleName -Value "TameMyCerts"
New-Variable -Option Constant -Name RegistryRoot -Value "HKLM:\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration"
New-Variable -Option Constant -Name BaseDirectory -Value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent)
New-Variable -Option Constant -Name ENUM_ENTERPRISE_ROOTCA -Value 0
New-Variable -Option Constant -Name ENUM_ENTERPRISE_SUBCA -Value 1
New-Variable -Option Constant -Name ENUM_STANDALONE_ROOTCA -Value 3
New-Variable -Option Constant -Name ENUM_STANDALONE_SUBCA -Value 4
function Copy-Registry {
[cmdletbinding()]
param(
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path -Path $_})]
[String]
$Source,
[ValidateNotNullOrEmpty()]
[String]
$Destination
)
(Get-Item -Path $Source).Property | ForEach-Object -Process {
Copy-ItemProperty `
-Path $Source `
-Name $_ `
-Destination $Destination
}
}
}
process {
If (($PolicyDirectory -eq [String]::Empty) -and (-not $Uninstall.IsPresent)) {
Write-Error -Message "You must either specify the -PolicyDirectory or the -Uninstall argument."
return
}
# Ensuring the Script will be run on a supported Operating System
If ([int32](Get-WmiObject Win32_OperatingSystem).BuildNumber -lt $BUILD_NUMBER_WINDOWS_2012) {
Write-Error -Message "This must be run on Windows Server 2012 or newer! Aborting."
Return
}
# Ensuring the Script will be run with Elevation
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Error -Message "This must be run as Administrator! Aborting."
Return
}
# We grab the relevant Data from the Registry
If (-not (Test-Path -Path $RegistryRoot)) {
Write-Error -Message "$($RegistryRoot) not found. Is this really a CA?"
Return
}
# Prevent running the installer without the module present
If (-not (Test-Path -Path "$BaseDirectory\$($PolicyModuleName).dll")) {
Write-Error -Message "Could not find $BaseDirectory\$($PolicyModuleName).dll"
Return
}
$CaName = (Get-ItemProperty -Path $RegistryRoot -Name Active).Active
$CaType = (Get-ItemProperty -Path "$RegistryRoot\$($CaName)" -Name CaType -ErrorAction Stop).CaType
$KeyStorageProvider = (Get-ItemProperty -Path "$($RegistryRoot)\$($CaName)\CSP" -Name Provider).Provider
If (-not (($CaType -eq $ENUM_ENTERPRISE_ROOTCA) -or ($CaType -eq $ENUM_ENTERPRISE_SUBCA))) {
Write-Error -Message "The $PolicyModuleName policy module currently does not support standalone certification authorities."
Return
}
$DefaultPolicyModuleName = "CertificateAuthority_MicrosoftDefault.Policy"
$RegistryHiveDefault = "$($RegistryRoot)\$($CaName)\PolicyModules\$DefaultPolicyModuleName"
$RegistryHiveCustom = "$($RegistryRoot)\$($CaName)\PolicyModules\$($PolicyModuleName).Policy"
# This part is called both on (re)installation and uninstallation
Write-Verbose -Message "Stopping certification authority service"
Stop-Service -Name certsvc
If ($KeyStorageProvider -eq "SafeNet Key Storage Provider") {
Write-Warning -Message "Waiting 120 seconds for the AD CS service to shutdown properly (to avoid known bug in SafeNet Key Storage Provider)."
Start-Sleep -Seconds 120
}
$MmcProcesses = Get-Process -ProcessName "mmc" -ErrorAction SilentlyContinue
If ($MmcProcesses) {
Write-Warning -Message "Killing running MMC processes (certsrv.msc may lock the policy module DLL if opened during (un)installation)."
$MmcProcesses | Stop-Process -Force
}
Write-Verbose -Message "Trying to unregister $PolicyModuleName policy module COM object"
"System32","SysWOW64" | ForEach-Object -Process {
$Path = "$($env:SystemRoot)\$($_)\$($PolicyModuleName).dll"
If (Test-Path -Path $Path) {
Start-Process `
-FilePath "$($env:SystemRoot)\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" `
-ArgumentList "/unregister", $Path `
-Wait `
-WindowStyle Hidden
}
}
Write-Verbose -Message "Deleting policy module DLL file"
"System32","SysWOW64" | ForEach-Object -Process {
$Path = "$($env:SystemRoot)\$($_)\$($PolicyModuleName).dll"
If (Test-Path -Path $Path) {
Remove-Item -Path $Path -Force
}
}
# Uninstall
If ($Uninstall.IsPresent) {
If (Get-ItemProperty -Path $RegistryHiveCustom -Name PolicyDirectory -ErrorAction SilentlyContinue) {
Write-Verbose "Deleting policy directory from registry"
Remove-ItemProperty -Path $RegistryHiveCustom -Name PolicyDirectory
Write-Verbose "Copying back configuration to default path (may have changed in the meantime)."
Copy-Registry -Source $RegistryHiveCustom -Destination $RegistryHiveDefault
Write-Verbose -Message "Deleting custom module configuration $RegistryHiveCustom from registry"
Remove-Item -Path $RegistryHiveCustom -Recurse -Force
}
If ((Get-ItemProperty -Path "$($RegistryRoot)\$($CaName)\PolicyModules" -Name Active).Active -ne "$DefaultPolicyModuleName") {
Write-Verbose "Setting the active policy module back to Microsoft Default policy module"
Set-ItemProperty -Path "$($RegistryRoot)\$($CaName)\PolicyModules" -Name Active -Value "$DefaultPolicyModuleName"
}
}
# (Re)Install
If (-not $Uninstall.IsPresent) {
Write-Verbose -Message "Registering $PolicyModuleName policy module COM Object"
"System32","SysWOW64" | ForEach-Object -Process {
$SourcePath = "$BaseDirectory\$($PolicyModuleName).dll"
$Path = "$($env:SystemRoot)\$($_)\$($PolicyModuleName).dll"
Copy-Item -Path $SourcePath -Destination $Path -Force -ErrorAction Stop
Start-Process `
-FilePath "$($env:SystemRoot)\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" `
-ArgumentList $Path `
-Wait `
-WindowStyle Hidden
}
If (-not (Test-Path -Path $RegistryHiveCustom)) {
Write-Verbose -Message "Creating registry path"
[void](New-Item -Path "$($RegistryRoot)\$($CaName)\PolicyModules" -Name "$($PolicyModuleName).Policy" -Force)
Write-Verbose -Message "Copying registry Keys from Microsoft Default policy module to $RegistryHiveCustom"
Copy-Registry -Source $RegistryHiveDefault -Destination $RegistryHiveCustom
}
Write-Verbose -Message "Setting policy directory in registry"
[void](Set-ItemProperty -Path $RegistryHiveCustom -Name PolicyDirectory -Value $PolicyDirectory -Force)
Write-Verbose -Message "Setting the currently active policy Module to $PolicyModuleName"
Set-ItemProperty -Path "$($RegistryRoot)\$($CaName)\PolicyModules" -Name Active -Value "$($PolicyModuleName).Policy" -Force
If ([System.Diagnostics.EventLog]::SourceExists($PolicyModuleName) -eq $false) {
Write-Verbose -Message "Registering Windows event source ""$PolicyModuleName"""
[System.Diagnostics.EventLog]::CreateEventSource("$PolicyModuleName", 'Application')
}
}
Write-Verbose -Message "Starting certification authority service"
Start-Service -Name certsvc
[PSCustomObject]@{
Success = $True
Message = "The operation was successful."
}
}
end {}