.NET Requirements
You will notice that the .NET 4.6.1 download page (found here) does not list any prerequisites in order to install it. However, when you install it, you will find that you need to install KB2919355. If you review the download page for this patch, there is a list of other patches that must be installed:
- These KB’s must be installed in the following order: clearcompressionflag.exe, KB2919355, KB2932046, KB2959977, KB2937592, KB2938439, and KB2934018.
- KB2919442 is a prerequisite for Windows Server 2012 R2 Update and should be installed before attempting to install KB2919355
So, for Windows 2012 R2 we’ll need to install the above patches in this order:
- KB2919442
- clearcompressionflag.exe
- KB2919355
- KB2932046
- KB2959977
- KB2937592
- KB2938439
- KB2934018
For scripting purposes I needed the download link for each of these patches which was accomplish by manually downloading the files and then copying the link for the Downloads pop-up box in IE. I noticed that most of the patches were MSU files. Running MSU files with the technique I used in the prerequisite script would not work – I tested this and found that I would get pop-ups from the WSUA installer program.
Installation Code
Here is the code in order to install .NET 4.6.1 and/or .NET 4.6.2. This script is still enhanced as this article is being published. Option 5 on the menu only shows what hotfixes are installed on the server and it does not check for the specific hotfixes for .NET. This should be in the next revision of the script (version 1.2). Otherwise the script allows you to install all prereqs (option 1) for .NET 4.6.1, install .NET 4.6.1 (option 2), the postfix for .NET 4.6.1 (option 3) and .NET 4.6.2 (option 4) installation. Below is the code and a sample run through. of the script.
** NOTE ** This will be added in the next revisions of the prerequisite scripts.
# These KB's must be installed in the following order: clearcompressionflag.exe, KB2919355, KB2932046, KB2959977, KB2937592, KB2938439, and KB2934018. # KB2919442 is a prerequisite for Windows Server 2012 R2 Update and should be installed before attempting to install KB2919355 ################################## # Global Variable Definitions # ################################## $Ver = (Get-WMIObject win32_OperatingSystem).Version $OSCheck = $false $Choice = "None" $Date = get-date -Format "MM.dd.yyyy-hh.mm-tt" $DownloadFolder = "c:\downloads" $CurrentPath = (Get-Item -Path ".\" -Verbose).FullName $Reboot = $false $Error.clear() Clear-Host $Arg1 = "/quiet /norestart" ####################### ## Defined Functions ## ####################### # Begin BITSCheck function function BITSCheck { $Bits = Get-Module BitsTransfer if ($Bits -eq $null) { write-host "Importing the BITS module." -ForegroundColor cyan try { Import-Module BitsTransfer -erroraction STOP } catch { write-host "Server Management module could not be loaded." -ForegroundColor Red } } } # End BITSCheck function # Begin FileDownload function function FileDownload { param ($sourcefile) $Internetaccess = (Get-NetConnectionProfile -IPv4Connectivity Internet).ipv4connectivity If ($Internetaccess -eq "Internet") { if (Test-path $DownloadFolder) { write-host "Target folder $DownloadFolder exists." -foregroundcolor white } else { New-Item $DownloadFolder -type Directory | Out-Null } BITSCheck [string] $DownloadFile = $sourcefile.Substring($sourcefile.LastIndexOf("/") + 1) if (Test-Path "$DownloadFolder\$DownloadFile"){ write-host "The file $DownloadFile already exists in the $DownloadFolder folder." -ForegroundColor Cyan } else { Start-BitsTransfer -Source "$SourceFile" -Destination "$DownloadFolder\$DownloadFile" } } else { write-host "This machine does not have internet access and thus cannot download required files. Please resolve!" -ForegroundColor Red } } # End FileDownload function # KB2919442 Install function KB2919442 { FileDownload "https://download.microsoft.com/download/D/6/0/D60ED3E0-93A5-4505-8F6A-8D0A5DA16C8A/Windows8.1-KB2919442-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2919442-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2919442-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2919442 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # clearcompressionflag.exe Install function clearcompressionflag { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/clearcompressionflag.exe" Set-Location $DownloadFolder # [string]$expression = ".\clearcompressionflag.exe /quiet /norestart /l* $DownloadFolder\clearcompressionflag.log" [string]$expression = ".\clearcompressionflag.exe /norestart /l* $DownloadFolder\clearcompressionflag.log" write-host " " Write-Host "File: clearcompressionflag.exe installing..." -NoNewLine Invoke-Expression $expression Start-Sleep -Seconds 60 Write-Host "`nClearcompressionflag.exe has been run" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2919355 Install function KB2919355 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2919355-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2919355-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2919355-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2919355 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2932046 Install function KB2932046 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2932046-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2932046-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2932046-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2932046 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2959977 Install function KB2959977 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2959977-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2959977-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2959977-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2959977 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2937592 Install function KB2937592 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2937592-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2937592-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2937592-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2937592 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2938439 Install function KB2938439 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2938439-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2938439-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2938439-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2938439 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # KB2934018 Install function KB2934018 { FileDownload "https://download.microsoft.com/download/2/5/6/256CCCFB-5341-4A8D-A277-8A81B21A1E35/Windows8.1-KB2934018-x64.msu" Set-Location $DownloadFolder write-host " " Write-Host "File: Windows8.1-KB2934018-x64.msu installing..." -NoNewLine $HotFixInstall={ $arglist='Windows8.1-KB2934018-x64.msu','/quiet','/norestart' Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList $arglist -NoNewWindow -Wait } Invoke-Command -ScriptBlock $HotFixInstall Start-Sleep -Seconds 60 Write-Host "`nKB2934018 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # .NET 4.6.1 install function function NET461 { FileDownload "https://download.microsoft.com/download/E/4/1/E4173890-A24A-4936-9FC9-AF930FE3FA40/NDP461-KB3102436-x86-x64-AllOS-ENU.exe" Set-Location $DownloadFolder [string]$expression = ".\NDP461-KB3102436-x86-x64-AllOS-ENU.exe /quiet /norestart /l* $DownloadFolder\DotNET461.log" write-host " " Write-Host "File: NDP461-KB3102436-x86-x64-AllOS-ENU.exe installing..." -NoNewLine Invoke-Expression $expression Start-Sleep -Seconds 60 Write-Host "`n.NET 4.6.1 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # NET461Cleanup Function NET461Cleanup { # Download the Hotfix FileDownload "http://download.microsoft.com/download/E/F/1/EF1FB34B-58CB-4568-85EC-FA359387E328/Windows8-RT-KB3146714-x64.msu" Set-Location $DownloadFolder [string]$expression = "wusa.exe .\Windows8-RT-KB3146714-x64.msu /quiet /norestart" write-host " " Write-Host "File: Windows8-RT-KB3146714-x64.msu installing..." -NoNewLine Invoke-Expression $expression Start-Sleep -Seconds 60 Write-Host "`n.HotFix KB3146714 is now installed" -Foregroundcolor Green write-host " " } # .NET 4.6.2 Install function function NET462 { # Download the Hotfix FileDownload "https://download.microsoft.com/download/F/9/4/F942F07D-F26F-4F30-B4E3-EBD54FABA377/NDP462-KB3151800-x86-x64-AllOS-ENU.exe" Set-Location $DownloadFolder [string]$expression = ".\NDP462-KB3151800-x86-x64-AllOS-ENU.exe /quiet /norestart /l* $DownloadFolder\DotNET461.log" write-host " " Write-Host "File: NDP462-KB3151800-x86-x64-AllOS-ENU.exe installing..." -NoNewLine Invoke-Expression $expression Start-Sleep -Seconds 60 Write-Host "`n.NET 4.6.2 is now installed" -Foregroundcolor Green write-host " " $Reboot = $true } # Check for all hotifxes Function HotFixCheck { Get-HotFix } ####################### ## MAIN CODE SECTION ## ####################### $Menu = { Write-Host "*******************************************" Write-Host "** .NET 4.6.1 and .NET 4.6.2 Installaton **" Write-Host "*******************************************" Write-Host " " Write-Host "1) Install Pre-Patches for .NET 4.6.1" Write-Host "2) Install .NET 4.6.1" Write-Host "3) Cleanup POST 4.6.1" Write-Host "4) Install .NET 4.6.2" Write-Host "5) Check for pre 4.6.1 hotfixes." Write-Host " " Write-Host "99) Exit" Write-Host " " write-host "Enter a number: " -nonewline } Do { invoke-command -scriptblock $Menu $Choice = Read-Host switch ($Choice) { 1 { # KB2919442 ClearCompressionFlag KB2919355 KB2932046 KB2959977 KB2937592 KB2938439 KB2934018 } 2 { # .NET 4.6.1 Install NET461 } 3 { # Cleanup post 4.6.1 NET461Cleanup } 4 { # .NET 4.6.2 Install NET462 } 5 { # HotFix Check HotFixCheck Write-host " " Write-host " " Write-host " " } 99 {# Exit popd Write-Host "Exiting..." } } } while ($Choice -ne 99)
All patches install silently. The only install that shows or has any sort of visual indicator is .NET installers.
So, use Options 1-3 to get .NET 4.6.1 installed on the server. There is no check for OS type, but this is geared towards Windows Server 2012 R2.