Overview
The parent runbook imports a list of servers from a CSV containing the hostname and domain name, then invokes a child runbook on the relevant Orchestrator Runbook Server, depending on the domain name.
The CSV is formatted as follows:
Server,Domain
HOST1,PROD
HOST2,PREPROD
Runbook Activity's
- GetRecords: PowerShell to ingest each line from the CSV and published to the Orchestrator data bus with $ArrayList variable.
$ArrayList = @()
@"
{Line text from "Read Line"}
"@.Split("'`n") | foreach {
$ArrayList += "$_"
}
- ProcessRecords: PowerShell to split the $ArrayList string into individual variables ready to be used for subsequent activity's.
$Computer= "[Field({ArrayList from "GetRecords"},',',1)]"
$Domain= "[Field({ArrayList from "GetRecords"},',',2)]"
- Invoke the Request PFX Runbook: This runbook will be run on the corresponding Orchestrator Runbook Server depending on the 'Domain' value.
(The Server name is translated into the CN parameter.)
- Request and Export PFX Certificate
The 'Domain' and 'Server' values from the CSV are parsed into the script which ultimately exports a PFX file to D:\SCORCH ready to be transferred to the target Linux system and used during SCCM client installation.
This is the contents of the PowerShell 'Run .Net Script' activity.
- Determine the issuing CA server and Certificate Template name using the 'Domain' Initialize Data value.
if ($Domain -like "PREPROD")
{
$CAName = "#SERVERNAME#\PreProd CA"
$TemplateName = "ConfigMgrClientCertificateforExport"
}
elseif ($Domain -like "PROD")
{
$CAName = "#SERVERNAME#\IssuingCA"
$TemplateName = "ConfigMgrClientCertificateforExport"
}
elseif ($Domain -like "ST")
{
$CAName = "#SERVERNAME#\ST CA"
$TemplateName = "ConfigMgrClientCertificateforExport"
}
- Define a function to remove temporary certificate request files.
function Remove-ReqTempfiles()
{
param(
[String[]]$tempfiles
)
Write-Verbose "Cleanup temp files and pending requests"
#delete pending request (if a request exists for the CN)
$certstore = new-object system.security.cryptography.x509certificates.x509Store('REQUEST', 'LocalMachine')
$certstore.Open('ReadWrite')
foreach($certreq in $($certstore.Certificates))
{
if($certreq.Subject -eq "CN=$CN")
{
$certstore.Remove($certreq)
}
}
$certstore.close()
foreach($file in $tempfiles){remove-item ".\$file" -ErrorAction silentlycontinue}
}
- Remove temporary request files (in case left over from previous requests)
Remove-ReqTempfiles -tempfiles "certreq.inf","certreq.req","$CN.cer","$CN.rsp"
- Build certificate request file
$file = @"
[NewRequest]
Subject = "CN=$CN"
MachineKeySet = TRUE
KeyLength = 2048
Exportable = TRUE
[RequestAttributes]
CertificateTemplate = "$TemplateName"
"@
Set-Content .\certreq.inf $file
- Submit certificate request and add to local cert store.
Invoke-Expression -Command "certreq -new certreq.inf certreq.req"
Invoke-Expression -Command "certreq -submit -config `"$CAName`" certreq.req $CN.cer"
Invoke-Expression -Command "certreq -accept $CN.cer"
- Export PFX file to D:\SCORCH directory
$certpath = "d:\SCORCH\$CN.pfx"
Invoke-Expression -Command "certutil -privatekey -exportPFX -p 'Password' my $CN $certpath"
- Remove certificate from local cert store, and remove temporary files.
$cert = Get-Childitem "cert:\LocalMachine\My" | where-object {$_.Thumbprint -eq (New-Object System.Security.Cryptography.X509Certificates.X509Certificate2((Get-Item "$CN.cer").FullName,"")).Thumbprint}
$certstore = new-object system.security.cryptography.x509certificates.x509Store('My', 'LocalMachine')
$certstore.Open('ReadWrite')
$certstore.Remove($cert)
$certstore.close()
Remove-ReqTempfiles -tempfiles "certreq.inf","certreq.req","$CN.cer","$CN.rsp"
The PFX file will be located on each Orchestrator server in the D:\SCORCH directory, which then needs to be manually copied to where ever it's needed.
0 comments:
Post a Comment