(2012-02-10) Managing Certificates On A Windows Computer With PowerShell
Posted by Jorge on 2012-02-10
To manage certificates on a computer, you can use the “Certificates” MMC. With that MMC you scope either the (local) computer or the current user or even both. For either scope you will find different certificate stores that contain the different certificates, with or without the private key.
Figure 1: Scoping The Certificates MMC And The Different Certificate Stores For Either Scope
–
Common management tasks are shown in the pictures below.
Figure 2a: Common Management Tasks For Certificates (For Existing Certificates In Stores)
–
Figure 2b: Common Management Tasks For Certificates (For New Certificates)
–
Now this is the way of doing it through the GUI. Can you do this through PowerShell to achieve automation? Yes, you can. I will provide you with examples for a few functions.
–
By default, when starting PowerShell a few default PowerShell Drivers are loaded and available. To view the current available PSDrives, use the CMDlet “Get-PSDrive”.
Figure 3: PS Drives Loaded And Available Right After Starting PowerShell
–
As you can see there is a PS Drive called “cert”. That’s the one you can use to manage existing certificates through PowerShell. When you issue the PoSH command “dir cert:\” you will see the two available scopes (or locations), including the available stores.
Figure 4: Scopes (Locations) And The Certificate Stores
–
When you issue the PoSH command “dir cert:\LocalMachine” or “dir cert:\CurrentUser”, you will see all the available stores for each scope more clear.
Figure 5: All The Certificate Stores For Each Scope (Location) (! May Be Different For Another Computer !)
–
When you issue the PoSH command “dir cert:\LocalMachine\<Cert Store>” or “dir cert:\CurrentUser\<Cert Store>”, you will see all the available certificates in that store.
Figure 6: All The Available Certificates In The Personal Store Of The Local Computer
–
Now with this knowledge it is possible to manage those certificates.
–
Exporting Certificates WITHOUT The Private Key
By using the following PoSH commands you can export the certificate to a CER file without the private key, if any.
# Find And Target The Cert Required Based Upon Some Condition $CertToExport = dir cert:\LocalMachine\My | where {$_.ThumbPrint -eq "EC9498B48CA4E48EB8D5BC557BCFBC09B5A02651"} # Export The Targeted Cert In Bytes For The CER format $CertToExportInBytesForCERFile = $CertToExport.export("Cert") # Write The Files Based Upon The Exported Bytes [system.IO.file]::WriteAllBytes("D:\Temp\CertToExportCERFile.CER", $CertToExportInBytesForCERFile)
–
Exporting Certificates WITH The Private Key
By using the following PoSH commands you can export the certificate to a PFX file with the private key and protect it with a password.
# Find And Target The Cert Required Based Upon Some Condition $CertToExport = dir cert:\LocalMachine\My | where {$_.ThumbPrint -eq "EC9498B48CA4E48EB8D5BC557BCFBC09B5A02651"} # Define Cert Type When Exporting To PFX $CertType = [System.Security.Cryptography.X509Certificates.X509ContentType]::pfx # Define The Password To Protect The Private Key # (ALSO see: https://jorgequestforknowledge.wordpress.com/2011/12/15/passwords-containing-special-characters-in-powershell/) $PrivateKeyPassword = 'Pa$$w0rd' # Export The Targeted Cert In Bytes For The PFX format While Specifying A Password # REMARK: It Must Be Allowed To Export The Private Key, Otherwise You Will See The Error "Key not valid for use in specified state" $CertToExportInBytesForPFXFile = $CertToExport.export($CertType, $PrivateKeyPassword) # Write The Files Based Upon The Exported Bytes [system.IO.file]::WriteAllBytes("D:\Temp\CertToExportPFXFile.PFX", $CertToExportInBytesForPFXFile)
–
Managing The Permissions On The Private Keys
By using the following PoSH commands you can manage the permissions on the private key of a certificate.
# Find And Target The Cert Required Based Upon Some Condition $CertToAdjustPermissions = dir cert:\LocalMachine\My | where {$_.ThumbPrint -eq "EC9498B48CA4E48EB8D5BC557BCFBC09B5A02651"} # Possible Values For File System Based Access Rights Are # * ListDirectory, ReadData, WriteData # * CreateFiles, CreateDirectories, AppendData # * ReadExtendedAttributes, WriteExtendedAttributes, Traverse # * ExecuteFile, DeleteSubdirectoriesAndFiles, ReadAttributes # * WriteAttributes, Write, Delete # * ReadPermissions, Read, ReadAndExecute # * Modify, ChangePermissions, TakeOwnership # * Synchronize, FullControl # Specify The User, The Permissions And The Permission Type $ACE = "ADCORP\ADM.ROOT","Read,Synchronize","Allow" # Define A New File System Based Access Rule Based Upon The Previus ACE $AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $ACE # The Location Of The Machine Related Keys Can Be Found In The Following Location $MachineKeysLocation = $env:ALLUSERSPROFILE + "\Microsoft\Crypto\RSA\MachineKeys\" # Configuring ACE On Private Key Of Targeted Cert To Allow User Account To READ It (EXAMPLE!) $KeyFileCertToAdjustPermissions = $CertToAdjustPermissions.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName $KeyFileLocationCertToAdjustPermissions = $MachineKeysLocation + $KeyFileCertToAdjustPermissions # Get The Current ACL Of The Private Key $KeyFileCertToAdjustPermissionsACL = Get-Acl $KeyFileLocationCertToAdjustPermissions # Add The New ACE To The ACL Of The Private Key $KeyFileCertToAdjustPermissionsACL.SetAccessRule($AccessRule) # Write Back The New ACL $KeyFileCertToAdjustPermissionsACL | Set-Acl $KeyFileLocationCertToAdjustPermissions
Importing Certificates WITHOUT The Private Key
By using the following PoSH commands you can import the targeted certificate without the private key into the specified store.
# Define The Cert File To Import $CertFileToImport = "D:\Temp\CertToImportCERFile.CER" # Target The Cert That Needs To Be Imported $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertFileToImport # Define The Scope And Certificate Store Within That Scope To Import The Certificate Into # Available Cert Store Scopes are "LocalMachine" or "CurrentUser" $CertStoreScope = "LocalMachine" # For Available Cert Store Names See Figure 5 (Depends On Cert Store Scope) $CertStoreName = "My" $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreScope # Import The Targeted Certificate Into The Specified Cert Store Name Of The Specified Cert Store Scope $CertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) $CertStore.Add($CertToImport) $CertStore.Close()
–
You can also find multiple scripts about this here.
–
Importing Certificates WITH The Private Key
By using the following PoSH commands you can import the targeted certificate with the private key into the specified store. For this the password protecting the private key is needed.
# Define The Cert File To Import $CertFileToImport = "D:\Temp\CertToImportPFXFile.PFX" # Define The Password That Protects The Private Key # (ALSO see: https://jorgequestforknowledge.wordpress.com/2011/12/15/passwords-containing-special-characters-in-powershell/) $PrivateKeyPassword = 'Pa$$w0rd' # Target The Cert That Needs To Be Imported $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertFileToImport,$PrivateKeyPassword # Define The Scope And Certificate Store Within That Scope To Import The Certificate Into # Available Cert Store Scopes are "LocalMachine" or "CurrentUser" $CertStoreScope = "LocalMachine" # For Available Cert Store Names See Figure 5 (Depends On Cert Store Scope) $CertStoreName = "My" $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreScope # Import The Targeted Certificate Into The Specified Cert Store Name Of The Specified Cert Store Scope $CertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) $CertStore.Add($CertToImport) $CertStore.Close()
–
You can also find multiple scripts about this here.
–
So, what else can you use? Is there more than this? Yes, there is!
–
After you install the Quest Active Roles Management Shell For Active Directory (download here), you get lots of additional PowerShell CMDlets to use. To find those, just issue the command “Get-Command *QAD*” or have a look at the reference information. Just download and install the snap-in. To see the available snap-ins issue the command “Get-PSSnapIn -registered”. To import the snap-in issue the command “Add-PSSnapIn Quest.ActiveRoles.ADManagement”. The following CMDlets are available:
- Get-QADLocalCertificateStore
- New-QADLocalCertificateStore
- Remove-QADLocalCertificateStore
- Get-QADCertificate
- Where-QADCertificate
- Add-QADCertificate
- Import-QADCertificate
- Show-QADCertificate
- Edit-QADCertificate
- Export-QADCertificate
- Remove-QADCertificate
- Remove-QADPrivateKey
- Get-QADCertificateRevocationList
- Add-QADCertificateRevocationList
- Import-QADCertificateRevocationList
- Export-QADCertificateRevocationList
- Remove-QADCertificateRevocationList
- Get-QADPKIObject
- Publish-QADCertificate
- Unpublish-QADCertificate
- Publish-QADCertificateRevocationList
- Unpublish-QADCertificateRevocationList
–
In addition, after you install the Public Key Infrastructure PowerShell Module available on Codeplex (download here), you get lots of additional PowerShell CMDlets to manage Microsoft Certificate Authorities. Just download and install the module. To see the available modules issue the command “Get-Module -ListAvailable”. To import the module issue the command “Import-Module PKI”. The following PowerShell CMDlets are available:
- Add-AuthorityInformationAccess (Alias: Add-AIA)
- Add-CAKRACertificate
- Add-CATemplate
- Add-CertificateEnrollmentPolicyService (Alias: Add-CEP)
- Add-CertificateEnrollmentService (Alias: Add-CES)
- Add-CRLDistributionPoint (Alias: Add-CDP)
- Add-ExtensionList
- Approve-CertificateRequest
- Deny-CertificateRequest
- Disable-CertificateRevocationListFlag (Alias: Disable-CRLFlag)
- Disable-InterfaceFlag
- Disable-KeyRecoveryAgentFlag (Alias: Disable-KRAFlag)
- Disable-PolicyModuleFlag
- Enable-CertificateRevocationListFlag (Alias: Enable-CRLFlag)
- Enable-InterfaceFlag
- Enable-KeyRecoveryAgentFlag (Alias: Enable-KRAFlag)
- Enable-PolicyModuleFlag
- Get-ADKRACertificate
- Get-AuthorityInformationAccess (Alias: Get-AIA)
- Get-CAExchangeCertificate
- Get-CAKRACertificate
- Get-CASchema
- Get-CATemplate
- Get-CertificateRevocationList (Alias: Get-CRL)
- Get-CertificateRevocationListFlag (Alias: Get-CRLFlag)
- Get-CertificateTemplate
- Get-CertificateValidityPeriod
- Get-CertificationAuthority (Alias: Get-CA)
- Get-CRLDistributionPoint (Alias: Get-CDP)
- Get-CRLValidityPeriod
- Get-CryptographicServiceProvider (Alias: Get-Csp)
- Get-CryptographicServiceProviderCNG (Alias: Get-CspCNG)
- Get-EnrollmentServiceUri
- Get-ErrorMessage
- Get-ExtensionList
- Get-FailedRequest
- Get-InterfaceFlag
- Get-IssuedRequest
- Get-KeyRecoveryAgentFlag (Alias: Get-KRAFlag)
- Get-ObjectIdentifier
- Get-PendingRequest
- Get-PolicyModuleFlag
- Get-RevokedRequest
- Import-LostCertificate
- Install-CertificationAuthority
- Publish-CRL
- Remove-AuthorityInformationAccess (Alias: Remove-AIA)
- Remove-CAKRACertificate
- Remove-CATemplate
- Remove-CertificateEnrollmentPolicyService (Alias: Remove-CEP)
- Remove-CertificateEnrollmentService
- Remove-CertificateTemplate
- Remove-CRLDistributionPoint (Alias: Remove-CDP)
- Remove-ExtensionList
- Remove-Request
- Restart-CertificationAuthority
- Restore-CertificateRevocationListFlagDefault (Alias: Restore-CRLFlagDefault)
- Restore-InterFaceFlagDefault
- Restore-KeyRecoveryAgentFlagDefault (Alias: Restore-KRAFlagDefault)
- Restore-PolicyModuleFlagDefault
- Revoke-Certificate
- Set-AuthorityInformationAccess (Alias: Set-AIA)
- Set-CAKRACertificate
- Set-CATemplate
- Set-CertificateValidityPeriod
- Set-CRLDistributionPoint (Alias: Set-CDP)
- Set-CRLValidityPeriod
- Set-ExtensionList
- Show-Certificate
- Show-CertificateRevocationList (Alias: Show-CRL)
- Start-CertificationAuthority
- Stop-CertificationAuthority
- Uninstall-CertificationAuthority
–
Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
######### http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————
SW said
Great article
LikeLike
karthik said
When i import the certificate with private key the private key is storing in C:\Documents and Settings\username\Application Data\Microsoft\Crypto\RSA instead of C:\Documents and Settings\all users\Application Data\Microsoft\Crypto\RSA\MachineKeys. Could you please help on this.
LikeLike
fredric said
nice
LikeLike
Dhiraj Upadhyay said
I am struggling with taking ownership of the certificate,without which I am not able to assign permission .
LikeLike