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\. $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); } } } }