Automating the Pre-Requisites for vCAC 5.2

The other day I noticed some comments on Twitter around the time taken to install VMware vCloud Automation Center 5.2

Being of curious nature I decided to check it out further and in doing so discovered this extensive installation guide from Jad El-Zein. Seeing as a lot of the pre-requisites are installing Windows Roles / Features and configuring IIS, I figured this would make a good candidate for some PowerShell work and might save you some time if you need to do this yourself.

By following the above install guide and using the vCAC Prereq Checker, I put together the below script which will complete the pre-reqs for you on Windows Server 2008 R2 and give you green ticks in the vCAC Prereq Checker.

Note: You need .NET 4.5 to install the  vCAC Prereq Checker - the below script will attempt to download and install .NET 4.5 for you if you don’t have it, since it’s a requirement for the full install of vCAC.

Slightly confusingly (to me anyway!), if you run the  vCAC Prereq Checker before doing anything else, it doesn’t actually show you that you are missing any of the IIS components / configuration items.

Post-IIS install you now see the set of requirements you need to match:

A number of IIS configuration items on the check list are red even though they are the default values in IIS. I’m not sure if this is an issue with the vCAC Prereq Checker or IIS, but setting them away from the default value and then back to that value (Have you tried turning it off and on again?!), followed by re-running the checks gives them a green tick - this is also mentioned in the above manual install guide.

For instance the  vCAC Prereq Checker thinks that:

WindowsAuthenticationExtendedProtection is Enabled

WindowsAuthenticationKernelMode is Disabled

Looking at IIS before making any changes, the reverse appears to be true:

Also, the  vCAC Prereq Checker reports that the Negotiate and NTLM Providers are Disabled:

Looking at IIS before making any changes, the reverse appears to be true:

So the script will resolve this for you and make the vCAC Prereq Checker happy :-)

One final thing to note is that we need to set the vCAC AD service account being used to the Local Security Policy User Right Assignment ‘Log on as a batch job’. There is no native way to do this yet in PowerShell so here I have used the tool ntrights.exe from Windows 2003 (!) Resource Kit. (Even though I don’t typically like placing additonal requirements the alternative using secedit was messy and overkill for changing one setting).

Before running the script, ensure you have set your PowerShell execution policy away from the default of Restricted so that you can run the script.


Set-ExecutionPolicy RemoteSigned

While Googling ‘vCAC’ and ‘vCloud Automation Center’ to ensure I was using the correct ‘v’ sign for this post I discovered Randy Stanley had already created something similar for vCAC 5.1. You may well want to check out this effort too since it includes some additional options around which roles of vCAC you are installing.

You can run the script like so:


./Install-vCACPreReqs.ps1 -DomainAccount Sunnydale\\vcacsvc -NTRightsExe C:\\Scripts\\ntrights.exe

and you should then be presented with some nice green ticks:

Update 02/12/13: Following some great feedback from Michael Poore I’ve updated the code with some changes including adding “SeServiceLogonRight” as a default user right to configure, adding the option to specify a path to the .NET 4.5 install exe and some additional verbose feedback.

 


.DESCRIPTION Install the Pre-requisites for vCAC 5.2

.PARAMETER DomainAccount Name of the Windows Domain Account to use for the vCAC install

.PARAMETER NTRightsExe Path to the NTRights.exe file (used to set Local User Rights Assignments)

.PARAMETER DotNetExe Path to the .NET Install file

.PARAMETER UserRights User Rights to assign the DomainAccount to "SeBatchLogonRight"

.PARAMETER FirewallOn Leave Windows Firewall turned on and create an exception rule for Distributed Transaction Coordinator

.EXAMPLE ./Install-vCACPreReqs.ps1 -DomainAccount Sunnydale\\vcacsvc -NTRightsExe C:\\Scripts\\ntrights.exe

.EXAMPLE ./Install-vCACPreReqs.ps1 -DomainAccount Sunnydale\\vcacsvc -NTRightsExe C:\\Scripts\\ntrights.exe -DotNetExe C:\\Downloads\\dotnetfx45\_full\_x86\_x64.exe -Verbose #>

\[CmdletBinding()\] Param ( \[Parameter(Mandatory=$true)\] \[ValidateNotNullOrEmpty()\] \[String\]$DomainAccount,

\[Parameter(Mandatory=$true)\] \[ValidateNotNullOrEmpty()\] \[Io.FileInfo\]$NTRightsExe,

\[Parameter(Mandatory=$false)\] \[ValidateNotNullOrEmpty()\] \[Io.FileInfo\]$DotNetExe,

\[Parameter(Mandatory=$false)\] \[ValidateNotNullOrEmpty()\] \[String\[\]\]$UserRights = ("SeBatchLogonRight","SeServiceLogonRight"),

\[Parameter(Mandatory=$false)\] \[Switch\]$FirewallOn )

\# --- Check for NTRights.exe if (!($NTRightsExe.Exists)){

throw "Please supply a valid path to NTRights.exe" }

\# --- Check for .NET Install File if ($PSBoundParameters.ContainsKey('DotNetExe')) {

if (!($DotNetExe.Exists)){

throw "Please supply a valid path to the DotNet install Exe file" } }

\# --- Check for 64bit PowerShell (needed for ServerManager module) if (!(\[IntPtr\]::size -eq 8)){

throw "64bit version of PowerShell required for ServerManager module" }

\# --- Start the Secondary Logon service if ((Get-Service seclogon).Status -ne 'Running'){

Start-Service seclogon }

\# --- Add the necessary Windows Components Import-Module ServerManager Add-WindowsFeature Web-Server,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-HTTP-Redirect,Web-App-Dev,Web-Windows-Auth,WAS,NET-Win-CFAC

\# --- Test for the WebAdministration Module and import it if (Get-Module -ListAvailable WebAdministration){

Write-Verbose "Importing the WebAdministration Module \`n" Import-Module WebAdministration } else {

throw "Required Module WebAdministration is not installed on this system" }

\# --- Configure IIS Authentication Services Write-Verbose "Configuring IIS settings \`n"

\# --- Anonymous Authentication Disabled Set-WebConfigurationProperty -Filter system.webServer/security/authentication/AnonymousAuthentication -Location 'Default Web Site' -Name Enabled -Value $false

\# --- Windows Authentication Enabled Set-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name Enabled -Value $true

\# --- Disable Windows Authentication Extended Protection (turn it on and back off again before the vCAC Pre-Checker will recognise this) Set-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name extendedProtection.tokenChecking -Value 'Allow' Set-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name extendedProtection.tokenChecking -Value 'None'

\# --- Enable Windows Authentication Kernel-Mode Authentication (turn it off and back on again before the vCAC Pre-Checker will recognise this) Set-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name useKernelMode -Value $false Set-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name useKernelMode -Value $true

\# --- Set Windows Authentication Providers Negotiate and NTLM Enabled (Remove then add them before the vCAC Pre-Checker will recognise this) Get-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name providers.Collection | Select-Object -ExpandProperty Value | ForEach-Object {Remove-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name providers.Collection -AtElement @{value=$\_}}

Add-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name providers.Collection -AtIndex 0 -Value "Negotiate" Add-WebConfigurationProperty -Filter system.webServer/security/authentication/WindowsAuthentication -Location 'Default Web Site' -Name providers.Collection -AtIndex 1 -Value "NTLM"

\# --- Set a firewall rule for Distributed Transaction Coordinator or turn the firewall off if ($PSBoundParameters.ContainsKey('FirewallOn')){

netsh advfirewall firewall set rule group="Distributed Transaction Coordinator" new enable=Yes | Out-Null } else {

netsh advfirewall set allprofiles state off | Out-Null }

\# --- Set MSDTC Registry Settings "NetworkDtcAccess","NetworkDtcAccessClients","NetworkDtcAccessTransactions","NetworkDtcAccessInbound","NetworkDtcAccessOutbound" | ForEach-Object {Set-ItemProperty -Path HKLM:\\Software\\Microsoft\\MSDTC\\Security -Name $\_ -Value 1}

\# --- Add User Rights Assignment $UserRights | ForEach-Object {Invoke-Expression "$NTRightsExe -u $DomainAccount +r $\_"}

\# --- Check for .NET 4.5 and attempt to install if not present $NetVersion = Get-ChildItem 'HKLM:\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP' -Recurse | Get-ItemProperty -name Version -EA 0 | Where-Object { $\_.PSChildName -match '^(?!S)\\p{L}'} | Sort-Object version -Descending | Select-Object -ExpandProperty Version -First 1 Write-Verbose ".NET version on this server is $NetVersion \`n"

if ($NetVersion -lt 4.5){

\# --- If .NET install location specified as a parameter use that path if ($PSBoundParameters.ContainsKey('DotNetExe')) {

Write-Verbose "Installing .NET 4.5 \`n"

$NetInstall = Start-Process $DotNetExe -ArgumentList "/q" -Wait -PassThru

if ($NetInstall.ExitCode -eq 0){

Write-Verbose ".NET 4.5 successfully installed \`n" } else {

throw "Unable to install .NET 4.5. Please install manually" } } # --- Else attempt to download .NET install from the Internet else {

Write-Verbose "Downloading and Installing .NET 4.5 \`n" $WebClient = New-Object Net.WebClient $WebClient.DownloadFile("http://go.microsoft.com/fwlink/?LinkId=225702","dotNetFx45\_Full\_x86\_x64.exe")

if (Test-Path .\\dotNetFx45\_Full\_x86\_x64.exe){ $NetInstall = Start-Process ".\\dotNetFx45\_Full\_x86\_x64.exe" -ArgumentList "/q" -Wait -PassThru

if ($NetInstall.ExitCode -eq 0){

Write-Verbose ".NET 4.5 successfully installed \`n" } else {

throw "Unable to install .NET 4.5. Please install manually" } } else {

throw "Unable to download .NET 4.5. Please install manually" } } }