ldx-pki.psm1

function Get-AllIssuedCertificates {
    <#
    .SYNOPSIS
        Retrieves all certificates issued by a specific Certificate Authority.
     
    .DESCRIPTION
        This function retrieves all certificates that have been issued by the specified Certificate Authority.
        It can optionally filter the results to only include currently valid certificates.
     
    .PARAMETER CA
        The Certificate Authority object from which to retrieve issued certificates.
        This parameter is mandatory and can be passed via the pipeline.
     
    .PARAMETER OnlyValid
        If specified, only certificates that are currently valid (not expired) will be returned.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        Get-AllIssuedCertificates -CA $ca
         
        Returns all certificates issued by the specified CA.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        Get-AllIssuedCertificates -CA $ca -OnlyValid
         
        Returns only currently valid certificates issued by the specified CA.
     
    .OUTPUTS
        Array of certificate objects representing issued certificates.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [PKI.CertificateServices.CertificateAuthority]
        $CA,
        [Parameter(Mandatory = $false)]
        [switch]
        $OnlyValid
    )
    begin {}

    process {
        if ($OnlyValid) {
            return Get-IssuedRequest -CertificationAuthority $CA | Where-Object {$_.NotAfter -ge (Get-Date)}
        } else {
            return Get-IssuedRequest -CertificationAuthority $CA
        }
    }
    end {}
}

function Get-AllTemplates {
    <#
    .SYNOPSIS
        Retrieves all certificate templates from the Active Directory.
     
    .DESCRIPTION
        This function retrieves all certificate templates available in the Active Directory.
        It's a simple wrapper around the Get-CertificateTemplate cmdlet, basically just in order to get
        all commands needed gathered in this module.
     
    .EXAMPLE
        Get-AllTemplates
         
        Returns all certificate templates from the Active Directory.
     
    .OUTPUTS
        Array of certificate template objects.
    #>

    return Get-CertificateTemplate
}

function Get-TemplateReport {
    <#
    .SYNOPSIS
        Generates a report of certificate templates with formatted details.
     
    .DESCRIPTION
        This function returns a customized report of certificate templates with selected properties.
        It can return either all templates or only templates that are available on a specific CA.
     
    .PARAMETER CA
        The Certificate Authority to check for available templates.
        This parameter is optional and can be passed via the pipeline.
     
    .PARAMETER AllIssuedCertificates
        If specified and a CA is provided, returns only templates that are configured on the CA.
     
    .EXAMPLE
        Get-TemplateReport
         
        Returns a report of all certificate templates in the environment.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        Get-TemplateReport -CA $ca -AllIssuedCertificates
         
        Returns only the templates that are configured on the specified CA.
     
    .OUTPUTS
        Custom objects containing template details including Name, DisplayName, SchemaVersion, OID, OIDFriendlyName, ValidityPeriod, and RenewalPeriod.
    #>

    Param(
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [PKI.CertificateServices.CertificateAuthority]
        $CA,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [switch]
        $AllIssuedCertificates
    )
    begin {}

    process {
        if ($AllIssuedCertificates) {
            $Templates = (Get-CATemplate -CertificationAuthority $CA).Templates
        } else {
            $Templates = Get-AllTemplates
        }
        return $Templates | Select-Object Name, DisplayName, SchemaVersion, @{
            Name = "OID";
            Expression = {$_.OID.Value}
        }, @{
            Name = "OIDFriendlyName";
            Expression = {$_.OID.FriendlyName}
        }, ValidityPeriod, RenewalPeriod
    }
    end {}
}

function Get-CertificateReport {
    <#
    .SYNOPSIS
        Generates a formatted report from certificate objects.
     
    .DESCRIPTION
        This function takes certificate objects and returns a customized report with selected properties.
        It formats the output to focus on important certificate details.
     
    .PARAMETER Certificates
        The certificate objects to include in the report.
        This parameter is mandatory and can be passed via the pipeline.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-CertificateReport -Certificates $certs
         
        Returns a formatted report of all certificates issued by the specified CA.
     
    .OUTPUTS
        Custom objects containing certificate details including requester name, common name, validity period, and template information.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [object]
        $Certificates
    )

    begin {}

    process {
        return $Certificates | Select-Object Request.RequesterName, CommonName, NotBefore, NotAfter, @{
            Name = "CertificateTemplate";
            Expression = {$_.CertificateTemplate}
        }, @{
            Name = "OID";
            Expression = {$_.CertificateTemplateOID.Value}
        }
    }
    end {}
}
function Get-TemplateInUse {
    <#
    .SYNOPSIS
        Identifies certificate templates that are in use based on issued certificates.
     
    .DESCRIPTION
        This function analyzes a collection of certificates and identifies which templates are currently in use.
        It compares certificate template identifiers with the full list of available templates.
     
    .PARAMETER Certificates
        The certificate objects to analyze.
        This parameter is mandatory and can be passed via the pipeline.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-TemplateInUse -Certificates $certs
         
        Returns a list of certificate templates that are in use based on the certificates issued by the specified CA.
     
    .OUTPUTS
        Custom objects containing template details including DisplayName, Name, and OID for templates that are in use.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [object]
        $Certificates
    )
    begin {}

    process {
        $CertReport = Get-CertificateReport -Certificates $Certificates
        $TemplateReport = Get-TemplateReport
        return $templateReport | Where-Object {$_.Name -in $CertReport.oid -or $_.oid -in $CertReport.oid} | Select-Object DisplayName, Name, Oid
    }
    end {}
}

function Get-TemplateNotInUse {
    <#
    .SYNOPSIS
        Identifies certificate templates that are not in use based on issued certificates.
     
    .DESCRIPTION
        This function analyzes a collection of certificates and identifies which templates are not currently in use.
        It can be used to find unused templates either from the full template list or only from templates available on a specific CA.
     
    .PARAMETER Certificates
        The certificate objects to analyze.
        This parameter is mandatory and can be passed via the pipeline.
     
    .PARAMETER OnlyIssuedCertificates
        If specified, only templates that are configured on the specified CA will be considered.
     
    .PARAMETER CA
        The Certificate Authority to check for available templates when using the OnlyIssuedCertificates parameter.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-TemplateNotInUse -Certificates $certs
         
        Returns all templates that are not in use based on the certificates issued by the specified CA.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-TemplateNotInUse -Certificates $certs -OnlyIssuedCertificates -CA $ca
         
        Returns only templates that are configured on the CA but not in use.
     
    .OUTPUTS
        Custom objects containing template details including DisplayName, Name, and OID for templates that are not in use.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [object]
        $Certificates,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [switch]
        $OnlyIssuedCertificates,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [PKI.CertificateServices.CertificateAuthority]
        $CA
 
    )
    begin {}

    process {
        $CertReport = Get-CertificateReport -Certificates $Certificates
        if ($OnlyIssuedCertificates) {
            $TemplateReport = Get-TemplateReport -AllIssuedCertificates -CA $CA
        } else {
            $TemplateReport = Get-TemplateReport
        }
        return $TemplateReport | Where-Object {$_.oid -notin $CertReport.oid -and $_.name -notin $CertReport.oid} | Select-Object DisplayName, Name, Oid # -and för ca + machine
    }
    end {}
}

function Get-CertificateFromTemplate {
    <#
    .SYNOPSIS
        Counts certificates issued for each template that is in use.
     
    .DESCRIPTION
        This function analyzes a collection of certificates and counts how many certificates have been issued
        for each template that is currently in use. It returns a custom object with template details and counts.
     
    .PARAMETER Certificates
        The certificate objects to analyze.
        This parameter is mandatory and can be passed via the pipeline.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-CertificateFromTemplate -Certificates $certs
         
        Returns a count of certificates issued for each template that is in use.
     
    .OUTPUTS
        Collection of CertificateInfo objects containing TemplateName, OID, and IssuedCount.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [object]
        $Certificates
    )
    begin {}
    process {
        $UsedTemplates = Get-TemplateInUse -Certificates $Certificates
        $CertificateInfo = New-Object 'System.Collections.Generic.List[CertificateInfo]'
        foreach ($Template in $UsedTemplates) {
            $Oid = $Template.Oid
            $TemplateName = $Template.Name
            $count = ($Certificates | Where-Object {$_.certificateTemplate -eq $Oid -or $_.certificateTemplate -eq $TemplateName}).count
            $Cert = [CertificateInfo]::new(
                $TemplateName,
                $Oid,
                $count
            )
            $CertificateInfo.Add($cert)
        }
        return $CertificateInfo
    }
    end {}
}

function Get-CertificateFromAllTemplates {
    <#
    .SYNOPSIS
        Counts certificates issued for all templates, including those not in use.
     
    .DESCRIPTION
        This function analyzes a collection of certificates and counts how many certificates have been issued
        for each template, including templates with zero certificates. It shows a progress bar during execution.
        Normally you would only need to the Get-CertificateFromTemplate cmdlet but if you want to have a
        complete list, just to be really sure, use this cmdlet.
     
    .PARAMETER Certificates
        The certificate objects to analyze.
        This parameter is mandatory and can be passed via the pipeline.
     
    .EXAMPLE
        $ca = Get-CertificationAuthority -ComputerName "CA-SERVER" -Name "My-CA"
        $certs = Get-AllIssuedCertificates -CA $ca
        Get-CertificateFromAllTemplates -Certificates $certs
         
        Returns a count of certificates issued for all templates, including ones with zero certificates.
     
    .OUTPUTS
        Collection of CertificateInfo objects containing TemplateName, OID, and IssuedCount.
     
    .NOTES
        This function displays a progress bar during execution to indicate its progress.
    #>

    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [object]
        $Certificates
    )
    begin {}
    process {
        $CertificateInfo = New-Object 'System.Collections.Generic.List[CertificateInfo]'
        [int]$ProgressInitialValue = 5
        [int]$ProgressGoal = 100 - $ProgressInitialValue
        [int]$ProgressStep = 1
        Write-Progress -Activity "Processing" -Status "$ProgressInitialValue% complete" -PercentComplete $ProgressInitialValue
        $TemplateReport = Get-TemplateReport
        [int]$TemplateCount = $TemplateReport.count
        foreach ($Template in $TemplateReport) {
            [float]$ProgressValue = [math]::Round($ProgressInitialValue + $ProgressStep * $ProgressGoal / $TemplateCount , 2)
            Write-Progress -Activity "Processing" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue
            $ProgressStep++
            $Oid = $Template.OID
            $TemplateName = $Template.Name
            $count = ($Certificates | Where-Object {$_.certificateTemplate -eq $Oid -or $_.certificateTemplate -eq $TemplateName}).count
            $Cert = [CertificateInfo]::new(
                $TemplateName,
                $Oid,
                $count
            )
            $CertificateInfo.Add($cert)
        }
        return $CertificateInfo
    }
    end {}
}
Class CertificateInfo {
    <#
    .SYNOPSIS
        Class that stores certificate template usage information.
     
    .DESCRIPTION
        This class is used to store information about certificate templates and their usage,
        including the template name, OID, and the count of issued certificates.
     
    .PROPERTY TemplateName
        The name of the certificate template.
     
    .PROPERTY OID
        The Object Identifier of the certificate template.
     
    .PROPERTY IssuedCount
        The number of certificates issued using this template.
    #>

    [string]$TemplateName
    [string]$OID
    [int]$IssuedCount

    CertificateInfo (
        [string]$TemplateName,
        [string]$OID,
        [int]$IssuedCount
    )
    {
        $this.TemplateName = $TemplateName
        $this.OID = $OID
        $this.IssuedCount = $IssuedCount
    }
}