168 lines
7.2 KiB
PowerShell
168 lines
7.2 KiB
PowerShell
function Export-CertificatesToFileSystem {
|
|
<#
|
|
.SYNOPSIS
|
|
Exports certificates from desired stores (My, CertificateAuthority, Root, and TrustedPeople by default)
|
|
onto the file system.
|
|
|
|
.DESCRIPTION
|
|
This script will export all public certificates and private keys in a given store to the file system. The
|
|
certificate chain is also exported in an individualized folder along with the certificate so that you
|
|
can delineate what certificates are needed for the one exported.
|
|
|
|
A password is generated for private keys, if ADGroups are given they are assigned to the private keys as well.
|
|
This script also returns a model of the data exported. With this model the file system data is more
|
|
easily manipulated and was originally intended to be used by a module for uploading these certificates
|
|
and their chains to individual secrets in secret server.
|
|
|
|
.PARAMETER PodName
|
|
String
|
|
Used to create a leaf folder with in which the certificates will be exported and set as a property
|
|
on the model returned as a result of this cmdlet.
|
|
|
|
.PARAMETER CertRoot
|
|
String
|
|
Location that this cmdlet will be working out of. This is set to LocalMachine but could be set to Personal
|
|
or other certificate providers.
|
|
|
|
.PARAMETER StoresToExport
|
|
StoreName[]
|
|
All certificates in these stores will be exported along with their certificate chains and private keys.
|
|
|
|
.PARAMETER ADGroups
|
|
String[]
|
|
Any ADGroups or UserAccounts that are given will be assigned to private keys exported. These users
|
|
will be able to import the private keys without a password, although one is generated and set
|
|
by this cmdlet regardless
|
|
|
|
.EXAMPLE
|
|
Export-CertificatesToFileSystem -PodName "Pod 1.1.1"
|
|
|
|
Base usage, will export all certificates in the default stores and their private keys to the Default Export Root
|
|
Folder under leaf folder 'Pod 1.1.1'. A password will be generated for the private keys and returned to the
|
|
caller in the model object.
|
|
|
|
.EXAMPLE
|
|
Export-CertificatesToFileSystem -PodName "Pod 7.0.5" -ADGroups "corp\JSmith","corp\CCarter" -RootExportFolder "C:\Exports"
|
|
|
|
Will export all certificates in the default stores and their private keys to the C:\Exports
|
|
Folder under leaf folder 'Pod 7.0.5'. Users JSmith and CCarter will be able to import the private keys
|
|
without the password, however passwords generated for these certificates will be returned with the
|
|
model object that this cmdlet produces.
|
|
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $True)]
|
|
[string]$PodName,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CertRoot = "Cert:\LocalMachine\",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$RootExportFolder = "c:\temp\CertExports",
|
|
[Parameter(Mandatory = $False)]
|
|
$StoresToExport = @([System.Security.Cryptography.X509Certificates.StoreName]::My,
|
|
[System.Security.Cryptography.X509Certificates.StoreName]::CertificateAuthority,
|
|
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
|
|
[System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople),
|
|
[Parameter(Mandatory = $False)]
|
|
[string[]]$ADGroups = ""
|
|
)
|
|
|
|
begin {
|
|
|
|
$logLead = Get-LogLeadName
|
|
|
|
$Pod = [PSObject]@{
|
|
PodName = $PodName
|
|
ExportFolder = (Join-Path $RootExportFolder $PodName)
|
|
StoresToExport = $StoresToExport
|
|
CertRoot = $CertRoot
|
|
Stores = @{ }
|
|
}
|
|
|
|
if (Test-Path -Path $Pod.ExportFolder) {
|
|
Write-Host "$logLead : Removing items from $($Pod.ExportFolder) before beginning"
|
|
Remove-FileSystemItem -Path $Pod.ExportFolder -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
|
|
if (-not (Test-Path -PathType Container -Path $Pod.ExportFolder)) {
|
|
New-Item $Pod.ExportFolder -ItemType Directory | Out-Null
|
|
}
|
|
}
|
|
|
|
process {
|
|
foreach ($storeName in $Pod.StoresToExport) {
|
|
$store = [PSObject]@{
|
|
Name = $storeName
|
|
ExportStorePath = Join-Path $Pod.ExportFolder $storeName
|
|
StorePath = Join-Path $Pod.CertRoot $storeName
|
|
Certificates = @{ }
|
|
}
|
|
|
|
# Powershell's Paths don't match the X509 enum. So here we do a poor man's lookup. If we ever need more stores than just the CA, this needs to be expanded to something more robust and clean.
|
|
if ($store.Name -eq "CertificateAuthority") {
|
|
$store.StorePath = "Cert:\LocalMachine\CA"
|
|
}
|
|
|
|
$Pod.Stores.Add($storeName, $store)
|
|
$Pod.Stores | Add-Member -MemberType NoteProperty -Name $storeName -Value $store
|
|
|
|
New-Item $store.ExportStorePath -ItemType Directory | Out-Null
|
|
|
|
#foreach cert in store
|
|
try {
|
|
$certificates = Get-ChildItem $store.StorePath;
|
|
}
|
|
catch {
|
|
Write-Warning "Cannot find Certificates in $storeName"
|
|
}
|
|
if ($certificates.Count -gt 0) {
|
|
foreach ($cert in $certificates) {
|
|
|
|
try {
|
|
|
|
$exportInfo = Export-CertificateToFileSystem -cert $cert -exportStorePath $store.ExportStorePath -ADGroups $ADGroups
|
|
if ($null -eq $exportInfo) { continue }
|
|
|
|
$chainInfo = Export-CertChain -cert $cert -exportStorePath $store.ExportStorePath -exportCertPath $exportInfo.exportCertPath -ADGroups $ADGroups
|
|
|
|
$CertificateChain = [PSObject]@{
|
|
Folder = Join-Path $exportInfo.ExportCertPath "ChainedCertificates"
|
|
Certificates = @{ }
|
|
}
|
|
|
|
foreach ($chainedCert in $chainInfo) {
|
|
$CertificateChain.Certificates.Add($chainedCert.certName, $chainedCert)
|
|
$CertificateChain.Certificates | Add-Member -MemberType NoteProperty -Name $chainedCert.certName -Value $chainedCert
|
|
}
|
|
|
|
$certificate = [PSObject]@{
|
|
Name = $exportInfo.certName
|
|
FilePath = $exportInfo.exportCertFile
|
|
Folder = $exportInfo.exportCertPath
|
|
Password = $exportInfo.certPassword
|
|
CertificateChain = $CertificateChain
|
|
ADGroups = $exportInfo.ADGroups
|
|
ExpirationDate = $exportInfo.ExpirationDate
|
|
Thumbprint = $exportInfo.Thumbprint
|
|
}
|
|
|
|
$store.Certificates.Add($certificate.Name, $certificate)
|
|
|
|
$store.Certificates | Add-Member -MemberType NoteProperty -Name $certificate.Name -Value $certificate
|
|
}
|
|
catch {
|
|
|
|
Write-Error "Certificate has failed to export
|
|
Name: $($certificate.Name), FriendlyName: $($cert.FriendlyName), Thumprint: $($cert.Thumbprint), Store: $storeName
|
|
$($_.Exception) $($_.Message) $($_.ScriptStackTrace)"
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
end {
|
|
return $Pod
|
|
}
|
|
}
|