NTS.Tools.MSADCS.psm1

function Set-CAConfig {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateSet("RootCA", "SubCA")]
        [string]
        $CAType,

        [Parameter(Mandatory = $true)]
        [string]
        $Domain_DistinguishedName,

        [Parameter(Mandatory = $true)]
        [string]
        $WebServer_URL,

        [Parameter(Mandatory = $false)]
        [string]
        $ValidityPeriodUnits,

        [Parameter(Mandatory = $false)]
        [string]
        $ValidityPeriod,

        [Parameter(Mandatory = $false)]
        [string]
        $CRLPeriod,

        [Parameter(Mandatory = $false)]
        [string]
        $CRLPeriodUnits,

        [Parameter(Mandatory = $false)]
        [string]
        $CRLDeltaPeriod,

        [Parameter(Mandatory = $false)]
        [string]
        $CRLDeltaPeriodUnits
    )

    if ($CAType -eq "RootCA") {
        if ($ValidityPeriodUnits -eq "" -or $null -eq $ValidityPeriodUnits) {
            $ValidityPeriodUnits = "10"
        }
        if ($ValidityPeriod -eq "" -or $null -eq $ValidityPeriod) {
            $ValidityPeriod = "years"
        }
        if ($CRLPeriod -eq "" -or $null -eq $CRLPeriod) {
            $CRLPeriod = "weeks"
        }
        if ($CRLPeriodUnits -eq "" -or $null -eq $CRLPeriodUnits) {
            $CRLPeriodUnits = "26"
        }
        if ($CRLDeltaPeriod -eq "" -or $null -eq $CRLDeltaPeriod) {
            $CRLDeltaPeriod = "hours"
        }
        if ($CRLDeltaPeriodUnits -eq "" -or $null -eq $CRLDeltaPeriodUnits) {
            $CRLDeltaPeriodUnits = "0"
        }
    }
    elseif ($CAType -eq "SubCA") {
        if ($ValidityPeriodUnits -eq "" -or $null -eq $ValidityPeriodUnits) {
            $ValidityPeriodUnits = "5"
        }
        if ($ValidityPeriod -eq "" -or $null -eq $ValidityPeriod) {
            $ValidityPeriod = "years"
        }
        if ($CRLPeriod -eq "" -or $null -eq $CRLPeriod) {
            $CRLPeriod = "days"
        }
        if ($CRLPeriodUnits -eq "" -or $null -eq $CRLPeriodUnits) {
            $CRLPeriodUnits = "3"
        }
        if ($CRLDeltaPeriod -eq "" -or $null -eq $CRLDeltaPeriod) {
            $CRLDeltaPeriod = "days"
        }
        if ($CRLDeltaPeriodUnits -eq "" -or $null -eq $CRLDeltaPeriodUnits) {
            $CRLDeltaPeriodUnits = "0"
        }
    }
    
    try {
        Write-Output "$($env:COMPUTERNAME): configuring ca setting"
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\DSConfigDN `"CN=Configuration,$($Domain_DistinguishedName)`"" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\ValidityPeriodUnits $($ValidityPeriodUnits)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\ValidityPeriod $($ValidityPeriod)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CRLPeriodUnits $($CRLPeriod)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CRLPeriod $($CRLPeriodUnits)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CRLDeltaPeriodUnits $($CRLDeltaPeriodUnits)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CRLDeltaPeriod $($CRLDeltaPeriod)" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CRLPublicationURLs `"1:$($env:windir)\system32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://$($WebServer_URL)/CertEnroll/%3%8%9.crl\n10:LDAP:///CN=%3%8,CN=%3,CN=CDP,CN=Public Key Services,CN=Services,%6%10`"" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\CACertPublicationURLs `"1:$($env:windir)\system32\CertSrv\CertEnroll\%3.crt\n2:http://$($WebServer_URL)/CertEnroll/%3%4.crt\n2:LDAP:///CN=%3,CN=AIA,CN=Public Key Services,CN=Services,%6%11`"" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\AuditFilter 127" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg CA\forceteletex +0x20" -NoNewWindow -Wait
        Start-Process -FilePath certutil -ArgumentList "-setreg policy\EditFlags -EDITF_ADDOLDKEYUSAGE" -NoNewWindow -Wait
        Restart-Service -Name certsvc | Out-Null
        Start-Sleep -Seconds 5
    }
    catch {
        throw "error configuring ca settings - $($PSItem.Exception.Message)"
    }
}

function Set-RootCAPolicyInfFile {
    param (
        [Parameter(Mandatory = $false)]
        [string]
        $Renewalkeylength = "4096",

        [Parameter(Mandatory = $false)]
        [string]
        $RenewalValidityPeriodUnits = "10",

        [Parameter(Mandatory = $false)]
        [string]
        $RenewalValidityPeriod = "years",

        [Parameter(Mandatory = $false)]
        [string]
        $CRLPeriod = "weeks",

        [Parameter(Mandatory = $false)]
        [string]
        $CRLPeriodUnits = "26",

        [Parameter(Mandatory = $false)]
        [string]
        $CRLDeltaPeriod = "hours",

        [Parameter(Mandatory = $false)]
        [string]
        $CRLDeltaPeriodUnits = "0",

        [Parameter(Mandatory = $false)]
        [string]
        $DiscreteSignatureAlgorithm = "1"
    )
    
    #region capolicy.inf
    try {
        $CAPolicy_Path = "$($env:SystemDrive)\Windows\CAPolicy.inf"
        $CAPolicy_Value = "[Version]
        Signature= `"`$Windows NT$`"
 
        [certsrv_server]
        renewalkeylength = $($renewalkeylength)
        RenewalValidityPeriodUnits = $($RenewalValidityPeriodUnits)
        RenewalValidityPeriod = $($RenewalValidityPeriod)
        CRLPeriod = $($CRLPeriod)
        CRLPeriodUnits = $($CRLPeriodUnits)
        CRLDeltaPeriod = $($CRLDeltaPeriod)
        CRLDeltaPeriodUnits = $($CRLDeltaPeriodUnits)
        DiscreteSignatureAlgorithm = $($DiscreteSignatureAlgorithm)
 
        [CRLDistributionPoint]
        Empty = true
 
        [AuthorityInformationAccess]
        Empty = true
 
        [Extensions]
        2.5.29.15 = AwIBBg==
        Critical = 2.5.29.15
        "


        Write-Output "$($env:COMPUTERNAME): creating $($CAPolicy_Path)"
        if ((Test-Path -Path $CAPolicy_Path) -eq $false) {
            New-Item -Path $CAPolicy_Path -ItemType File -Force | Out-Null
        }
        
        Set-Content -Path $CAPolicy_Path -Value $CAPolicy_Value
    }
    catch {
        throw "error creating $($CAPolicy_Path) - $($psitem.Exception.Message)"
    }
    #endregion
}

function New-CACRL {
    #region crl
    try {
        Write-Output "$($env:COMPUTERNAME): creating crl"
        $CertutilMessage = certutil -CRL
        if ($CertutilMessage -notmatch "-CRL command completed successfully") {
            throw $CertutilMessage
        }
        
    }
    catch {
        throw "error creating crl - $($PSItem.Exception.Message)"
    }
    #endregion
}

function Set-SubCAPolicyInfFile {
    param (
        [Parameter(Mandatory = $false)]
        [string]
        $Renewalkeylength = "4096",

        [Parameter(Mandatory = $false)]
        [string]
        $RenewalValidityPeriodUnits = "10",

        [Parameter(Mandatory = $false)]
        [string]
        $RenewalValidityPeriod = "years"
    )
    
    #region capolicy.inf
    try {
        $CAPolicy_Path = "$($env:SystemDrive)\Windows\CAPolicy.inf"
        $CAPolicy_Value = "[Version]
        Signature = `"`$Windows NT`$`"
 
        [Extensions]
        2.5.29.15 = AwIBBg==
        Critical = 2.5.29.15
 
        [certsrv_server]
        RenewalKeyLength = $($Renewalkeylength)
        RenewalValidityPeriodUnits = $($RenewalValidityPeriodUnits)
        RenewalValidityPeriod = $($RenewalValidityPeriod)
        LoadDefaultTemplates=0
 
        [PolicyStatementExtension]
        Policies = AllIssuancePolicy
 
        [AllIssuancePolicy]
        OID = 2.5.29.32.0
        "


        Write-Output "$($env:COMPUTERNAME): creating $($CAPolicy_Path)"        
        if ((Test-Path -Path $CAPolicy_Path) -eq $false) {
            New-Item -Path $CAPolicy_Path -ItemType File -Force | Out-Null
        }
        
        Set-Content -Path $CAPolicy_Path -Value $CAPolicy_Value
    }
    catch {
        throw "error creating $($CAPolicy_Path) - $($PSItem.Exception.Message)"
    }
    #endregion
}

function Install-CACert {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $SubCA_CerFilePath
    )
    $ServiceName = "CertSvc"
    
    #region install ca with cer
    Write-Output "$($env:COMPUTERNAME): installing ca cert to activate ca"
    Start-Process -FilePath GPUpdate -ArgumentList "/force" -Wait -WindowStyle Hidden
    $AcceptResult = certutil -installCert $SubCA_CerFilePath
    if ($null -eq $AcceptResult -or $AcceptResult[0] -notlike "*CertUtil: -installCert command completed successfully*") {
        throw "subca could not be installed:`n$($AcceptResult)"
    }
    Start-Service -Name $ServiceName | Out-Null
    Restart-Service -Name $ServiceName | Out-Null
    #endregion
}

function Publish-CACRLToAD {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $CRLPath
    )
    try {
        if (Test-Path -Path $CRLPath) {
            $CertutilMessage = certutil -dspublish -f $CRLPath
            if (!(($CertutilMessage -like "*-dspublish command completed successfully*")[0] -like "*-dspublish command completed successfully*")) {
                throw $CertutilMessage
            }
        }
        else {
            throw "cannot find $($CRLPath)"
        }
    }
    catch {
        throw "error publishing crl - $($PSItem.Exception.Message)"
    }
}

function Enable-ScheduledTaskForCRLCreation {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $SMBSharePath, 

        [Parameter(Mandatory = $true)]
        [string]
        $CACommonName, 

        [Parameter(Mandatory = $true)]
        [string]
        $CAServerName,
        
        [Parameter(Mandatory = $false)]
        [string]
        $ScriptName = "Publish-DailyCRL",

        [Parameter(Mandatory = $false)]
        [string]
        $ScriptFolder = "$($env:ProgramData)\NTS\CertSrv"
    )

    #region scheduled task for crl
    try {
        $Script_FilePath = "$($ScriptFolder)\$($ScriptName).ps1"                
        $ScriptContent = "Start-Process -FilePath certutil -ArgumentList `"-CRL`" -Wait -WindowStyle Hidden
        Copy-Item -Path `"$($env:windir)\system32\certsrv\certenroll\*`" -Destination `"$($SMBSharePath)`" -Force
        `$Path = `"$($SMBSharePath)\$($CAServerName).$($env:USERDNSDOMAIN)_$($CACommonName).crt`"
        if(Test-Path -Path `$Path) {
            if(Test-Path -Path `"$($SMBSharePath)\$($CACommonName).crt`") {
                Remove-Item -Path `"$($SMBSharePath)\$($CACommonName).crt`" -Force
            }
            Rename-Item -Path `$Path -NewName `"$($CACommonName).crt`"
        }
        "

        
        Write-Output "$($env:COMPUTERNAME): creating scheduled task to publish crl on a daily basis"
                                        
        try {
            if ((Test-Path -Path $ScriptFolder) -eq $false) {
                New-Item -Path $ScriptFolder -ItemType Directory -Force | Out-Null
            }
                            
            New-Item -Path $Script_FilePath -ItemType File -Force | Out-Null
            Set-Content -Path $Script_FilePath -Value $ScriptContent -Force
        }
        catch {
            throw "$($env:COMPUTERNAME): error creating files: $($PSItem.Exception.Message)"
        }

        try {
            $Trigger = New-JobTrigger -Daily -At "4:00 AM" -DaysInterval 1
            $User = "NT AUTHORITY\SYSTEM"
            $Action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $($Script_FilePath)"
            Register-ScheduledTask -TaskName $ScriptName -Trigger $Trigger -User $User -Action $Action -RunLevel Highest -Force | Out-Null
        }
        catch {
            throw "$($env:COMPUTERNAME): error creating task: $($PSItem.Exception.Message)"
        }
        Write-Output "$($env:COMPUTERNAME): starting task"
        Start-ScheduledTask -TaskName $ScriptName
    }
    catch {
        throw "error creating task - $($PSItem.Exception.Message)"
    }
    #endregion
}