1*eeb7e5b3SAdam Hornáček # MIT License
2*eeb7e5b3SAdam Hornáček #
3*eeb7e5b3SAdam Hornáček # Copyright (c) 2016 Raimund Andée
4*eeb7e5b3SAdam Hornáček #
5*eeb7e5b3SAdam Hornáček # Permission is hereby granted, free of charge, to any person obtaining a copy
6*eeb7e5b3SAdam Hornáček # of this software and associated documentation files (the "Software"), to deal
7*eeb7e5b3SAdam Hornáček # in the Software without restriction, including without limitation the rights
8*eeb7e5b3SAdam Hornáček # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9*eeb7e5b3SAdam Hornáček # copies of the Software, and to permit persons to whom the Software is
10*eeb7e5b3SAdam Hornáček # furnished to do so, subject to the following conditions:
11*eeb7e5b3SAdam Hornáček #
12*eeb7e5b3SAdam Hornáček # The above copyright notice and this permission notice shall be included in all
13*eeb7e5b3SAdam Hornáček # copies or substantial portions of the Software.
14*eeb7e5b3SAdam Hornáček #
15*eeb7e5b3SAdam Hornáček # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*eeb7e5b3SAdam Hornáček # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*eeb7e5b3SAdam Hornáček # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*eeb7e5b3SAdam Hornáček # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*eeb7e5b3SAdam Hornáček # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*eeb7e5b3SAdam Hornáček # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*eeb7e5b3SAdam Hornáček # SOFTWARE.
22*eeb7e5b3SAdam Hornáček
23*eeb7e5b3SAdam Hornáček #region Internals
24*eeb7e5b3SAdam Hornáček #region .net Types
25*eeb7e5b3SAdam Hornáček $certStoreTypes = @'
26*eeb7e5b3SAdam Hornáček ...
27*eeb7e5b3SAdam Hornáček '@
28*eeb7e5b3SAdam Hornáček
29*eeb7e5b3SAdam Hornáček $pkiInternalsTypes = @'
30*eeb7e5b3SAdam Hornáček ...
31*eeb7e5b3SAdam Hornáček /// <summary>
32*eeb7e5b3SAdam Hornáček /// 2.28 msPKI-Certificate-Name-Flag Attribute
33*eeb7e5b3SAdam Hornáček /// https://msdn.microsoft.com/en-us/library/cc226548.aspx
34*eeb7e5b3SAdam Hornáček /// </summary>
35*eeb7e5b3SAdam Hornáček ...
36*eeb7e5b3SAdam Hornáček '@
37*eeb7e5b3SAdam Hornáček
38*eeb7e5b3SAdam Hornáček $gpoType = @'
39*eeb7e5b3SAdam Hornáček ...
40*eeb7e5b3SAdam Hornáček '@
41*eeb7e5b3SAdam Hornáček #endregion .net Types
42*eeb7e5b3SAdam Hornáček
43*eeb7e5b3SAdam Hornáček $ApplicationPolicies = @{
44*eeb7e5b3SAdam Hornáček # Remote Desktop
45*eeb7e5b3SAdam Hornáček 'Remote Desktop' = '1.3.6.1.4.1.311.54.1.2'
46*eeb7e5b3SAdam Hornáček # Windows Update
47*eeb7e5b3SAdam Hornáček 'Windows Update' = '1.3.6.1.4.1.311.76.6.1'
48*eeb7e5b3SAdam Hornáček # Windows Third Party Applicaiton Component
49*eeb7e5b3SAdam Hornáček 'Windows Third Party Application Component' = '1.3.6.1.4.1.311.10.3.25'
50*eeb7e5b3SAdam Hornáček # Windows TCB Component
51*eeb7e5b3SAdam Hornáček 'Windows TCB Component' = '1.3.6.1.4.1.311.10.3.23'
52*eeb7e5b3SAdam Hornáček # Windows Store
53*eeb7e5b3SAdam Hornáček 'Windows Store' = '1.3.6.1.4.1.311.76.3.1'
54*eeb7e5b3SAdam Hornáček #...
55*eeb7e5b3SAdam Hornáček }
56*eeb7e5b3SAdam Hornáček
57*eeb7e5b3SAdam Hornáček $ExtendedKeyUsages = @{
58*eeb7e5b3SAdam Hornáček OldAuthorityKeyIdentifier = '.29.1'
59*eeb7e5b3SAdam Hornáček OldPrimaryKeyAttributes = '2.5.29.2'
60*eeb7e5b3SAdam Hornáček #...
61*eeb7e5b3SAdam Hornáček X509version3CertificateExtensionInhibitAny = '2.5.29.54'
62*eeb7e5b3SAdam Hornáček }
63*eeb7e5b3SAdam Hornáček
64*eeb7e5b3SAdam Hornáček #endregion Internals
65*eeb7e5b3SAdam Hornáček
66*eeb7e5b3SAdam Hornáček #region Get-LabCertificate
Get-LabCertificatenull67*eeb7e5b3SAdam Hornáček function Get-LabCertificate
68*eeb7e5b3SAdam Hornáček {
69*eeb7e5b3SAdam Hornáček # .ExternalHelp AutomatedLab.Help.xml
70*eeb7e5b3SAdam Hornáček [cmdletBinding(DefaultParameterSetName = 'Find')]
71*eeb7e5b3SAdam Hornáček param (
72*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ParameterSetName = 'Find')]
73*eeb7e5b3SAdam Hornáček [string]$SearchString,
74*eeb7e5b3SAdam Hornáček
75*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ParameterSetName = 'Find')]
76*eeb7e5b3SAdam Hornáček [System.Security.Cryptography.X509Certificates.X509FindType]$FindType,
77*eeb7e5b3SAdam Hornáček
78*eeb7e5b3SAdam Hornáček [System.Security.Cryptography.X509Certificates.CertStoreLocation]$Location,
79*eeb7e5b3SAdam Hornáček
80*eeb7e5b3SAdam Hornáček [System.Security.Cryptography.X509Certificates.StoreName]$Store,
81*eeb7e5b3SAdam Hornáček
82*eeb7e5b3SAdam Hornáček [string]$ServiceName,
83*eeb7e5b3SAdam Hornáček
84*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ParameterSetName = 'All')]
85*eeb7e5b3SAdam Hornáček [switch]$All,
86*eeb7e5b3SAdam Hornáček
87*eeb7e5b3SAdam Hornáček [Parameter(ParameterSetName = 'All')]
88*eeb7e5b3SAdam Hornáček [switch]$IncludeServices,
89*eeb7e5b3SAdam Hornáček
90*eeb7e5b3SAdam Hornáček [string]$Password = 'AL',
91*eeb7e5b3SAdam Hornáček
92*eeb7e5b3SAdam Hornáček [Parameter(Mandatory)]
93*eeb7e5b3SAdam Hornáček [string[]]$ComputerName
94*eeb7e5b3SAdam Hornáček )
95*eeb7e5b3SAdam Hornáček
96*eeb7e5b3SAdam Hornáček Write-LogFunctionEntry
97*eeb7e5b3SAdam Hornáček
98*eeb7e5b3SAdam Hornáček $variables = Get-Variable -Name PSBoundParameters
99*eeb7e5b3SAdam Hornáček $functions = Get-Command -Name Get-Certificate2, Sync-Parameter
100*eeb7e5b3SAdam Hornáček
101*eeb7e5b3SAdam Hornáček $x = $PSBoundParameters
102*eeb7e5b3SAdam Hornáček
103*eeb7e5b3SAdam Hornáček foreach ($computer in $ComputerName)
104*eeb7e5b3SAdam Hornáček {
105*eeb7e5b3SAdam Hornáček Invoke-LabCommand -ActivityName 'Adding Cert Store Types' -ComputerName $ComputerName -ScriptBlock {
106*eeb7e5b3SAdam Hornáček Add-Type -TypeDefinition $args[0]
107*eeb7e5b3SAdam Hornáček } -ArgumentList $certStoreTypes -NoDisplay
108*eeb7e5b3SAdam Hornáček
109*eeb7e5b3SAdam Hornáček Invoke-LabCommand -ActivityName 'Exporting certificates' -ComputerName $ComputerName -ScriptBlock {
110*eeb7e5b3SAdam Hornáček $variables['Password'] = $variables['Password'] | ConvertTo-SecureString -AsPlainText -Force
111*eeb7e5b3SAdam Hornáček Sync-Parameter -Command (Get-Command -Name Get-Certificate2)
112*eeb7e5b3SAdam Hornáček Get-Certificate2 @ALBoundParameters
113*eeb7e5b3SAdam Hornáček
114*eeb7e5b3SAdam Hornáček } -Variable $variables -Function $functions -PassThru
115*eeb7e5b3SAdam Hornáček }
116*eeb7e5b3SAdam Hornáček
117*eeb7e5b3SAdam Hornáček Write-LogFunctionExit
118*eeb7e5b3SAdam Hornáček }
119*eeb7e5b3SAdam Hornáček #endregion Get-LabCertificate
120*eeb7e5b3SAdam Hornáček
121*eeb7e5b3SAdam Hornáček #region Add-LabCertificate
Add-LabCertificatenull122*eeb7e5b3SAdam Hornáček function Add-LabCertificate
123*eeb7e5b3SAdam Hornáček {
124*eeb7e5b3SAdam Hornáček # .ExternalHelp AutomatedLab.Help.xml
125*eeb7e5b3SAdam Hornáček [cmdletBinding(DefaultParameterSetName = 'ByteArray')]
126*eeb7e5b3SAdam Hornáček param(
127*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'File')]
128*eeb7e5b3SAdam Hornáček [string]$Path,
129*eeb7e5b3SAdam Hornáček
130*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'ByteArray')]
131*eeb7e5b3SAdam Hornáček [byte[]]$Cert,
132*eeb7e5b3SAdam Hornáček
133*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
134*eeb7e5b3SAdam Hornáček [System.Security.Cryptography.X509Certificates.StoreName]$Store,
135*eeb7e5b3SAdam Hornáček
136*eeb7e5b3SAdam Hornáček [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
137*eeb7e5b3SAdam Hornáček [System.Security.Cryptography.X509Certificates.CertStoreLocation]$Location,
138*eeb7e5b3SAdam Hornáček
139*eeb7e5b3SAdam Hornáček [Parameter(ValueFromPipelineByPropertyName = $true)]
140*eeb7e5b3SAdam Hornáček [string]$ServiceName,
141*eeb7e5b3SAdam Hornáček
142*eeb7e5b3SAdam Hornáček [Parameter(ValueFromPipelineByPropertyName = $true)]
143*eeb7e5b3SAdam Hornáček [ValidateSet('CER', 'PFX')]
144*eeb7e5b3SAdam Hornáček [string]$CertificateType = 'CER',
145*eeb7e5b3SAdam Hornáček
146*eeb7e5b3SAdam Hornáček [string]$Password = 'AL',
147*eeb7e5b3SAdam Hornáček
148*eeb7e5b3SAdam Hornáček [Parameter(Mandatory, ValueFromPipelineByPropertyName = $true)]
149*eeb7e5b3SAdam Hornáček [string[]]$ComputerName
150*eeb7e5b3SAdam Hornáček )
151*eeb7e5b3SAdam Hornáček
152*eeb7e5b3SAdam Hornáček begin
153*eeb7e5b3SAdam Hornáček {
154*eeb7e5b3SAdam Hornáček Write-LogFunctionEntry
155*eeb7e5b3SAdam Hornáček }
156*eeb7e5b3SAdam Hornáček
157*eeb7e5b3SAdam Hornáček process
158*eeb7e5b3SAdam Hornáček {
159*eeb7e5b3SAdam Hornáček $variables = Get-Variable -Name PSBoundParameters
160*eeb7e5b3SAdam Hornáček $functions = Get-Command -Name Add-Certificate2, Sync-Parameter
161*eeb7e5b3SAdam Hornáček
162*eeb7e5b3SAdam Hornáček Invoke-LabCommand -ActivityName 'Adding Cert Store Types' -ComputerName $ComputerName -ScriptBlock {
163*eeb7e5b3SAdam Hornáček Add-Type -TypeDefinition $args[0]
164*eeb7e5b3SAdam Hornáček } -ArgumentList $certStoreTypes -NoDisplay
165*eeb7e5b3SAdam Hornáček
166*eeb7e5b3SAdam Hornáček Invoke-LabCommand -ActivityName 'Storing certificate bytes on target machine' -ComputerName $ComputerName -ScriptBlock {
167*eeb7e5b3SAdam Hornáček
168*eeb7e5b3SAdam Hornáček $tempFile = [System.IO.Path]::GetTempFileName()
169*eeb7e5b3SAdam Hornáček [System.IO.File]::WriteAllBytes($tempFile, $args[0])
170*eeb7e5b3SAdam Hornáček Write-Verbose "Cert is written to '$tempFile'"
171*eeb7e5b3SAdam Hornáček
172*eeb7e5b3SAdam Hornáček } -ArgumentList (,$Cert) -Variable $variables
173*eeb7e5b3SAdam Hornáček
174*eeb7e5b3SAdam Hornáček Invoke-LabCommand -ActivityName 'Importing Cert file' -ComputerName $ComputerName -ScriptBlock {
175*eeb7e5b3SAdam Hornáček $variables['Password'] = $variables['Password'] | ConvertTo-SecureString -AsPlainText -Force
176*eeb7e5b3SAdam Hornáček Sync-Parameter -Command (Get-Command -Name Add-Certificate2)
177*eeb7e5b3SAdam Hornáček $ALBoundParameters.Add('Path', $tempFile)
178*eeb7e5b3SAdam Hornáček $ALBoundParameters.Remove('Cert')
179*eeb7e5b3SAdam Hornáček Add-Certificate2 @ALBoundParameters | Out-Null
180*eeb7e5b3SAdam Hornáček Remove-Item -Path $tempFile
181*eeb7e5b3SAdam Hornáček
182*eeb7e5b3SAdam Hornáček } -Variable $variables -Function $functions -PassThru
183*eeb7e5b3SAdam Hornáček
184*eeb7e5b3SAdam Hornáček }
185*eeb7e5b3SAdam Hornáček
186*eeb7e5b3SAdam Hornáček end
187*eeb7e5b3SAdam Hornáček {
188*eeb7e5b3SAdam Hornáček Write-LogFunctionExit
189*eeb7e5b3SAdam Hornáček }
190*eeb7e5b3SAdam Hornáček }
191*eeb7e5b3SAdam Hornáček #endregion Add-LabCertificate
192*eeb7e5b3SAdam Hornáček
193*eeb7e5b3SAdam Hornáček # ...
194*eeb7e5b3SAdam Hornáček
195*eeb7e5b3SAdam Hornáček #region Install-LabCAMachine
Install-LabCAMachinenull196*eeb7e5b3SAdam Hornáček function Install-LabCAMachine
197*eeb7e5b3SAdam Hornáček {
198*eeb7e5b3SAdam Hornáček # .ExternalHelp AutomatedLab.Help.xml
199*eeb7e5b3SAdam Hornáček [CmdletBinding()]
200*eeb7e5b3SAdam Hornáček
201*eeb7e5b3SAdam Hornáček param (
202*eeb7e5b3SAdam Hornáček [Parameter(Mandatory)]
203*eeb7e5b3SAdam Hornáček [AutomatedLab.Machine]$Machine,
204*eeb7e5b3SAdam Hornáček
205*eeb7e5b3SAdam Hornáček [int]$PreDelaySeconds,
206*eeb7e5b3SAdam Hornáček
207*eeb7e5b3SAdam Hornáček [switch]$PassThru
208*eeb7e5b3SAdam Hornáček )
209*eeb7e5b3SAdam Hornáček
210*eeb7e5b3SAdam Hornáček Write-LogFunctionEntry
211*eeb7e5b3SAdam Hornáček
212*eeb7e5b3SAdam Hornáček Write-Verbose -Message '****************************************************'
213*eeb7e5b3SAdam Hornáček Write-Verbose -Message "Starting installation of machine: $($machine.name)"
214*eeb7e5b3SAdam Hornáček Write-Verbose -Message '****************************************************'
215*eeb7e5b3SAdam Hornáček
216*eeb7e5b3SAdam Hornáček $role = $machine.Roles | Where-Object { $_.Name -eq ([AutomatedLab.Roles]::CaRoot) -or $_.Name -eq ([AutomatedLab.Roles]::CaSubordinate) }
217*eeb7e5b3SAdam Hornáček
218*eeb7e5b3SAdam Hornáček $param = [ordered]@{ }
219*eeb7e5b3SAdam Hornáček
220*eeb7e5b3SAdam Hornáček #region - Locate admin username and password for machine
221*eeb7e5b3SAdam Hornáček if ($machine.IsDomainJoined)
222*eeb7e5b3SAdam Hornáček {
223*eeb7e5b3SAdam Hornáček $domain = $lab.Domains | Where-Object { $_.Name -eq $machine.DomainName }
224*eeb7e5b3SAdam Hornáček
225*eeb7e5b3SAdam Hornáček $param.Add('UserName', ('{0}\{1}' -f $domain.Name, $domain.Administrator.UserName))
226*eeb7e5b3SAdam Hornáček $param.Add('Password', $domain.Administrator.Password)
227*eeb7e5b3SAdam Hornáček
228*eeb7e5b3SAdam Hornáček $rootDc = Get-LabMachine -Role RootDC | Where-Object DomainName -eq $machine.DomainName
229*eeb7e5b3SAdam Hornáček if ($rootDc) #if there is a root domain controller in the same domain as the machine
230*eeb7e5b3SAdam Hornáček {
231*eeb7e5b3SAdam Hornáček $rootDomain = (Get-Lab).Domains | Where-Object Name -eq $rootDc.DomainName
232*eeb7e5b3SAdam Hornáček $rootDomainNetBIOSName = ($rootDomain.Name -split '\.')[0]
233*eeb7e5b3SAdam Hornáček }
234*eeb7e5b3SAdam Hornáček else #else the machine is in a child domain and the parent domain need to be used for the query
235*eeb7e5b3SAdam Hornáček {
236*eeb7e5b3SAdam Hornáček $rootDomain = $lab.GetParentDomain($machine.DomainName)
237*eeb7e5b3SAdam Hornáček $rootDomainNetBIOSName = ($rootDomain.Name -split '\.')[0]
238*eeb7e5b3SAdam Hornáček $rootDc = Get-LabMachine -Role RootDC | Where-Object DomainName -eq $rootDomain
239*eeb7e5b3SAdam Hornáček }
240*eeb7e5b3SAdam Hornáček
241*eeb7e5b3SAdam Hornáček $param.Add('ForestAdminUserName', ('{0}\{1}' -f $rootDomainNetBIOSName, $rootDomain.Administrator.UserName))
242*eeb7e5b3SAdam Hornáček $param.Add('ForestAdminPassword', $rootDomain.Administrator.Password)
243*eeb7e5b3SAdam Hornáček
244*eeb7e5b3SAdam Hornáček Write-Debug -Message "Machine : $($machine.name)"
245*eeb7e5b3SAdam Hornáček Write-Debug -Message "Machine Domain : $($machine.DomainName)"
246*eeb7e5b3SAdam Hornáček Write-Debug -Message "Username for job : $($param.username)"
247*eeb7e5b3SAdam Hornáček Write-Debug -Message "Password for job : $($param.Password)"
248*eeb7e5b3SAdam Hornáček Write-Debug -Message "ForestAdmin Username : $($param.ForestAdminUserName)"
249*eeb7e5b3SAdam Hornáček Write-Debug -Message "ForestAdmin Password : $($param.ForestAdminPassword)"
250*eeb7e5b3SAdam Hornáček }
251*eeb7e5b3SAdam Hornáček else
252*eeb7e5b3SAdam Hornáček {
253*eeb7e5b3SAdam Hornáček $param.Add('UserName', ('{0}\{1}' -f $machine.Name, $machine.InstallationUser.UserName))
254*eeb7e5b3SAdam Hornáček $param.Add('Password', $machine.InstallationUser.Password)
255*eeb7e5b3SAdam Hornáček }
256*eeb7e5b3SAdam Hornáček $param.Add('ComputerName', $Machine.Name)
257*eeb7e5b3SAdam Hornáček #endregion
258*eeb7e5b3SAdam Hornáček
259*eeb7e5b3SAdam Hornáček
260*eeb7e5b3SAdam Hornáček
261*eeb7e5b3SAdam Hornáček #region - Determine DNS name for machine. This is used when installing Enterprise CAs
262*eeb7e5b3SAdam Hornáček $caDNSName = $Machine.Name
263*eeb7e5b3SAdam Hornáček if ($Machine.DomainName) { $caDNSName += ('.' + $Machine.DomainName) }
264*eeb7e5b3SAdam Hornáček
265*eeb7e5b3SAdam Hornáček if ($Machine.DomainName)
266*eeb7e5b3SAdam Hornáček {
267*eeb7e5b3SAdam Hornáček $param.Add('DomainName', $Machine.DomainName)
268*eeb7e5b3SAdam Hornáček }
269*eeb7e5b3SAdam Hornáček else
270*eeb7e5b3SAdam Hornáček {
271*eeb7e5b3SAdam Hornáček $param.Add('DomainName', '')
272*eeb7e5b3SAdam Hornáček }
273*eeb7e5b3SAdam Hornáček
274*eeb7e5b3SAdam Hornáček
275*eeb7e5b3SAdam Hornáček if ($role.Name -eq 'CaSubordinate')
276*eeb7e5b3SAdam Hornáček {
277*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('ParentCA'))) { $param.Add('ParentCA', '<auto>') }
278*eeb7e5b3SAdam Hornáček else { $param.Add('ParentCA', $role.Properties.ParentCA) }
279*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('ParentCALogicalName'))) { $param.Add('ParentCALogicalName', '<auto>') }
280*eeb7e5b3SAdam Hornáček else { $param.Add('ParentCALogicalName', $role.Properties.ParentCALogicalName) }
281*eeb7e5b3SAdam Hornáček }
282*eeb7e5b3SAdam Hornáček
283*eeb7e5b3SAdam Hornáček #...
284*eeb7e5b3SAdam Hornáček
285*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('CPSURL'))) { $param.Add('CPSURL', 'http://' + $caDNSName + '/cps/cps.html') }
286*eeb7e5b3SAdam Hornáček else { $param.Add('CPSURL', $role.Properties.CPSURL) }
287*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('CPSText'))) { $param.Add('CPSText', 'Certification Practice Statement') }
288*eeb7e5b3SAdam Hornáček else { $param.Add('CPSText', $($role.Properties.CPSText)) }
289*eeb7e5b3SAdam Hornáček
290*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('InstallOCSP'))) { $param.Add('InstallOCSP', '<auto>') }
291*eeb7e5b3SAdam Hornáček else { $param.Add('InstallOCSP', ($role.Properties.InstallOCSP -like '*Y*')) }
292*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('OCSPHTTPURL01'))) { $param.Add('OCSPHTTPURL01', '<auto>') }
293*eeb7e5b3SAdam Hornáček else { $param.Add('OCSPHTTPURL01', $role.Properties.OCSPHTTPURL01) }
294*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('OCSPHTTPURL02'))) { $param.Add('OCSPHTTPURL02', '<auto>') }
295*eeb7e5b3SAdam Hornáček else { $param.Add('OCSPHTTPURL02', $role.Properties.OCSPHTTPURL02) }
296*eeb7e5b3SAdam Hornáček
297*eeb7e5b3SAdam Hornáček if (!($role.Properties.ContainsKey('DoNotLoadDefaultTemplates'))) { $param.Add('DoNotLoadDefaultTemplates', '<auto>') }
298*eeb7e5b3SAdam Hornáček else { $param.Add('DoNotLoadDefaultTemplates', $role.Properties.DoNotLoadDefaultTemplates -like '*Y*') }
299*eeb7e5b3SAdam Hornáček
300*eeb7e5b3SAdam Hornáček
301*eeb7e5b3SAdam Hornáček #region - Check if any unknown parameter name was passed
302*eeb7e5b3SAdam Hornáček $knownParameters = @()
303*eeb7e5b3SAdam Hornáček $knownParameters += 'ParentCA (only valid for Subordinate CA. Ignored for Root CAs)'
304*eeb7e5b3SAdam Hornáček $knownParameters += 'ParentCALogicalName (only valid for Subordinate CAs. Ignored for Root CAs)'
305*eeb7e5b3SAdam Hornáček $knownParameters += 'CACommonName'
306*eeb7e5b3SAdam Hornáček $knownParameters += 'CAType'
307*eeb7e5b3SAdam Hornáček #...
308*eeb7e5b3SAdam Hornáček $knownParameters += 'DoNotLoadDefaultTemplates'
309*eeb7e5b3SAdam Hornáček $knownParameters += 'PreDelaySeconds'
310*eeb7e5b3SAdam Hornáček $unkownParFound = $false
311*eeb7e5b3SAdam Hornáček foreach ($keySet in $role.Properties.GetEnumerator())
312*eeb7e5b3SAdam Hornáček {
313*eeb7e5b3SAdam Hornáček if ($keySet.Key -cnotin $knownParameters)
314*eeb7e5b3SAdam Hornáček {
315*eeb7e5b3SAdam Hornáček Write-Warning -Message "Parameter name '$($keySet.Key)' is unknown/ignored)"
316*eeb7e5b3SAdam Hornáček $unkownParFound = $true
317*eeb7e5b3SAdam Hornáček }
318*eeb7e5b3SAdam Hornáček }
319*eeb7e5b3SAdam Hornáček if ($unkownParFound)
320*eeb7e5b3SAdam Hornáček {
321*eeb7e5b3SAdam Hornáček Write-Warning -Message 'Valid parameter names are:'
322*eeb7e5b3SAdam Hornáček Foreach ($name in ($knownParameters.GetEnumerator()))
323*eeb7e5b3SAdam Hornáček {
324*eeb7e5b3SAdam Hornáček Write-Warning -Message " $($name)"
325*eeb7e5b3SAdam Hornáček }
326*eeb7e5b3SAdam Hornáček Write-Warning -Message 'NOTE that all parameter names are CASE SENSITIVE!'
327*eeb7e5b3SAdam Hornáček }
328*eeb7e5b3SAdam Hornáček #endregion - Check if any unknown parameter names was passed
329*eeb7e5b3SAdam Hornáček
330*eeb7e5b3SAdam Hornáček #endregion - Parameters
331*eeb7e5b3SAdam Hornáček
332*eeb7e5b3SAdam Hornáček
333*eeb7e5b3SAdam Hornáček #region - Parameters debug
334*eeb7e5b3SAdam Hornáček Write-Debug -Message '---------------------------------------------------------------------------------------'
335*eeb7e5b3SAdam Hornáček Write-Debug -Message "Parameters for $($machine.name)"
336*eeb7e5b3SAdam Hornáček Write-Debug -Message '---------------------------------------------------------------------------------------'
337*eeb7e5b3SAdam Hornáček if ($machine.Roles.Properties.GetEnumerator().Count)
338*eeb7e5b3SAdam Hornáček {
339*eeb7e5b3SAdam Hornáček foreach ($r in $machine.Roles)
340*eeb7e5b3SAdam Hornáček {
341*eeb7e5b3SAdam Hornáček if (([AutomatedLab.Roles]$r.Name -band $roles) -ne 0) #if this is a CA role
342*eeb7e5b3SAdam Hornáček {
343*eeb7e5b3SAdam Hornáček foreach ($key in ($r.Properties.GetEnumerator() | Sort-Object -Property Key))
344*eeb7e5b3SAdam Hornáček {
345*eeb7e5b3SAdam Hornáček Write-Debug -Message " $($key.Key.PadRight(27)) $($key.Value)"
346*eeb7e5b3SAdam Hornáček }
347*eeb7e5b3SAdam Hornáček }
348*eeb7e5b3SAdam Hornáček }
349*eeb7e5b3SAdam Hornáček }
350*eeb7e5b3SAdam Hornáček else
351*eeb7e5b3SAdam Hornáček {
352*eeb7e5b3SAdam Hornáček Write-Debug -message ' No parameters specified'
353*eeb7e5b3SAdam Hornáček }
354*eeb7e5b3SAdam Hornáček Write-Debug -Message '---------------------------------------------------------------------------------------'
355*eeb7e5b3SAdam Hornáček #endregion - Parameters debug
356*eeb7e5b3SAdam Hornáček
357*eeb7e5b3SAdam Hornáček
358*eeb7e5b3SAdam Hornáček #region ----- Input validation (raw values) -----
359*eeb7e5b3SAdam Hornáček if ($role.Properties.ContainsKey('CACommonName') -and ($param.CACommonName.Length -gt 37))
360*eeb7e5b3SAdam Hornáček {
361*eeb7e5b3SAdam Hornáček Write-Error -Message "CACommonName cannot be longer than 37 characters. Specified value is: '$($param.CACommonName)'"; return
362*eeb7e5b3SAdam Hornáček }
363*eeb7e5b3SAdam Hornáček
364*eeb7e5b3SAdam Hornáček if ($role.Properties.ContainsKey('CACommonName') -and ($param.CACommonName.Length -lt 1))
365*eeb7e5b3SAdam Hornáček {
366*eeb7e5b3SAdam Hornáček Write-Error -Message "CACommonName cannot be blank. Specified value is: '$($param.CACommonName)'"; return
367*eeb7e5b3SAdam Hornáček }
368*eeb7e5b3SAdam Hornáček
369*eeb7e5b3SAdam Hornáček if ($role.Name -eq 'CaRoot')
370*eeb7e5b3SAdam Hornáček {
371*eeb7e5b3SAdam Hornáček if (-not ($param.CAType -in 'EnterpriseRootCA', 'StandAloneRootCA', '<auto>'))
372*eeb7e5b3SAdam Hornáček {
373*eeb7e5b3SAdam Hornáček Write-Error -Message "CAType needs to be 'EnterpriseRootCA' or 'StandAloneRootCA' when role is CaRoot. Specified value is: '$param.CAType'"; return
374*eeb7e5b3SAdam Hornáček }
375*eeb7e5b3SAdam Hornáček }
376*eeb7e5b3SAdam Hornáček
377*eeb7e5b3SAdam Hornáček if ($role.Name -eq 'CaSubordinate')
378*eeb7e5b3SAdam Hornáček {
379*eeb7e5b3SAdam Hornáček if (-not ($param.CAType -in 'EnterpriseSubordinateCA', 'StandAloneSubordinateCA', '<auto>'))
380*eeb7e5b3SAdam Hornáček {
381*eeb7e5b3SAdam Hornáček Write-Error -Message "CAType needs to be 'EnterpriseSubordinateCA' or 'StandAloneSubordinateCA' when role is CaSubordinate. Specified value is: '$param.CAType'"; return
382*eeb7e5b3SAdam Hornáček }
383*eeb7e5b3SAdam Hornáček }
384*eeb7e5b3SAdam Hornáček
385*eeb7e5b3SAdam Hornáček
386*eeb7e5b3SAdam Hornáček $availableCombinations = @()
387*eeb7e5b3SAdam Hornáček $availableCombinations += @{CryptoProviderName='Microsoft Base SMart Card Crypto Provider'; HashAlgorithmName='sha1','md2','md4','md5'; KeyLength='1024','2048','4096'}
388*eeb7e5b3SAdam Hornáček #...
389*eeb7e5b3SAdam Hornáček $combination = $availableCombinations | Where-Object {$_.CryptoProviderName -eq $param.CryptoProviderName}
390*eeb7e5b3SAdam Hornáček
391*eeb7e5b3SAdam Hornáček if (-not ($param.CryptoProviderName -in $combination.CryptoProviderName))
392*eeb7e5b3SAdam Hornáček {
393*eeb7e5b3SAdam Hornáček Write-Error -Message "CryptoProviderName '$($param.CryptoProviderName)' is unknown. `nList of valid options for CryptoProviderName:`n $($availableCombinations.CryptoProviderName -join "`n ")"; return
394*eeb7e5b3SAdam Hornáček }
395*eeb7e5b3SAdam Hornáček elseif (-not ($param.HashAlgorithmName -in $combination.HashAlgorithmName))
396*eeb7e5b3SAdam Hornáček {
397*eeb7e5b3SAdam Hornáček Write-Error -Message "HashAlgorithmName '$($param.HashAlgorithmName)' is not valid for CryptoProviderName '$($param.CryptoProviderName)'. The Crypto Provider selected supports the following Hash Algorithms:`n $($combination.HashAlgorithmName -join "`n ")"; return
398*eeb7e5b3SAdam Hornáček }
399*eeb7e5b3SAdam Hornáček elseif (-not ($param.KeyLength -in $combination.KeyLength))
400*eeb7e5b3SAdam Hornáček {
401*eeb7e5b3SAdam Hornáček Write-Error -Message "Keylength '$($param.KeyLength)' is not valid for CryptoProviderName '$($param.CryptoProviderName)'. The Crypto Provider selected supports the following keylengths:`n $($combination.KeyLength -join "`n ")"; return
402*eeb7e5b3SAdam Hornáček }
403*eeb7e5b3SAdam Hornáček
404*eeb7e5b3SAdam Hornáček
405*eeb7e5b3SAdam Hornáček
406*eeb7e5b3SAdam Hornáček if ($role.Properties.ContainsKey('DatabaseDirectory') -and -not ($param.DatabaseDirectory -match '^[C-Z]:\\'))
407*eeb7e5b3SAdam Hornáček {
408*eeb7e5b3SAdam Hornáček Write-Error -Message 'DatabaseDirectory needs to be located on a local drive (drive letter C-Z)'; return
409*eeb7e5b3SAdam Hornáček }
410*eeb7e5b3SAdam Hornáček
411*eeb7e5b3SAdam Hornáček #...
412*eeb7e5b3SAdam Hornáček
413*eeb7e5b3SAdam Hornáček #if any validity parameter was defined, get these now and convert them all to hours (temporary variables)
414*eeb7e5b3SAdam Hornáček if ($param.ValidityPeriodUnits -ne '<auto>')
415*eeb7e5b3SAdam Hornáček {
416*eeb7e5b3SAdam Hornáček switch ($param.ValidityPeriod)
417*eeb7e5b3SAdam Hornáček {
418*eeb7e5b3SAdam Hornáček 'Years' { $validityPeriodUnitsHours = [int]$param.ValidityPeriodUnits * 365 * 24 }
419*eeb7e5b3SAdam Hornáček 'Months' { $validityPeriodUnitsHours = [int]$param.ValidityPeriodUnits * (365/12) * 24 }
420*eeb7e5b3SAdam Hornáček 'Weeks' { $validityPeriodUnitsHours = [int]$param.ValidityPeriodUnits * 7 * 24 }
421*eeb7e5b3SAdam Hornáček 'Days' { $validityPeriodUnitsHours = [int]$param.ValidityPeriodUnits * 24 }
422*eeb7e5b3SAdam Hornáček 'Hours' { $validityPeriodUnitsHours = [int]$param.ValidityPeriodUnits }
423*eeb7e5b3SAdam Hornáček }
424*eeb7e5b3SAdam Hornáček }
425*eeb7e5b3SAdam Hornáček if ($param.CertsValidityPeriodUnits -ne '<auto>')
426*eeb7e5b3SAdam Hornáček {
427*eeb7e5b3SAdam Hornáček switch ($param.CertsValidityPeriod)
428*eeb7e5b3SAdam Hornáček {
429*eeb7e5b3SAdam Hornáček 'Years' { $certsvalidityPeriodUnitsHours = [int]$param.CertsValidityPeriodUnits * 365 * 24 }
430*eeb7e5b3SAdam Hornáček 'Months' { $certsvalidityPeriodUnitsHours = [int]$param.CertsValidityPeriodUnits * (365/12) * 24 }
431*eeb7e5b3SAdam Hornáček 'Weeks' { $certsvalidityPeriodUnitsHours = [int]$param.CertsValidityPeriodUnits * 7 * 24 }
432*eeb7e5b3SAdam Hornáček 'Days' { $certsvalidityPeriodUnitsHours = [int]$param.CertsValidityPeriodUnits * 24 }
433*eeb7e5b3SAdam Hornáček 'Hours' { $certsvalidityPeriodUnitsHours = [int]$param.CertsValidityPeriodUnits }
434*eeb7e5b3SAdam Hornáček }
435*eeb7e5b3SAdam Hornáček }
436*eeb7e5b3SAdam Hornáček if ($param.CRLPeriodUnits -ne '<auto>')
437*eeb7e5b3SAdam Hornáček {
438*eeb7e5b3SAdam Hornáček switch ($param.CRLPeriod)
439*eeb7e5b3SAdam Hornáček {
440*eeb7e5b3SAdam Hornáček 'Years' { $cRLPeriodUnitsHours = [int]([int]$param.CRLPeriodUnits * 365 * 24) }
441*eeb7e5b3SAdam Hornáček 'Months' { $cRLPeriodUnitsHours = [int]([int]$param.CRLPeriodUnit * (365/12) * 24) }
442*eeb7e5b3SAdam Hornáček 'Weeks' { $cRLPeriodUnitsHours = [int]([int]$param.CRLPeriodUnits * 7 * 24) }
443*eeb7e5b3SAdam Hornáček 'Days' { $cRLPeriodUnitsHours = [int]([int]$param.CRLPeriodUnits * 24) }
444*eeb7e5b3SAdam Hornáček 'Hours' { $cRLPeriodUnitsHours = [int]([int]$param.CRLPeriodUnits) }
445*eeb7e5b3SAdam Hornáček }
446*eeb7e5b3SAdam Hornáček }
447*eeb7e5b3SAdam Hornáček if ($param.CRLDeltaPeriodUnits -ne '<auto>')
448*eeb7e5b3SAdam Hornáček {
449*eeb7e5b3SAdam Hornáček switch ($param.CRLDeltaPeriod)
450*eeb7e5b3SAdam Hornáček {
451*eeb7e5b3SAdam Hornáček 'Years' { $cRLDeltaPeriodUnitsHours = [int]([int]$param.CRLDeltaPeriodUnits * 365 * 24) }
452*eeb7e5b3SAdam Hornáček 'Months' { $cRLDeltaPeriodUnitsHours = [int]([int]$param.CRLDeltaPeriodUnits * (365/12) * 24) }
453*eeb7e5b3SAdam Hornáček 'Weeks' { $cRLDeltaPeriodUnitsHours = [int]([int]$param.CRLDeltaPeriodUnits * 7 * 24) }
454*eeb7e5b3SAdam Hornáček 'Days' { $cRLDeltaPeriodUnitsHours = [int]([int]$param.CRLDeltaPeriodUnits * 24) }
455*eeb7e5b3SAdam Hornáček 'Hours' { $cRLDeltaPeriodUnitsHours = [int]([int]$param.CRLDeltaPeriodUnits) }
456*eeb7e5b3SAdam Hornáček }
457*eeb7e5b3SAdam Hornáček }
458*eeb7e5b3SAdam Hornáček if ($param.CRLOverlapUnits -ne '<auto>')
459*eeb7e5b3SAdam Hornáček {
460*eeb7e5b3SAdam Hornáček switch ($param.CRLOverlapPeriod)
461*eeb7e5b3SAdam Hornáček {
462*eeb7e5b3SAdam Hornáček 'Years' { $CRLOverlapUnitsHours = [int]([int]$param.CRLOverlapUnits * 365 * 24) }
463*eeb7e5b3SAdam Hornáček 'Months' { $CRLOverlapUnitsHours = [int]([int]$param.CRLOverlapUnits * (365/12) * 24) }
464*eeb7e5b3SAdam Hornáček 'Weeks' { $CRLOverlapUnitsHours = [int]([int]$param.CRLOverlapUnits * 7 * 24) }
465*eeb7e5b3SAdam Hornáček 'Days' { $CRLOverlapUnitsHours = [int]([int]$param.CRLOverlapUnits * 24) }
466*eeb7e5b3SAdam Hornáček 'Hours' { $CRLOverlapUnitsHours = [int]([int]${param}.CRLOverlapUnits) }
467*eeb7e5b3SAdam Hornáček }
468*eeb7e5b3SAdam Hornáček }
469*eeb7e5b3SAdam Hornáček #...
470*eeb7e5b3SAdam Hornáček }
471*eeb7e5b3SAdam Hornáček #endregion Install-LabCAMachine
472*eeb7e5b3SAdam Hornáček #...
473*eeb7e5b3SAdam Hornáček <#http://example.com.#>
474*eeb7e5b3SAdam Hornáček Write-Debug `$`{`}
475*eeb7e5b3SAdam Hornáček Write-Debug $false.$true.$param
476*eeb7e5b3SAdam Hornáček $(Write-Debug $true)
477*eeb7e5b3SAdam Hornáček
478*eeb7e5b3SAdam Hornáček :OuterLoop while ($true) {
479*eeb7e5b3SAdam Hornáček while ($true) { break OuterLoop }
480*eeb7e5b3SAdam Hornáček }
481