Installing .NET 4.6.1 on Windows Server 2012 R2 with Chef
Recently I was lucky enough to take part in a ‘hackathon’ with Chef, Microsoft and a partner company based in Norway. It was a great week working with some amazing people!
One of the challenges we faced was automating the installation of .NET 4.6.1; a requirement of the application that was the focus of the week long event. We struggled with automatically determining whether the package should be installed on the system, and then triggering a reboot in the correct order to allow IIS configuration to complete.
Here’s the Windows package resource we used to install .NET originally.
package '.NET 4.6.1' do
source 'https://download.microsoft.com/download/E/4/1/E4173890-A24A-4936-9FC9-AF930FE3FA40/NDP461-KB3102436-x86-x64-AllOS-ENU.exe'
installer_type :custom
action :install
returns [0, 3010]
options '/norestart /passive'
timeout 3000
end
As you can see we needed to set the installer type to :custom
because we were using a .exe package. In addition to this we passed some options to prevent an automatic reboot interrupting the Chef run, and to prevent user dialogues from interrupting the installation.
This worked, but running chef-client
again would re-trigger the installation. Additionally, we had issues with IIS configuration (a different recipe) due to .NET installation being our first task. The flagged reboot prevented IIS features from fully enabling.
We decided to push the reboot out to the reboot resource with a notification from the Windows package resource.
reboot '.Net Install' do
reason 'Need to reboot after .NET installation'
action :nothing
end
if version_arr[6][:data] != 394_271
package '.NET 4.6.1' do
source 'https://download.microsoft.com/download/E/4/1/E4173890-A24A-4936-9FC9-AF930FE3FA40/NDP461-KB3102436-x86-x64-AllOS-ENU.exe'
installer_type :custom
action :install
returns [0, 3010]
options '/norestart /passive'
notifies :request_reboot, 'reboot[.Net Install]', :immediately
timeout 3000
end
We also changed the recipe order in default.rb
to make .NET installation the last task; this fixed our reboot flag issue with IIS.
With this working we could now trigger a reboot from the successful installation of .NET as the last task in the chef-client
run. Using request_reboot
in the Reboot resource ensured a complete run before the machine going down.
We still had the problem of idempotency. Every time we converged the .NET installation kicked off, even if it was already installed at the correct version. To resolve this we added some logic. We settled on checking the registry for the build release number (matching 4.6.1) to either skip or trigger the windows_package resource.
reboot '.Net Install' do
reason 'Need to reboot after .NET installation'
action :nothing
end
version_arr = registry_get_values('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', :x86_64)
if version_arr[6][:data] != 394_271
package '.NET 4.6.1' do
source 'https://download.microsoft.com/download/E/4/1/E4173890-A24A-4936-9FC9-AF930FE3FA40/NDP461-KB3102436-x86-x64-AllOS-ENU.exe'
installer_type :custom
action :install
returns [0, 3010]
options '/norestart /passive'
notifies :request_reboot, 'reboot[.Net Install]', :immediately
timeout 3000
end
end
Here’s the complete, working code.