I have a PowerShell script that installs pfx certificate into the LocalMachine certificate store. The function looks like this:
function Add-Certificate {
param
(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxPath,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxPassword
)
Write-Host "Installing certificate" -ForegroundColor Yellow
try
{
$pfxcert = new-object system.security.cryptography.x509certificates.x509certificate2
$pfxcert.Import($pfxPath, $pfxPassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", LocalMachine
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite");
$store.Add($pfxcert);
$store.Close();
return $pfxcert
}
catch
{
throw
}
}
When I open the Certificate Manager to verify the installation I can see that it has installed correctly.
The next step in my process is to assign permissions to the certificate to a service account.
function Set-CertificatePermission
{
param
(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxThumbPrint,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$serviceAccount
)
$cert = Get-ChildItem -Path cert:\LocalMachine\My | Where-Object -FilterScript { $PSItem.ThumbPrint -eq $pfxThumbPrint; };
# Specify the user, the permissions and the permission type
$permission = "$($serviceAccount)","Read,FullControl","Allow"
$accessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission;
# Location of the machine related keys
$keyPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\";
$keyName = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName;
$keyFullPath = $keyPath + $keyName;
try
{
# Get the current acl of the private key
# This is the line that fails!
$acl = Get-Acl -Path $keyFullPath;
# Add the new ace to the acl of the private key
$acl.AddAccessRule($accessRule);
# Write back the new acl
Set-Acl -Path $keyFullPath -AclObject $acl;
}
catch
{
throw $_;
}
}
This function fails. Specifically, this function fails when trying to evaluate the Get-Acl command, with the following error: Get-Acl : Cannot find path 'C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\59f1e969a4f7e5de90224f68bc9be536_1d508f5e-0cbc-4eca-a402-3e55947faa3b'
As it turns out the key file has been installed into my roaming profile C:\Users\MyUserName\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1259098847-1967870486-1845911597-155499
I'm sure there is something wrong with the Add-Certificate function, but I cannot figure out what it is. How do I force it to install the key file in the C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys directory?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With