public/Invoke-CADatabaseMaintenance.ps1
function Invoke-CADatabaseMaintenance { <# .SYNOPSIS Start AD CS database cleanup. .DESCRIPTION Return nothing. .PARAMETER CertificateRemovalDate Date to remove expired, denied, failed and revoked certificates/requests from. .PARAMETER BackupFolderPath Path to the backup folder. .PARAMETER Confirm Confirm the action. .EXAMPLE Invoke-CADatabaseMaintenance -CertificateRemovalDate (Get-Date).AddMonths(-3) -BackupFolderPath 'C:\ADCSBackup' -Confirm; #> [cmdletbinding()] [OutputType([void])] param ( # Date to remove expired and revoked certificates from. [Parameter(Mandatory = $false)] [ValidateScript({ $_ -le (Get-Date) })] [DateTime]$CertificateRemovalDate = (Get-Date).AddMonths(-3), # Path to the backup folder. [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$BackupFolderPath = $script:ModuleBackupFolder, # Include private key in the backup. [Parameter(Mandatory = $false)] [bool]$PrivateKey = $true, # Password for the backup. [Parameter(Mandatory = $false)] [string]$Password, # Confirm the action. [Parameter(Mandatory = $false)] [switch]$Confirm = $true ) BEGIN { # Write to log. $customProgress = Write-CustomProgress -Activity $MyInvocation.MyCommand.Name -CurrentOperation 'Certificate authority database cleanup'; # Ask user to confirm. if ($true -eq $Confirm) { # Get user input. $userInput = Get-UserInput -Question 'Do you want to continue with expired/revoked certificate removal, AD CS service restart, temporary extend CRL? (Answer: "Yes" or "No")' -Options 'Yes', 'No'; # If the user input is not 'Yes'. if ($userInput -ne 'Yes') { # Write to log. Write-CustomLog -Message 'User did not confirm the action' -Level Verbose; # Exit script. exit 1; } } # Create the backup folder. $null = New-Item -Path $BackupFolderPath -ItemType Directory -Force -ErrorAction Stop; # File path for original CRL configuration. $originalCrlConfigFilePath = ('{0}\crlconfig.xml' -f $BackupFolderPath); # Splatting for the backup. $backupSplat = @{ Path = ('{0}\Database' -f $BackupFolderPath); }; # If the password is set. if (-not [string]::IsNullOrEmpty($Password)) { # Convert the password to a secure string. $securePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force; # Add password to the splat. $null = $backupSplat.Add('Password', $securePassword); } } PROCESS { # Backup the database (with private key if applicable). $null = Backup-CA @backupSplat -PrivateKey:$PrivateKey; # Get current CRL configuraiton. $originalCrlConfig = Get-CACrlConfig; # If the CRL config file path dont exist. if (-not (Test-Path -Path $originalCrlConfigFilePath -PathType Leaf)) { # Write to log. Write-CustomLog -Message ('Original (backup) CRL configuration file does not exist. Creating file at path {0}' -f $originalCrlConfigFilePath) -Level Verbose; # Save the original CRL configuration to a file. $null = $originalCrlConfig | Export-Clixml -Path $originalCrlConfigFilePath -Force; } # Get the AD CS service status. $serviceStatus = Get-CAService; # If the service is running. if ($serviceStatus -eq 'Running') { # Temporary extend the CRL. Set-CACrlConfig ` -OverlapUnits 0 ` -PeriodUnits 2 ` -Period Weeks ` -DeltaOverlapUnits 0 ` -DeltaPeriodUnits 0; # Publish the CRL. $null = Publish-CACrl; } # Splatting for Remove-CACertificate. $removeCertificateSplat = @{ Confirm = $false; }; # If date is set. if ($true -eq $PSBoundParameters.ContainsKey('CertificateRemovalDate')) { # Add to the splat. $removeCertificateSplat.Add('Date', $CertificateRemovalDate); } # Remove expired, denied, failed and revoked certificates/requests. $null = Remove-CACertificate -State Failed @removeCertificateSplat; $null = Remove-CACertificate -State Denied @removeCertificateSplat; $null = Remove-CACertificate -State Expired @removeCertificateSplat; $null = Remove-CACertificate -State Revoked @removeCertificateSplat; # Stop the service. $null = Stop-CAService; # Wait until the service is stopped. $null = Wait-CAService -State Stopped; # Defrag the database. $null = Invoke-CADatabaseDefragmentation; # If the service was running. if ($serviceStatus -eq 'Running') { # Start the service. Start-CAService; # Wait until the service is running. $null = Wait-CAService -State Running; # Restore original CRL configuration. Set-CACrlConfig ` -OverlapUnits $originalCrlConfig.OverlapUnits ` -Period $originalCrlConfig.Period ` -PeriodUnits $originalCrlConfig.PeriodUnits ` -DeltaOverlapUnits $originalCrlConfig.DeltaOverlapUnits ` -DeltaPeriodUnits $originalCrlConfig.DeltaPeriodUnits; # Publish the CRL. $null = Publish-CACrl; } } END { # Write to log. Write-CustomProgress @customProgress; } } |