NTS.Tools.MSADCS.psm1
function Set-CAConfig { <# .Description This function kann be used to set some settings on the certification authority by using certutil. .Parameter CAType Type of CA .Parameter Domain_DistinguishedName Distinguished name of domain .Parameter WebServer_URL FQDN of web server that will host the crl .Parameter ValidityPeriodUnits units of validity period for certificate .Parameter ValidityPeriod type of validity period for certificate .Parameter CRLPeriod type of validity period for crl .Parameter CRLPeriodUnits units of validity period for crl .Parameter CRLDeltaPeriod type of validity period for delta crl .Parameter CRLDeltaPeriodUnits units of validity period for delta crl .Example # configures the local ca with specified values Set-CAConfig -CAType "RootCA" ` -Domain_DistinguishedName $Domain_DistinguishedName ` -WebServer_URL $WebServer_URL ` -ValidityPeriodUnits $RootCA_RenewalValidityPeriodUnits ` -ValidityPeriod $RootCA_RenewalValidityPeriod ` -CRLPeriod $RootCA_CRLPeriod ` -CRLPeriodUnits $RootCA_CRLPeriodUnits ` -CRLDeltaPeriod $RootCA_CRLDeltaPeriod ` -CRLDeltaPeriodUnits $RootCA_CRLDeltaPeriodUnits .NOTES this function is just a wrapper for cerutil #> [CmdletBinding()] 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 { <# .Description Creates a CAPolicy.inf file at $($env:SystemDrive)\Windows\ with specified values .Parameter Renewalkeylength length of key for renewal .Parameter RenewalValidityPeriodUnits unit of key for renewal .Parameter RenewalValidityPeriod type of key for renewal .Parameter CRLPeriod type of validity period for crl .Parameter CRLPeriodUnits units of validity period for crl .Parameter CRLDeltaPeriod type of validity period for delta crl .Parameter CRLDeltaPeriodUnits units of validity period for delta crl .Parameter DiscreteSignatureAlgorithm DiscreteSignatureAlgorithm .Example # creates a capolicy.inf for a root ca Set-RootCAPolicyInfFile -Renewalkeylength $using:RootCA_Renewalkeylength ` -RenewalValidityPeriodUnits $using:RootCA_RenewalValidityPeriodUnits ` -RenewalValidityPeriod $using:RootCA_RenewalValidityPeriod ` -CRLPeriod $using:RootCA_CRLPeriod ` -CRLPeriodUnits $using:RootCA_CRLPeriodUnits ` -CRLDeltaPeriod $using:RootCA_CRLDeltaPeriod ` -CRLDeltaPeriodUnits $using:RootCA_CRLDeltaPeriodUnits ` -DiscreteSignatureAlgorithm $using:RootCA_DiscreteSignatureAlgorithm .NOTES this used some predefined values #> 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" ) 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)" } } function New-CACRL { <# .Description runs certutil -CRL .Example # creates a new crl New-CACRL .NOTES #> #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 { <# .Description Creates a CAPolicy.inf file at $($env:SystemDrive)\Windows\ with specified values .Parameter Renewalkeylength length of key for renewal .Parameter RenewalValidityPeriodUnits unit of key for renewal .Parameter RenewalValidityPeriod type of key for renewal .Example # Creates a volume with the letter W Set-SubCAPolicyInfFile -Renewalkeylength $using:SubCA_Renewalkeylength ` -RenewalValidityPeriodUnits $using:SubCA_RenewalValidityPeriodUnits ` -RenewalValidityPeriod $using:SubCA_RenewalValidityPeriod .NOTES this used some predefined values #> param ( [Parameter(Mandatory = $false)] [string] $Renewalkeylength = "4096", [Parameter(Mandatory = $false)] [string] $RenewalValidityPeriodUnits = "10", [Parameter(Mandatory = $false)] [string] $RenewalValidityPeriod = "years" ) 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)" } } function Install-CACert { <# .Description installs the certificate of a sub ca to activate it .Parameter CerFilePath path to certificate file to install for ca .Example # this will install the certificate of the local ca Install-CACert -CerFilePath $SubCA_CerFilePath .NOTES should only be run on an enterprise subca #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $CerFilePath ) $ServiceName = "CertSvc" try { Write-Output "$($env:COMPUTERNAME): installing ca cert to activate ca" Start-Process -FilePath GPUpdate -ArgumentList "/force" -Wait -WindowStyle Hidden $AcceptResult = certutil -installCert $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 } catch { throw $PSItem.Exception.Message } } function Publish-CACRLToAD { <# .Description runs certutil -dspublish -f $CRLPath .Parameter CRLPath path to crl file .Example # published the certificate revocation list to ad Publish-CACRLToAD -CRLPath $BaseCRLPath .NOTES #> [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 { <# .Description Creates a script and a scheduled task to automate crl creation .Parameter SMBSharePath smb share path .Parameter CACommonName CA Name .Parameter CAServerName CA Server Name .Parameter ScriptName Name of the script .Parameter ScriptFolder path to the script, it will be created there .Example # creates the script and scheduled task Enable-ScheduledTaskForCRLCreation -SMBSharePath "\\$($using:WEB_Obj.Name).$($env:USERDNSDOMAIN)\CertEnroll" ` -CACommonName $using:SubCA_Initial_CACommonName ` -CAServerName $using:SubCA_Obj.Name .NOTES Scheduled Task Properties $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)" #> [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" ) 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 } function Complete-CertRequest { <# .Description this function can be used to sign a certificate request using the local ca .Parameter CertReqFilePath path to the certificate request .Parameter CAName name of the local ca .Example # completes the request Complete-CertRequest -CertReqFilePath $CertReqFilePath -CAName $CAName .NOTES #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $CertReqFilePath, [Parameter(Mandatory = $true)] [string] $CAName ) Write-Output "$($env:COMPUTERNAME): trying to sign the subca cert req" if (Test-Path -Path $CertReqFilePath) { $SubCA_CerFilePath = $CertReqFilePath.Replace(".req", ".cer") # load req into cert authority try { Write-Output "$($env:COMPUTERNAME): loading subca request into ca" $ImportResult = certreq -submit -q -config - "$($CertReqFilePath)" "$($SubCA_CerFilePath)" if ($ImportResult -like "*ERROR_FILE_EXISTS*" ) { Remove-Item -Path "$($CertReqFilePath.Replace(".req",".rsp"))" -Force } $ReqID = ($ImportResult -like "*RequestId: *")[0].Replace("RequestId: ", "") } catch { throw "error importing ca req file - $($PSItem.Exception.Message)" } # sign req Write-Output "$($env:COMPUTERNAME): submitting subca request" $SubmitResult = certutil -config $CAName -resubmit $ReqID if ($SubmitResult[-1] -notlike "*command completed successfully*") { throw "$($env:COMPUTERNAME): submit was not successful:`n$($SubmitResult)" } # export cer to file Write-Output "$($env:COMPUTERNAME): exporting signed subca cert" $ExportResult = certutil -config $CAName -view -restrict requestid=$ReqID -out rawcertificate if ($ExportResult[-1] -like "*command completed successfully*") { $FirstFilterString = "-----BEGIN CERTIFICATE-----" $SecondFilterString = "-----END CERTIFICATE-----" $RegexPattern = "$($FirstFilterString)(.*?)$($SecondFilterString)" #Perform the opperation $CertFileValue = $firstString + "`n" + ([regex]::Match($ExportResult, $RegexPattern).Groups[1].Value) + "`n" + $secondString New-Item -Path $SubCA_CerFilePath -ItemType File -Force | Out-Null Set-Content -Path $SubCA_CerFilePath -Value $CertFileValue | Out-Null } else { throw "$($env:COMPUTERNAME): file could not be created:`n$($ExportResult)" } } else { throw "$($env:COMPUTERNAME): cert req file could not be found at $($CertReqFilePath)" } } |