ps/Modules/Alkami.DevOps.Certificates/Public/Import-Certificates.ps1
2023-05-30 22:51:22 -07:00

194 lines
7.2 KiB
PowerShell

function Import-Certificates {
<#
.SYNOPSIS
Imports certificates onto a machine.
.PARAMETER importPassword
The password used to import the certificate with. Only used when Personal store certificates are imported.
.PARAMETER importPath
The path the certificates are imported from. If no path is defined, the current working directory is used.
.PARAMETER usersWhoNeedRights
Optional list of users to grant rights for certificates which have private keys. If not supplied, defaults to IIS_IUSRS + $defaultUsersWhoNeedRights array.
.PARAMETER securityGroup
The Security Group for each GMSA account (pod6, pod8). When not supplied, defaults to the value in the machine.config on the current server.
If not found in machine.config, throws.
.PARAMETER skipRootCerts
When this flag is supplied it will skip the importing of certificates in the 'Root' store.
.PARAMETER skipPersonalCerts
When this flag is supplied it will skip the importing of certificates in the 'My' store.
.PARAMETER skipTrustedCerts
When this flag is supplied it will skip the importing of certificates in the 'Trusted' store.
.PARAMETER skipIACerts
When this flag is supplied it will skip the importing of certificates in the 'CertificateAuthority' store.
#>
[CmdletBinding()]
Param(
[parameter(Mandatory = $false)]
[string]$importPassword,
[Parameter(Mandatory = $false)]
[string]$importPath = $PWD,
[Parameter(Mandatory = $false)]
[string[]]$usersWhoNeedRights = @("IIS_IUSRS"),
[Parameter(Mandatory = $false)]
[string]$securityGroup,
[Parameter(Mandatory = $false)]
[hashtable]$certPasswordList = @{ },
[Parameter(Mandatory = $false)]
[switch]$skipRootCerts,
[Parameter(Mandatory = $false)]
[switch]$skipPersonalCerts,
[Parameter(Mandatory = $false)]
[switch]$skipTrustedCerts,
[Parameter(Mandatory = $false)]
[switch]$skipIACerts
)
$unsignedCertFileIncludeFilter = @("*.cer", "*.crt")
# Modify this to add/remove accounts as defaults when usersWhoNeedRights is not supplied by the user
# Will be formatted as FH\<securityGroup>.<account>
$defaultUsersWhoNeedRights = @("radium$", "nag$", "dbms$", "micro$")
if (!$skipPersonalCerts.IsPresent -and !$importPassword) {
throw "Import Password cannot be null";
}
if ($skipRootCerts.IsPresent -and $skipPersonalCerts.IsPresent -and $skipTrustedCerts.IsPresent -and $skipIACerts.IsPresent) {
throw "All Skip Switches cannot be set";
}
if (!(Test-Path $importPath)) {
throw "Import Path not found";
}
if ( !($PSBoundParameters.ContainsKey('securityGroup')) ) {
Write-Host "securityGroup was not supplied by the user. Attempting to pull securityGroup from Environment.UserPrefix in machine.config."
if ($securityGroup = Get-AppSetting Environment.UserPrefix) {
Write-Host "securityGroup read from machine.config as: $securityGroup"
} else {
throw("securityGroup was not supplied by the user and could not be found in the machine config. Please specify the security group (i.e. pod6, pod8) and rerun this function.")
}
}
if ( !($PSBoundParameters.ContainsKey('usersWhoNeedRights')) ) {
Write-Host "usersWhoNeedRights was not supplied by the user. Using default accounts."
$defaultUsersWhoNeedRights = foreach ($defaultUserWhoNeedsRights in $defaultUsersWhoNeedRights) {
"fh\$securityGroup.$defaultUserWhoNeedsRights"
}
$usersWhoNeedRights += $defaultUsersWhoNeedRights
}
$rootImportPath = (Join-Path $importPath "Root");
if (!($skipRootCerts.IsPresent) -and (Test-Path $rootImportPath)) {
Write-Host "Importing Root Certs";
$certs = Get-ChildItem $rootImportPath -Recurse -include $unsignedCertFileIncludeFilter -Exclude "WMSVC*";
foreach ($cert in $certs) {
Import-Cert $cert.FullName ([System.Security.Cryptography.X509Certificates.StoreName]::Root);
}
}
$iaImportPath = (Join-Path $importPath "IA");
if (!($skipIACerts.IsPresent) -and (Test-Path $iaImportPath)) {
Write-Host "Importing IA Certs";
$certs = Get-ChildItem $iaImportPath -Recurse -include $unsignedCertFileIncludeFilter -Exclude "WMSVC*";
foreach ($cert in $certs) {
Import-Cert $cert.FullName ([System.Security.Cryptography.X509Certificates.StoreName]::CertificateAuthority);
}
}
$trustedImportPath = (Join-Path $importPath "TrustedPeople");
if (!($skipTrustedCerts.IsPresent) -and (Test-Path $trustedImportPath)) {
Write-Host "Importing Trusted Certs";
$certs = Get-ChildItem $trustedImportPath -Recurse -include $unsignedCertFileIncludeFilter -Exclude "WMSVC*";
foreach ($cert in $certs) {
Import-Cert $cert.FullName ([System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople);
}
}
$pfxImportPath = (Join-Path $importPath "Personal");
if (!($skipPersonalCerts.IsPresent) -and (Test-Path $pfxImportPath)) {
Write-Host "Importing Personal Certs";
$certs = Get-ChildItem $pfxImportPath -Recurse -include @("*.pfx", "*.cer") -Exclude "WMSVC*";
# Add any additional Service Users to $usersWhoNeedRights if they're assigned to a Windows Service
# and are running under the environment's gMSA Security Group
$ServiceUserAccounts = Get-CIMInstance Win32_Service | Where-Object { $_.StartName -match $securityGroup }
if ($ServiceUserAccounts) {
$usersWhoNeedRights += $ServiceUserAccounts.StartName
}
$usersWhoNeedRights = $usersWhoNeedRights | Sort-Object | Get-Unique
foreach ($cert in $certs) {
if ($cert.Extension -eq ".pfx") {
$currentCertPassword = $importPassword;
if ($certPasswordList.ContainsKey($cert.Name)) {
$currentCertPassword = certPasswordList.Get_Item($cert.Name);
}
Import-Cert $cert.FullName ([System.Security.Cryptography.X509Certificates.StoreName]::My) $currentCertPassword;
Confirm-Cert $cert.Name ([System.Security.Cryptography.X509Certificates.StoreName]::My);
$x509cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cert.FullName, $currentCertPassword);
$usersWhoNeedRights | ForEach-Object {
$user = $_;
Write-Host ("Granting {0} rights to PK for certificate {1}" -f $user, $targetCert.Name);
Set-CertPermissions $x509cert.Thumbprint $user;
}
} else {
$currentCertPassword = $importPassword;
if ($certPasswordList.ContainsKey($cert.Name)) {
$currentCertPassword = certPasswordList.Get_Item($cert.Name);
}
Import-Cert $cert.FullName ([System.Security.Cryptography.X509Certificates.StoreName]::My);
Confirm-Cert $cert.Name ([System.Security.Cryptography.X509Certificates.StoreName]::My);
}
}
}
}