526 lines
25 KiB
PowerShell
526 lines
25 KiB
PowerShell
|
function Install-CertificationAuthority {
|
|||
|
<#
|
|||
|
.Synopsis
|
|||
|
Installs Active Directory Certificate Services role on local computer.
|
|||
|
.Description
|
|||
|
Installs Active Directory Certificate Services (AD CS) role on local computer. A user can choose different options, such
|
|||
|
Certification Authority (CA) type, key pair parameters, CA certificate validity and so on.
|
|||
|
|
|||
|
The command supports Windows Server 2008 R2 Server Core installations.
|
|||
|
.Parameter CAName
|
|||
|
Specifies a custom CA certificate name/subject (what you see in the certificate display UI). If not passed, a '<ComputerName>-CA'
|
|||
|
form is used for workgroup CAs and '<DomainName>-<ComputerName-CA>' form is used for domain CAs. The parameter supports Unicode names.
|
|||
|
.Parameter CADNSuffix
|
|||
|
Specifies a DN suffix to specify some additional information. For example, company name, country, city, etc. DN suffix is empty for
|
|||
|
workgroup CAs and includes current domain distinguished name (for example, DC=domain,DC=com). The parameter accepts suffixes in a
|
|||
|
X500 form, for example: OU=Information Systems, O=Sysadmins LV, C=LV.
|
|||
|
.Parameter CAType
|
|||
|
Specifies CA type:
|
|||
|
|
|||
|
Standalone Root,
|
|||
|
Standalone Subordinate,
|
|||
|
Enterprise Root,
|
|||
|
Enterprise Subordinate.
|
|||
|
|
|||
|
If not passed, for non-domain environments or if you don't have Enterprise Admins rights, Standalone Root is used. If you have
|
|||
|
Enterprise Admins rights and your forest already has installed CAs, Enterprise Subordinate is used. If no Enterprise CAs installed
|
|||
|
in the forest, Enterprise Root is used.
|
|||
|
.Parameter ParentCA
|
|||
|
This parameter allows you to specify parent CA location only if you install Enterprise Subordinate CA. For other CA types, the
|
|||
|
parameter is ignored. Parent CA information must be passed in the following form: CAComputerName\CASanitizedName. Sanitized name
|
|||
|
is a sanitized form of CA name (subject). Mostly sanitized name is the same as CA name (unless you use Unicode and/or special
|
|||
|
characters, that are disallowed in X500). If the parameter is not specified, a certificate request will be generated on the root
|
|||
|
of system drive. I've decided to not implement this parameter for Standalone Subordinate CAs, because mostly they are installed
|
|||
|
in a workgroup environments and direct request submission to other CAs is likely unavailable (due of computer authentication
|
|||
|
complexity in the non-domain environments). However, if you need it — contact me.
|
|||
|
.Parameter CSP
|
|||
|
Specifies custom cryptographic service provider. By default 'RSA#Microsoft Software Key Storage Provider' is used (in most cases
|
|||
|
you will use default CSP). You need to explicitly specify custom CSP only when you setup completely CNG authority (CSPs with ECDSA
|
|||
|
prefix) or you use HSM. Each HSM uses it's own custom CSP. You must install HSM middleware before CA installation.
|
|||
|
|
|||
|
The full list of supportable and available "by default" CSPs for Windows Server 2008+ is:
|
|||
|
|
|||
|
Microsoft Base Cryptographic Provider v1.0
|
|||
|
Microsoft Base DSS Cryptographic Provider
|
|||
|
Microsoft Base Smart Card Crypto Provider
|
|||
|
Microsoft Enhanced Cryptographic Provider v1.0
|
|||
|
Microsoft Strong Cryptographic Provider
|
|||
|
RSA#Microsoft Software Key Storage Provider
|
|||
|
DSA#Microsoft Software Key Storage Provider
|
|||
|
ECDSA_P256#Microsoft Software Key Storage Provider
|
|||
|
ECDSA_P384#Microsoft Software Key Storage Provider
|
|||
|
ECDSA_P521#Microsoft Software Key Storage Provider
|
|||
|
RSA#Microsoft Smart Card Key Storage Provider
|
|||
|
ECDSA_P256#Microsoft Smart Card Key Storage Provider
|
|||
|
ECDSA_P384#Microsoft Smart Card Key Storage Provider
|
|||
|
ECDSA_P521#Microsoft Smart Card Key Storage Provider
|
|||
|
.Parameter KeyLength
|
|||
|
This parameter specifies the key length. If not specified, a 2048-bit key will be generated. There is a little trick: if you look to
|
|||
|
a CSP list (above), you will see that key length is specified for each ECDSA* provider. I've developed a script logic in that way,
|
|||
|
so the script ignores this parameter if one of ECDSA* CSP is explicitly chosen and uses key length that is supported by the CSP.
|
|||
|
Therefore you will not receive an error if you select 'ECDSA_P256#Microsoft Smart Card Key Storage Provider' CSP with 2048 key length.
|
|||
|
256-bit key will be selected automatically
|
|||
|
.Parameter HashAlgorithm
|
|||
|
This parameter specifies hash algorithm that will be used for CA certificate/request hashing. Note that this is important for root
|
|||
|
CA installations. Subordinate CA certificates are hashed and signed by the parent CA with it's own settings. By default 'SHA1' is
|
|||
|
used (though this parameter is applicable for all CA installation types).
|
|||
|
.Parameter ValidForYears
|
|||
|
Specifies the validity for root CA installations. By default root CA certificates are valid for 5 years. You can increase this value
|
|||
|
to 10, 20, 50, whatever you need. For any subordinate CA types this parameter is silently ignored. This is because subordinate CA
|
|||
|
validity is determined by the parent CA. This parameter accepts integer values, assuming that the value is specified in years.
|
|||
|
.Parameter RequestFileName
|
|||
|
If you setup any sort of subordinate (not root) CAs you can specify custom path to a request file. By default request file is
|
|||
|
generated on the root of system drive.
|
|||
|
.Parameter CACertFile
|
|||
|
Specifies the path to a PFX file with CA certificate. Relative paths are allowed. Setup API performs additional checks for the certificate.
|
|||
|
Therefore you must ensure if: this is CA certificate (but not EFS encryption ;)), CA certificate is trusted (for non-root certificates)
|
|||
|
and chains to trusted CA and CA certificate revocation checking can be performed. Otherwise you will unable to setup CA with that CA certificate.
|
|||
|
.Parameter Password
|
|||
|
Specifies the password to open PFX file. The parameter supports only securestrings! You can't type a password as a simple text. This is made for
|
|||
|
security reasons. There are few ways to pass a password in a securestring form:
|
|||
|
|
|||
|
$Password = Read-Host –a
|
|||
|
|
|||
|
or
|
|||
|
|
|||
|
ConvertTo-SecureString <plaintext> –a –f
|
|||
|
|
|||
|
You can enclose last command in parentheses and pass directly as a parameter value.
|
|||
|
.Parameter Thumbprint
|
|||
|
specifies a thumbprint of the certificate to use. The certificate must be installed in Local Machine\Personal store and must be trusted
|
|||
|
(for non-root certificates) and must not be revoked (the issuer revocation information must be available).
|
|||
|
.Parameter DBDirectory
|
|||
|
Specifies the path to a folder to store CA database. If not specified, the default path: %windir%\System32\CertLog folder is used. If you
|
|||
|
need to specify custom path (for example, shared storage for CA clusters), you need to specify the next parameter too. The path must be valid.
|
|||
|
.Parameter LogDirectory
|
|||
|
Specifies the path to a folderto store CA database log files. By default %windir%\System32\CertLog folder is used. If you use custom path for
|
|||
|
either database or log folders, you must explicitly specify both paths.
|
|||
|
.Parameter OverwriteExisting
|
|||
|
Specifies, whether to overwrite any existing database files in the specified directories.
|
|||
|
.Parameter AllowCSPInteraction
|
|||
|
Specifies, whether the cryptographic service provider (CSP) is allowed to interact with the desktop. This parameter should be used only if you
|
|||
|
use custom hardware-based CSP (HSM or smart card CSP). In other cases you don't need to allow CSP interactions.
|
|||
|
.Parameter Force
|
|||
|
By default, the script explicitly prompts you whether you want to install Certification Authority with selected values. If you want to implement
|
|||
|
silent (quiet) installations — specify this parameter to suppress any prompts during role installation
|
|||
|
.EXAMPLE
|
|||
|
PS > Install-CertificationAuthority -CAName "My Root CA" -CADNSuffix "OU=Information Systems, O=Sysadmins LV, C=LV" `
|
|||
|
-CAType "Standalone Root" -ValidForYears 10
|
|||
|
|
|||
|
|
|||
|
In this scenario you setup new Standalone Root CA with "CN=My Root CA, OU=Information Systems, O=Sysadmins LV, C=LV" subject, that will be valid
|
|||
|
for 10 years. The CA will use default paths to CA database and log files and certificate will use 'RSA#Microsoft Software Key Storage Provider'
|
|||
|
CSP with 2048-bit key and SHA1 hashing algorithm.
|
|||
|
.EXAMPLE
|
|||
|
PS > Install-CertificationAuthority -CAName "My Root CA" -CADNSuffix "OU=Information Systems, O=Sysadmins LV, C=LV" `
|
|||
|
-CAType "Standalone Root" -ValidForYears 20 -CSP "ECDSA_P256#Microsoft Smart Card Key Storage Provider" `
|
|||
|
-HashAlgorithm SHA512
|
|||
|
|
|||
|
This example is similar to previous, with the exception that this CA will be completely CNG/SHA2 root. CA certificate will use CNG (not RSA)
|
|||
|
keys and hashing algorithm will be SHA512.
|
|||
|
.EXAMPLE
|
|||
|
PS > Install-CertificationAuthority -CAName "Clustered CA" -CADNSuffix "OU=Information Systems, O=Sysadmins LV, C=LV" `
|
|||
|
-CAType "Enterprise Subordinate" -KeyLength 4096 -DBDirectory "S:\CertDB" -LogDirectory "S:\CertLog" `
|
|||
|
-RequestFileName "S:\Clustered CA.req"
|
|||
|
|
|||
|
This example assumes that you setup CA cluster first node (but not necessary). CA database will be stored on a shared storage (attached with S: drive letter).
|
|||
|
CA certificate will use default 'RSA#Microsoft Software Key Storage Provider' with 4096-bit key and default SHA1 hashing algorithm. CA certificate validity
|
|||
|
will be determined by the parent CA. In addition, CA certificate request will be stored on the shared storage.
|
|||
|
.EXAMPLE
|
|||
|
PS > $Password = Read-Host -AsSecureString
|
|||
|
PS > Install-CertificationAuthority -CACertFile .\ClusteredCA.pfx -Password $Password `
|
|||
|
-DBDirectory "S:\CertDB" -LogDirectory "S:\CertLog" -OverwriteExisting
|
|||
|
|
|||
|
This is two-line example. Say, you have successfully installed CA cluster first node and have exported CA certificate to a PFX, and moved it to the second
|
|||
|
node (to the current directory). At first you will be prompted for a password. Since you type password to a securestring prompt, no characters will be displayed.
|
|||
|
After that you will specify relative path to a PFX file and specify shared storage to store CA database and log files. You overwrite database files that was
|
|||
|
created during first node installation. Actually this command installs CA cluster second node.
|
|||
|
.EXAMPLE
|
|||
|
PS > Install-CertificationAuthority -CAName "Company Enterprise CA-2" -CADNSuffix "O=Company, E=companypky@company.com" `
|
|||
|
-CAType "Enterprise Subordinate" -ParentCA "ca01.company.com\Company Enterprise CA-1"
|
|||
|
|
|||
|
From best-practices perspective this is not a very good example, because it assumes at least 2 tiers of Enterprise CAs. However, it is still common. In a given
|
|||
|
example, Enterprise Subordinate CA will be installed and certificate request will be sent directly to existing Enterprise CA — 'Company Enterprise CA-1' that is
|
|||
|
hosted on 'ca01.company.com'. Note that existing CA must be online and must issue 'Subordinate Certification Authority' template.
|
|||
|
.Inputs
|
|||
|
None.
|
|||
|
.Outputs
|
|||
|
None.
|
|||
|
.NOTES
|
|||
|
Author: Vadims Podans
|
|||
|
Blog : http://en-us.sysadmins.lv
|
|||
|
#>
|
|||
|
[CmdletBinding(
|
|||
|
DefaultParameterSetName = 'NewKeySet',
|
|||
|
ConfirmImpact = 'High',
|
|||
|
SupportsShouldProcess = $true
|
|||
|
)]
|
|||
|
param(
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$CAName,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$CADNSuffix,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[ValidateSet("Standalone Root","Standalone Subordinate","Enterprise Root","Enterprise Subordinate")]
|
|||
|
[string]$CAType,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$ParentCA,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$CSP,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[int]$KeyLength,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$HashAlgorithm,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[int]$ValidForYears = 5,
|
|||
|
[Parameter(ParameterSetName = 'NewKeySet')]
|
|||
|
[string]$RequestFileName,
|
|||
|
[Parameter(Mandatory = $true, ParameterSetName = 'PFXKeySet')]
|
|||
|
[IO.FileInfo]$CACertFile,
|
|||
|
[Parameter(Mandatory = $true, ParameterSetName = 'PFXKeySet')]
|
|||
|
[Security.SecureString]$Password,
|
|||
|
[Parameter(Mandatory = $true, ParameterSetName = 'ExistingKeySet')]
|
|||
|
[string]$Thumbprint,
|
|||
|
[string]$DBDirectory,
|
|||
|
[string]$LogDirectory,
|
|||
|
[switch]$OverwriteExisting,
|
|||
|
[switch]$AllowCSPInteraction,
|
|||
|
[switch]$Force
|
|||
|
)
|
|||
|
|
|||
|
#region OS and existing CA checking
|
|||
|
# check if script running on Windows Server 2008 or Windows Server 2008 R2
|
|||
|
$OS = Get-WmiObject Win32_OperatingSystem -Property ProductType
|
|||
|
if ([Environment]::OSVersion.Version.Major -lt 6) {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotSupportedException" `
|
|||
|
-Message "Windows XP, Windows Server 2003 and Windows Server 2003 R2 are not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
if ($OS.ProductType -eq 1) {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotSupportedException" `
|
|||
|
-Message "Client operating systems are not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
$CertConfig = New-Object -ComObject CertificateAuthority.Config
|
|||
|
try {$ExistingDetected = $CertConfig.GetConfig(3)}
|
|||
|
catch {}
|
|||
|
if ($ExistingDetected) {
|
|||
|
Write-Error -Category ResourceExists -ErrorId "ResourceExistsException" `
|
|||
|
-Message "Certificate Services are already installed on this computer. Only one Certification Authority instance per computer is supported."
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Binaries checking and installation if necessary
|
|||
|
if ([Environment]::OSVersion.Version.Major -eq 6 -and [Environment]::OSVersion.Version.Minor -eq 0) {
|
|||
|
cmd /c "servermanagercmd -install AD-Certificate 2> null" | Out-Null
|
|||
|
} else {
|
|||
|
try {Import-Module ServerManager -ErrorAction Stop}
|
|||
|
catch {
|
|||
|
ocsetup 'ServerManager-PSH-Cmdlets' /quiet | Out-Null
|
|||
|
Start-Sleep 1
|
|||
|
Import-Module ServerManager -ErrorAction Stop
|
|||
|
}
|
|||
|
$status = (Get-WindowsFeature -Name AD-Certificate).Installed
|
|||
|
# if still no, install binaries, otherwise do nothing
|
|||
|
if (!$status) {$retn = Add-WindowsFeature -Name AD-Certificate -ErrorAction Stop
|
|||
|
if (!$retn.Success) {
|
|||
|
Write-Error -Category NotInstalled -ErrorId "NotInstalledException" `
|
|||
|
-Message "Unable to install ADCS installation packages due of the following error: $($retn.breakCode)"
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
try {$CASetup = New-Object -ComObject CertOCM.CertSrvSetup.1}
|
|||
|
catch {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotImplementedException" `
|
|||
|
-Message "Unable to load necessary interfaces. Your Windows Server operating system is not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
# initialize setup binaries
|
|||
|
try {$CASetup.InitializeDefaults($true, $false)}
|
|||
|
catch {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId ParameterIncorrectException `
|
|||
|
-ErrorAction Stop -Message "Cannot initialize setup binaries!"
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Property enums
|
|||
|
$CATypesByName = @{"Enterprise Root" = 0; "Enterprise Subordinate" = 1; "Standalone Root" = 3; "Standalone Subordinate" = 4}
|
|||
|
$CATypesByVal = @{}
|
|||
|
$CATypesByName.keys | ForEach-Object {$CATypesByVal.Add($CATypesByName[$_],$_)}
|
|||
|
$CAPRopertyByName = @{"CAType"=0;"CAKeyInfo"=1;"Interactive"=2;"ValidityPeriodUnits"=5;
|
|||
|
"ValidityPeriod"=6;"ExpirationDate"=7;"PreserveDataBase"=8;"DBDirectory"=9;"Logdirectory"=10;
|
|||
|
"ParentCAMachine"=12;"ParentCAName"=13;"RequestFile"=14;"WebCAMachine"=15;"WebCAName"=16
|
|||
|
}
|
|||
|
$CAPRopertyByVal = @{}
|
|||
|
$CAPRopertyByName.keys | ForEach-Object {$CAPRopertyByVal.Add($CAPRopertyByName[$_],$_)}
|
|||
|
$ValidityUnitsByName = @{"years" = 6}
|
|||
|
$ValidityUnitsByVal = @{6 = "years"}
|
|||
|
#endregion
|
|||
|
$ofs = ", "
|
|||
|
#region Key set processing functions
|
|||
|
|
|||
|
#region NewKeySet
|
|||
|
function NewKeySet ($CAName, $CADNSuffix, $CAType, $ParentCA, $CSP, $KeyLength, $HashAlgorithm, $ValidForYears, $RequestFileName) {
|
|||
|
|
|||
|
#region CSP, key length and hashing algorithm verification
|
|||
|
$CAKey = $CASetup.GetCASetupProperty(1)
|
|||
|
if ($CSP -ne "") {
|
|||
|
if ($CASetup.GetProviderNameList() -notcontains $CSP) {
|
|||
|
# TODO add available CSP list
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidCryptographicServiceProviderException" `
|
|||
|
-ErrorAction Stop -Message "Specified CSP '$CSP' is not valid!"
|
|||
|
} else {
|
|||
|
$CAKey.ProviderName = $CSP
|
|||
|
}
|
|||
|
} else {
|
|||
|
$CAKey.ProviderName = "RSA#Microsoft Software Key Storage Provider"
|
|||
|
}
|
|||
|
if ($KeyLength -ne 0) {
|
|||
|
if ($CASetup.GetKeyLengthList($CSP).Length -eq 1) {
|
|||
|
$CAKey.Length = $CASetup.GetKeyLengthList($CSP)[0]
|
|||
|
} else {
|
|||
|
if ($CASetup.GetKeyLengthList($CSP) -notcontains $KeyLength) {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidKeyLengthException" `
|
|||
|
-ErrorAction Stop -Message @"
|
|||
|
The specified key length '$KeyLength' is not supported by the selected CSP '$CSP' The following
|
|||
|
key lengths are supported by this CSP: $($CASetup.GetKeyLengthList($CSP))
|
|||
|
"@
|
|||
|
}
|
|||
|
$CAKey.Length = $KeyLength
|
|||
|
}
|
|||
|
}
|
|||
|
if ($HashAlgorithm -ne "") {
|
|||
|
if ($CASetup.GetHashAlgorithmList($CSP) -notcontains $HashAlgorithm) {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidHashAlgorithmException" `
|
|||
|
-ErrorAction Stop -Message @"
|
|||
|
The specified hash algorithm is not supported by the selected CSP '$CSP' The following
|
|||
|
hash algorithms are supported by this CSP: $($CASetup.GetHashAlgorithmList($CSP))
|
|||
|
"@
|
|||
|
}
|
|||
|
$CAKey.HashAlgorithm = $HashAlgorithm
|
|||
|
}
|
|||
|
$CASetup.SetCASetupProperty(1,$CAKey)
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Setting CA type
|
|||
|
if ($CAType) {
|
|||
|
$SupportedTypes = $CASetup.GetSupportedCATypes()
|
|||
|
$SelectedType = $CATypesByName[$CAType]
|
|||
|
if ($SupportedTypes -notcontains $CATypesByName[$CAType]) {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidCATypeException" `
|
|||
|
-ErrorAction Stop -Message @"
|
|||
|
Selected CA type: '$CAType' is not supported by current Windows Server installation.
|
|||
|
The following CA types are supported by this installation: $([int[]]$CASetup.GetSupportedCATypes() | %{$CATypesByVal[$_]})
|
|||
|
"@
|
|||
|
} else {$CASetup.SetCASetupProperty($CAPRopertyByName.CAType,$SelectedType)}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region setting CA certificate validity
|
|||
|
if ($SelectedType -eq 0 -or $SelectedType -eq 3 -and $ValidForYears -ne 0) {
|
|||
|
try{$CASetup.SetCASetupProperty(6,$ValidForYears)}
|
|||
|
catch {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidCAValidityException" `
|
|||
|
-ErrorAction Stop -Message "The specified CA certificate validity period '$ValidForYears' is invalid."
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region setting CA name
|
|||
|
if ($CAName -ne "") {
|
|||
|
if ($CADNSuffix -ne "") {$Subject = "CN=$CAName" + ",$CADNSuffix"} else {$Subject = "CN=$CAName"}
|
|||
|
$DN = New-Object -ComObject X509Enrollment.CX500DistinguishedName
|
|||
|
# validate X500 name format
|
|||
|
try {$DN.Encode($Subject,0x0)}
|
|||
|
catch {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidX500NameException" `
|
|||
|
-ErrorAction Stop -Message "Specified CA name or CA name suffix is not correct X.500 Distinguished Name."
|
|||
|
}
|
|||
|
$CASetup.SetCADistinguishedName($Subject, $true, $true, $true)
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region set parent CA/request file properties
|
|||
|
if ($CASetup.GetCASetupProperty(0) -eq 1 -and $ParentCA) {
|
|||
|
[void]($ParentCA -match "^(.+)\\(.+)$")
|
|||
|
try {$CASetup.SetParentCAInformation($ParentCA)}
|
|||
|
catch {
|
|||
|
Write-Error -Category ObjectNotFound -ErrorId "ObjectNotFoundException" `
|
|||
|
-ErrorAction Stop -Message @"
|
|||
|
The specified parent CA information '$ParentCA' is incorrect. Make sure if parent CA
|
|||
|
information is correct (you must specify existing CA) and is supplied in a 'CAComputerName\CASanitizedName' form.
|
|||
|
"@
|
|||
|
}
|
|||
|
} elseif ($CASetup.GetCASetupProperty(0) -eq 1 -or $CASetup.GetCASetupProperty(0) -eq 4 -and $RequestFileName -ne "") {
|
|||
|
$CASetup.SetCASetupProperty(14,$RequestFileName)
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region PFXKeySet
|
|||
|
function PFXKeySet ($CACertFile, $Password) {
|
|||
|
$FilePath = Resolve-Path $CACertFile -ErrorAction Stop
|
|||
|
try {[void]$CASetup.CAImportPFX(
|
|||
|
$FilePath.Path,
|
|||
|
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)),
|
|||
|
$true)
|
|||
|
} catch {Write-Error $_ -ErrorAction Stop}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ExistingKeySet
|
|||
|
function ExistingKeySet ($Thumbprint) {
|
|||
|
$ExKeys = $CASetup.GetExistingCACertificates() | ?{
|
|||
|
([Security.Cryptography.X509Certificates.X509Certificate2]$_.ExistingCACertificate).Thumbprint -eq $Thumbprint
|
|||
|
}
|
|||
|
if (!$ExKeys) {
|
|||
|
Write-Error -Category ObjectNotFound -ErrorId "ElementNotFoundException" `
|
|||
|
-ErrorAction Stop -Message "The system cannot find a valid CA certificate with thumbprint: $Thumbprint"
|
|||
|
} else {$CASetup.SetCASetupProperty(1,@($ExKeys)[0])}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region set database settings
|
|||
|
if ($DBDirectory -ne "" -and $LogDirectory -ne "") {
|
|||
|
try {$CASetup.SetDatabaseInformation($DBDirectory,$LogDirectory,$null,$OverwriteExisting)}
|
|||
|
catch {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidPathException" `
|
|||
|
-ErrorAction Stop -Message "Specified path to either database directory or log directory is invalid."
|
|||
|
}
|
|||
|
} elseif ($DBDirectory -ne "" -and $LogDirectory -eq "") {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidPathException" `
|
|||
|
-ErrorAction Stop -Message "CA Log file directory cannot be empty."
|
|||
|
} elseif ($DBDirectory -eq "" -and $LogDirectory -ne "") {
|
|||
|
Write-Error -Category InvalidArgument -ErrorId "InvalidPathException" `
|
|||
|
-ErrorAction Stop -Message "CA database directory cannot be empty."
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
# process parametersets.
|
|||
|
switch ($PSCmdlet.ParameterSetName) {
|
|||
|
"ExistingKeySet" {ExistingKeySet $Thumbprint}
|
|||
|
"PFXKeySet" {PFXKeySet $CACertFile $Password}
|
|||
|
"NewKeySet" {NewKeySet $CAName $CADNSuffix $CAType $ParentCA $CSP $KeyLength $HashAlgorithm $ValidForYears $RequestFileName}
|
|||
|
}
|
|||
|
try {
|
|||
|
Write-Host "Installing Certification Authority role on $env:computername ..." -ForegroundColor Cyan
|
|||
|
if ($Force -or $PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Install Certification Authority")) {
|
|||
|
$CASetup.Install()
|
|||
|
$PostRequiredMsg = @"
|
|||
|
Certification Authority role was successfully installed, but not completed. To complete installation submit
|
|||
|
request file '$($CASetup.GetCASetupProperty(14))' to parent Certification Authority
|
|||
|
and install issued certificate by running the following command: certutil -installcert 'PathToACertFile'
|
|||
|
"@
|
|||
|
if ($CASetup.GetCASetupProperty(0) -eq 1 -and $ParentCA -eq "") {
|
|||
|
Write-Host $PostRequiredMsg -ForegroundColor Yellow -BackgroundColor Black
|
|||
|
} elseif ($CASetup.GetCASetupProperty(0) -eq 1 -and $PSCmdlet.ParameterSetName -eq "NewKeySet" -and $ParentCA -ne "") {
|
|||
|
$CASName = (Get-ItemProperty HKLM:\System\CurrentControlSet\Services\CertSvc\Configuration).Active
|
|||
|
$SetupStatus = (Get-ItemProperty HKLM:\System\CurrentControlSet\Services\CertSvc\Configuration\$CASName).SetupStatus
|
|||
|
$RequestID = (Get-ItemProperty HKLM:\System\CurrentControlSet\Services\CertSvc\Configuration\$CASName).RequestID
|
|||
|
if ($SetupStatus -ne 1) {
|
|||
|
Write-Host $PostRequiredMsg -ForegroundColor Yellow -BackgroundColor Black
|
|||
|
}
|
|||
|
} elseif ($CASetup.GetCASetupProperty(0) -eq 4) {
|
|||
|
Write-Host $PostRequiredMsg -ForegroundColor Yellow -BackgroundColor Black
|
|||
|
} else {Write-Host "Certification Authority role is successfully installed!" -ForegroundColor Green}
|
|||
|
}
|
|||
|
} catch {Write-Error $_ -ErrorAction Stop}
|
|||
|
Remove-Module ServerManager -ErrorAction SilentlyContinue
|
|||
|
}
|
|||
|
|
|||
|
function Uninstall-CertificationAuthority {
|
|||
|
<#
|
|||
|
.Synopsis
|
|||
|
Uninstalls Active Directory Certificate Services role from the local computer.
|
|||
|
.Description
|
|||
|
Uninstalls Active Directory Certificate Services role from the local computer.
|
|||
|
|
|||
|
The command supports Windows Server 2008 R2 Server Core installations.
|
|||
|
.Parameter AutoRestart
|
|||
|
Automatically restarts computer to complete CA role removal. Otherwise you will have to restart the server manually.
|
|||
|
.Parameter Force
|
|||
|
By default, the commands prompts you whether you want to remove CA role. Use –Force switch to suppress all prompts.
|
|||
|
.EXAMPLE
|
|||
|
PS > Uninstall-CertificationAuthority -AutoRestart -Force
|
|||
|
|
|||
|
The command will uninstall CA role, suppresses all prompts and automatically restarts the server upon completion.
|
|||
|
.Inputs
|
|||
|
None.
|
|||
|
.Outputs
|
|||
|
None.
|
|||
|
.NOTES
|
|||
|
Author: Vadims Podans
|
|||
|
Blog : http://en-us.sysadmins.lv
|
|||
|
#>
|
|||
|
[CmdletBinding(
|
|||
|
ConfirmImpact = 'High',
|
|||
|
SupportsShouldProcess = $true
|
|||
|
)]
|
|||
|
param(
|
|||
|
[switch]$AutoRestart,
|
|||
|
[switch]$Force
|
|||
|
)
|
|||
|
|
|||
|
#region OS and existing CA checking
|
|||
|
# check if script running on Windows Server 2008 or Windows Server 2008 R2
|
|||
|
$OS = Get-WmiObject Win32_OperatingSystem -Property ProductType
|
|||
|
if ([Environment]::OSVersion.Version.Major -lt 6) {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotSupportedException" `
|
|||
|
-Message "Windows XP, Windows Server 2003 and Windows Server 2003 R2 are not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
if ($OS.ProductType -eq 1) {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotSupportedException" `
|
|||
|
-Message "Client operating systems are not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
$CertConfig = New-Object -ComObject CertificateAuthority.Config
|
|||
|
try {$ExistingDetected = $CertConfig.GetConfig(3)}
|
|||
|
catch {
|
|||
|
Write-Error -Category ObjectNotFound -ErrorId "ElementNotFoundException" `
|
|||
|
-ErrorAction Stop -Message "Certificate Services are not installed on this computer."
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Binaries checking and removal stuff
|
|||
|
try {$CASetup = New-Object -ComObject CertOCM.CertSrvSetup.1}
|
|||
|
catch {
|
|||
|
Write-Error -Category NotImplemented -ErrorId "NotImplementedException" `
|
|||
|
-Message "Unable to load necessary interfaces. Your Windows Server operating system is not supported!"
|
|||
|
return
|
|||
|
}
|
|||
|
if ([Environment]::OSVersion.Version.Major -eq 6 -and [Environment]::OSVersion.Version.Minor -eq 0) {
|
|||
|
cmd /c "servermanagercmd -remove ADCS-Cert-Authority 2> null" | Out-Null
|
|||
|
} else {
|
|||
|
try {Import-Module ServerManager -ErrorAction Stop}
|
|||
|
catch {
|
|||
|
ocsetup 'ServerManager-PSH-Cmdlets' /quiet | Out-Null
|
|||
|
Start-Sleep 2
|
|||
|
Import-Module ServerManager
|
|||
|
}
|
|||
|
$status = (Get-WindowsFeature -Name ADCS-Cert-Authority).Installed
|
|||
|
if ($status) {
|
|||
|
$WarningPreference = "SilentlyContinue"
|
|||
|
if ($Force -or $PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Uninstall Certification Authority")) {
|
|||
|
$CASetup.PreUninstall($false)
|
|||
|
$retn = Remove-WindowsFeature -Name ADCS-Cert-Authority -ErrorAction Stop
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if ($AutoRestart) {
|
|||
|
#Restart-Computer -Force
|
|||
|
} else {
|
|||
|
Write-Host "Certification Authority role was removed successfully. You must restart this server to complete role removal." `
|
|||
|
-ForegroundColor Yellow -BackgroundColor Black
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|