Functions/CertificateManagement/Install-FpsCertificate.ps1

<#
.SYNOPSIS
    Imports a PFX certificate into the Windows Certificate Store and grant the supplied Service Accounts read access to the imported certificate.
.DESCRIPTION
    Default this cmdlet adds the configured Service Account(s) on the Business Central Server Instance(s) as user with read access on the imported certificate.
.EXAMPLE
    Install-FpsCertificate -CertFilePath 'c:\temp\mycert.pfx' -CertPassword ('myPassword' | ConvertTo-SecureString -AsPlainText -Force)
.EXAMPLE
    $CertFilePath = 'c:\temp\mycert.pfx'
    $CertPassword = 'myPassword' | ConvertTo-SecureString -AsPlainText -Force
    Install-FpsCertificate -CertFilePath $CertFilePath -CertPassword $CertPassword -ServiceAccounts 'Domain\UserName'
#>

function Install-FpsCertificate{
    [CmdletBinding()] 
    param(
        # The file path to the certificate (pfx) file to install.
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)]
        [string] $CertFilePath,

        # The password required to install the certificate.
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] 
        [SecureString] $CertPassword,

        # The users that are granted read access on the certificate after the certificate is installed in the windows certificate store.
        # Default all the unique service accounts configured on Business Central ServerInstances are used.
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [string[]] $ServiceAccounts = ((Get-BCServerInstance).ServiceAccount | Select-Object -Unique),

        # The certificate provider path where to scan for certificates. Path should start with 'Cert:'. E.g. 'cert:\LocalMachine\WebHosting'.
        # Default value is: 'cert:\LocalMachine\My'
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [string] $CertStorePath = 'cert:\LocalMachine\My'
    )

    'Importing certificate ''{0}'' into Certificate Store ''{1}''...' -f ($CertFilePath | Split-Path -Leaf), $CertStorePath | Write-Host

    $cert = Import-PfxCertificate -FilePath $CertFilePath -Password $CertPassword -CertStoreLocation $CertStorePath
    
    if([string]::IsNullOrEmpty($cert)){
        Write-Error 'Something went wrong while importing the certificate.'
        return 
    } else {
        ' Certificated is imported.' | Write-Host
    }

    $rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
    $fileName = $rsaCert.key.UniqueName

    #Path to certificate
    $path_certificate = Join-Path (Join-Path $env:ALLUSERSPROFILE 'Microsoft\Crypto\RSA\MachineKeys') $fileName

    #Define Acces-Control-List (Acl)
    $new_access_control_list = Get-Acl -Path $path_certificate
    $service_accounts = $ServiceAccounts
    $file_system_rights = 'Read' #'FullControl'
    $type = 'Allow'

    #If several accounts need to be provisioned create a new rule for each account
    if(-not [string]::IsNullOrEmpty($service_accounts)){
        'The following user are granted {0} permission on the certificate: {1}' -f $file_system_rights, ($service_accounts -join ', ') | Write-Host
        'Imported Certificate file location: {0}' -f $path_certificate
    } 

    foreach ($service_account in $service_accounts){
        #create new rule
        $file_argument_list = $service_account, $file_system_rights, $type
        $file_system_acces_rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $file_argument_list

        #apply new rule
        $new_access_control_list.SetAccessRule($file_system_acces_rule)
    }

    #set access control list to file
    Set-Acl -Path $path_certificate -AclObject $new_access_control_list

    return $cert
}

Export-ModuleMember -Function Install-FpsCertificate