Authoring tidbits / tricks and misc thoughts

I’ve been in the middle of publishing my fourth book, 33 : About the Letter C. The ebook version is availableon Amazon. As I’ve went through this process, I want to capture thoughts, tips / tricksI’ve learned through the writing /publishing process. This is a starter blog / table of contents sorta to document what I want to share. As with other books, it was entirely Holy Spirit inspired.

Each book has taken give or take 15 – 18 months from initial idea to print to complete. As I do more, it becomes more refined. Here is a list in no particular order, a blog seriesmeant to share what I’ve learned, hope to help others and if Lord willing, I have to publish another book, it’ll be reference for the steps I did.

  • Why do I write?
  • The editing process
  • The publishing process (formatting what?)
  • What items in Word do you adjust?
  • Ebook or Print?
  • Tips / Tricks and Tools to format your ebook
  • Tips / Tricks and Tools to format your print book
  • Marketing or lack of ?

Have you thought about writing a book? What is stopping you?!.



vRealize Automation certificate script to generate PEM files

I’ve been learning vRealize Automation 7 installs over the last few months.   I developed a script and associated xml config files to create necessary PEM files needed during vRA install.  For an Enterprise install, at least two certificates are required (medium install in my case).  This blog post doesn’t cover vRA install.  Check out Eric Shanks articles here along with VMware docs for install questions.

Regarding certificates, there a few articles that kind of cover creating PEM files.  When completing the install wizard requires the following:

  • PEM file with necessary root / intermediate / certificate in one file,
  • Private Key in another file

The script and associated XML files give flexible to create necessary certificates.  In my case, I’m doing an Medium install, two certificates are required.

  • One PEM file for vRA appliances
  • One PEM file for Iaas / Manager web sites

A medium enterprise install has two vRA appliances and two windows servers hosting Iaas Web and Manager service.   I use SAN (subject alternative names) certificates.


#1 - A working internal certificate authority is setup
#2 - A template in your CA setup provides Client and Server authentication
#3 - OpenSSL has been downloaded and placed in C:OpenSSL
#4 - Account running commands in script has appropriate rights on template in CA
#5 - Each OpenSSL configuration has been configured with appropriate DNS names (script creates this dynamically with input from XML files)

	[String] $ConfigurationFile = $(throw "Please specify the configuration file for the Content move.`r`nExample:`r`n`tGet-MachineLookup.ps1 -ConfigurationFile `"E:DirectoryChangeThisPath.xml`"")

switch (Test-Path $ConfigurationFile)
	True {Write-Host "Using $ConfigurationFile For Script Variables"
		$P = [xml](Get-Content $ConfigurationFile)
	False {Write-Host "$ConfigurationFile Not Found For Script Variables - Quitting"

#Get Properties and assign to local variables from XML file
[string]$certPath = $P.Configuration.Properties.certPath
[string]$subjAltName = $P.Configuration.Properties.subjAltName
[string]$commonName = $P.Configuration.Properties.commonName

[string]#OpenSSL config settings
[string]$openSSLCFGfileName = $P.Configuration.Properties.openSSLCFGfileName
[string]$countryName = $P.Configuration.Properties.countryName
[string]$stateOrProvinceName = $P.Configuration.Properties.stateOrProvinceName
[string]$localityName = $P.Configuration.Properties.localityName
[string]$organizationName = $P.Configuration.Properties.organizationName
[string]$organizationalUnitName = $P.Configuration.Properties.organizationalUnitName

[string]#General variables
[string]$CertificateTemplateName = $P.Configuration.Properties.CertificateTemplateName
[string]$CertificateKeyLength = $P.Configuration.Properties.CertificateKeyLength
[string]$RootCA = $P.Configuration.Properties.RootCA
[string]$OpenSSLPath = $P.Configuration.Properties.OpenSSLPath
[string]$OpenSSLRootDir = $P.Configuration.Properties.OpenSSLRootDir
[string]$CertPassword = $P.Configuration.Properties.CertPassword

function CreateOpenSSLConfig([string]$Path, [string]$subjAltName, [string]$commonName)
	Add-Content -path $Path$openSSLCFGfileName  -value "[ req ]"
	Add-Content -path $Path$openSSLCFGfileName  -value "default_bits = 2048"
	Add-Content -path $Path$openSSLCFGfileName  -value "default_keyfile = rui.key"
	Add-Content -path $Path$openSSLCFGfileName  -value "distinguished_name = req_distinguished_name"
	Add-Content -path $Path$openSSLCFGfileName  -value "encrypt_key = no"
	Add-Content -path $Path$openSSLCFGfileName  -value "prompt = no"
	Add-Content -path $Path$openSSLCFGfileName  -value "string_mask = nombstr"
	Add-Content -path $Path$openSSLCFGfileName  -value "req_extensions = v3_req"
	Add-Content -path $Path$openSSLCFGfileName  -value ""
	Add-Content -path $Path$openSSLCFGfileName  -value "[ v3_req ]"
	Add-Content -path $Path$openSSLCFGfileName  -value "basicConstraints = CA:FALSE"
	Add-Content -path $Path$openSSLCFGfileName  -value "keyUsage = digitalSignature,  keyEncipherment,  dataEncipherment, nonRepudiation"
	Add-Content -path $Path$openSSLCFGfileName  -value "extendedKeyUsage = serverAuth,  clientAuth"
	Add-Content -path $Path$openSSLCFGfileName  -value "subjectAltName = $($subjAltName)"
	Add-Content -path $Path$openSSLCFGfileName  -value ""						  
	Add-Content -path $Path$openSSLCFGfileName  -value "[ req_distinguished_name ]"
	Add-Content -path $Path$openSSLCFGfileName  -value "countryName = $($countryName)"
	Add-Content -path $Path$openSSLCFGfileName  -value "stateOrProvinceName = $($stateOrProvinceName)"
	Add-Content -path $Path$openSSLCFGfileName  -value "localityName = $($localityName)"
	Add-Content -path $Path$openSSLCFGfileName  -value "0.organizationName = $($organizationName)"
	Add-Content -path $Path$openSSLCFGfileName  -value "organizationalUnitName = $($organizationalUnitName)"
	Add-Content -path $Path$openSSLCFGfileName  -value "commonName = $($commonName)"

function CreateCertificate([string]$Path)
	[string]$certPathCMD = "$($OpenSSLPath) req -new -nodes -out $($Path)vra-cert.csr -keyout $($Path)vra-cert.key -config $($Path)openssl.cfg"
	Add-Content -path "$($Path)cmds.txt" -value $certPathCMD
	Invoke-Expression -Command $certPathCMD

	#Write RSA key
	[string]$certRSACMD = "$($OpenSSLPath) rsa -in  $($Path)vra-cert.key -out  $($Path)vra-cert.key"
	Add-Content -path "$($Path)cmds.txt" -value $certRSACMD
	Invoke-Expression -Command $certRSACMD

	#Variables for CSR, Certificate and P7B
	$CSRPath = "$($Path)vra-Cert.csr"
	$CertificatePath = "$($Path)vra-Cert.cer"
	$p7bPath = "$($Path)vra-Cert.p7b"

	#Call CA authority and retrieve certificates, p7bfile
	$certCMD = "$Env:SystemRootSystem32certreq -attrib `"CertificateTemplate:$($CertificateTemplateName)`" -submit -config $RootCA $CSRPath $CertificatePath $p7bPath"
	Add-Content -path "$($Path)cmds.txt" -value $certCMD
	Invoke-Expression -Command $certCMD 

	#This adds root CA and certificate to PEM files
	$ChainPEMFile = "$($OpenSSLPath) pkcs7 -in $($p7bPath) -print_certs -out $($Path)chain.pem"
	Add-Content -path "$($Path)cmds.txt" -value $ChainPEMFile
	Invoke-Expression -Command $ChainPEMFile

if(Test-Path -path $OpenSSLRootDir)
	#Create Path for config, files 
	New-Item -ItemType Directory -path $certPath -force

	#Create OpenSSL.cfg
	CreateOpenSSLConfig -Path $certPath -subjAltName $subjAltName -commonName $commonName 

	#Create CSR, Request Cert and create PEM file
	CreateCertificate -Path $certPath

XML Configuration File

<?xml version="1.0" encoding="UTF-8"?>
#1 - A working internal certificate authority is setup
#2 - A template is setup to provide Client and Server authentication
#3 - OpenSSL has been downloaded and placed in C:OpenSSL
#4 - The account running commands below have appropriate rights on the template
#5 - Each OpenSSL configuration has been configured with appropriate DNS names
		<subjAltName>DNS: vravaprod, DNS:, DNS:, IP:, DNS:, IP:, DNS: vra1, DNS:vra2</subjAltName>
		<!--#OpenSSL config settings-->
		<!--#General variables-->
		<CertificateTemplateName>Copy of Web Server</CertificateTemplateName>