Hello again! Continuing Certificate Enrollment Service (CES) and Certificate Enrollment Policy (CEP) service subject I would like to post another PowerShell script that will install and remove CEP service. Like CES, CEP CryptoAPI COM interface is not documented yet. However you can manually find this interface in your registry:

these keys are located in HKEY_CLASSES_ROOT hive. Actually there are a lot of interesting things that are not documented on MSDN. I don't know why, so don't ask me why, I'm not Microsoft guy. The code is quite similar as posted in the previous post, so I don't think that I need to additionally explain something else. Yes, I know, I'm bad PowerShell MVP, because my posts are quite complex and not all PowerShell users can understand it. Instead I provide (ate least I try) finished solutions for end-users. They just run my scripts and get the fun (or PROFIT!!!). Let's go:

#####################################################################
# AddRemoveCEP.ps1
# Version 1.0
#
# Installs or removes Certificate Enrollment Policy service (CEP) instance
#
# Note: Requires Windows Server 2008 R2 Standard/Enterprise/Datacenter.
#
# Vadims Podans (c) 2010
# http://en-us.sysadmins.lv/
#####################################################################
#requires -Version 2.0

function Add-CEP {
<#
.Synopsis
    Installs Certificate Enrollment Policy Service instance to local computer
.Description
    This function installs Certificate Enrollment Policy Service instance to
    local computer and configures IIS web application.
.Parameter Authentication
    Specifies authentication type for communication. Possible values are:
    Kerberos, UsrPwd or Certificate. Kerberos is used by default.
.Parameter Thumbprint
    Specifies SSL certificate thumbprint.
.EXAMPLE
    Add-CEP
    
    Running command without parameters will install Certificate Enrollment Policy Service
    instance with the default Kerberos authentication. If no valid SSL certificate is
    found, the new one will be requested and assigned for CEP service.
.EXAMPLE
    Add-CEP -Authentication Certificate -Thumbprint D485FFFD6C2CBC161667087B3209CCD765A32544
    
    In this example CEP server will be configured to use Certificate authentication.
    In addition, IIS Default Web Site will be configured to use SSL certificate
    with thumbprint D485FFFD6C2CBC161667087B3209CCD765A32544. This certificate
    must be stored in LocalMachine store and has private key.
#>
[CmdletBinding()]
    param(
        [ValidateSet("UsrPwd", "Kerberos", "Certificate")]
        [string]$Authentication = "Kerberos",
        [string]$Thumbprint
    )

#region Check operating system
    $OS = (Get-WmiObject Win32_OperatingSystem).Caption
    if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
        Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
    }
#endregion

#region Check user permissions
# check if user has Enterprise Admins permissions
    $elevated = $false
    foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
        if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
            $elevated = $true
        }
    }
    if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion

#region Obtain SSL certificate from local store or enroll new one
    function Get-Cert {
        # retrieve current domain name. this suffix is used to construct current computer FQDN
        try {
            $domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name
        # if command above generates error, the computer is not a member of any AD domain
        } catch {Write-Warning "Current computer is not a part of any Active Directory domain!"; return}
        $fqdn = $env:COMPUTERNAME + "." + $domain
        $validCerts = @()
        # retrive all certificates from computer store that have private key and subject equals computer FQDN
        $certs = @(Get-ChildItem cert:\localmachine\my | ?{$_.HasPrivateKey -and $_.subject -eq "CN=$fqdn"})
        # loop extensions for EKU extension and check for Server Authentication OID
        foreach ($cert in $certs) {
            $eku = $cert.extensions | ?{$_.oid.value -eq "2.5.29.37"}
            if ($eku) {
                if ($eku.EnhancedKeyUsages | ?{$_.value -eq "1.3.6.1.5.5.7.3.1"}) {
                    # if certificate meet minimum requirements, write it to valid certs collection
                    $validCerts += $cert
                }
            }
        }
        # sort certificates in the collection by NotAfter and select one with the longest
        # validity
        if ($validCerts.count -gt 0) {
            ($validCerts | sort NotAfter | select -Last 1).Thumbprint
        } else {
            # if no valid certificate exist in the local store, enroll fro new one.
            $enrollment = New-Object -ComObject X509Enrollment.CX509enrollment
            # use ProductType of Win32_OperatingSystem class to determine computer role
            # domain Controller or Member Server.
            $ServerType = Get-WmiObject (Win32_OperatingSystem).ProductType
            if ($ServerType -eq 2) {$enrollment.InitializeFromTemplate(0x3, "DomainController")}
            elseif ($ServerType -eq 3) {$enrollment.InitializeFromTemplate(0x3, "Machine")}
            try {$enrollment.Enroll()}
            catch {
                Write-Warning "Unable to enroll SSL certificate. In order to use CEP server"
                Write-Warning "you will have to manually obtain SSL certificate and configure"
                Write-Warning "IIS to use this certificate."
                return
            }
            $base64 = $enrollment.Certificate(1)
            $cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2
            $cert.Import($([Convert]::FromBase64String($base64)))
            $cert.Thumbprint
        }
    }
#endregion

    $auth = @{"Kerberos" = 2; "UsrPwd" = 4; "Certificate" = 8}
    # we can use ServerManager module to install CEP binaries
    Import-Module ServerManager
    # at first check if CEP is already installed
    $status = (Get-WindowsFeature -Name ADCS-Enroll-Web-Pol).Installed
    # if still no, install binaries, otherwise do nothing
    if (!$status) {$retn = Add-WindowsFeature -Name ADCS-Enroll-Web-Pol
        if (!$retn.Success) {
            Write-Warning "Unable to install CES service installation packages due of the following error:"
            Write-Warning $retn.ExitCode
            return
        }
    }
    # instantiate CEP COM object
    $CEP = New-Object -ComObject CERTOCM.CertificateEnrollmentPolicyServerSetup
    $CEP.InitializeInstallDefaults()
    if (!$Thumbprint) {$Thumbprint = $(Get-Cert)}
    # set required properties. Here are only two available properties: Authentication and
    # thumbprint.
    $CEP.SetProperty(0x0, $auth.$Authentication)
    $CEP.SetProperty(0x1, $Thumbprint)
    Write-Host "Performing Certificate Enrollment Service installation with the following settings:" `
    `nAuthentication type: $Authentication
 `
    `nCEP server URL: $($CEP.GetProperty(0x2))
 -ForegroundColor Cyan
    if ($Thumbprint) {Write-Host "SSL certificate thumbprint: $Thumbprint" -ForegroundColor Cyan}
    Write-Host ("-" * 50) `
    `nInstallation
 results `
    `n
("-" * 50) -ForegroundColor Green
    # install CEP instance
    $CEP.Install()
    if ($?) {Write-Host "CEP service was successfully installed!" -ForegroundColor Green}
}

function Remove-CEP {
<#
.Synopsis
    Removes Certificate Enrollment Policy service instance from local computer.
.Description
    Removes Certificate Enrollment Policy service instance from local computer.
.Parameter Force
    Removes all CEP instances from local computer and removes role installation packages.
.EXAMPLE
    Remove-CEP
    
    Will remove all CEP instances but leaves installation packages.
.EXAMPLE
    Remove-CEP -Force
    
    Will remove all CEP instances and removes installation packages.
#>
[CmdletBinding()]
    param (
        [switch]$Force
    )

#region Check operating system
    $OS = (Get-WmiObject Win32_OperatingSystem).Caption
    if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
        Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
    }
#endregion

#region User permissions
# check if user has Enterprise Admins permissions
    $elevated = $false
    foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
        if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
            $elevated = $true
        }
    }
    if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion

    $CEP = New-Object -ComObject CERTOCM.CertificateEnrollmentPolicyServerSetup
    Write-Host "Performing Certificate Enrollment Service removal with the fillowing settings:" -ForegroundColor Cyan
    if ($Force) {Write-Host "Remove installation packages: Yes" -ForegroundColor Cyan}
    else {write-Host "Remove installation packages: No" -ForegroundColor Cyan}
    Write-Host ("-" * 50) `
    `nRemoval
 results `
    `n
("-" * 50) -ForegroundColor Green
    $CEP.Uninstall()
    if ($?) {Write-Host "CEP service successfully removed!" -ForegroundColor Green}
    if ($Force) {
        Import-Module ServerManager
        $retn = Remove-WindowsFeature -Name ADCS-Enroll-Web-Pol
        if (!$retn.Success) {
            Write-Warning "CEP installation package removal failed due of the following error:"
            Write-Warning $retn.ExitCode
        }
        else {Write-Host "CEP installation packages are successfully removed!" -ForegroundColor Green}
    }
}

Dot-source this script and run the following command to install CEP instance:

Add-CEP –Authentication <UsrPwd> –Thumbprint <EB74DA32E86>

you don't need to specify '–Authentication' parameter for Kerberos authentication. This is because Kerberos is used by default in my script. Only 3 authentication methods are supported by CEP: Kerberos, UsrPwd (User name and Password) and Certificate. '-Thumbprint' is not mandatory parameter. However you may have to set CEP for non-domain or external users. In that case it is common when you will use Internet name for your CEP server. Therefore you will have to assign certificate that matches your server Internet name. By specifying your own thumbprint, this certificate will be assigned for CEP. By default this script will find or enroll new one that will matches your server domain name (FQDN). Therefore you don't need to specify '-Thumbprint' parameter for internal use (within your AD forest).

In order to remove CEP instance from your server run the following command:

Remove-CEP –Force

You can run the command without any parameter. '-Force' switch will remove installation packages too. The different is that when you run 'Remove-CEP', server manager will show that CEP role is installed, but not configured. When you run 'Remove-CEP –Force', the script will also remove CEP role from server manager.

As usually you may check internal script help by typing:

  • Get-Help Add-CEP –full
  • Get-Help Remove-CEP –full

For script download click here:

feel free to ask me if you have comments or questions.


Share this article:

Comments:


Post your comment:

Please, solve this little equation and enter result below. Captcha