.NET 4.6.1 and .NET 4.6.2 Installer

While working on my Prerequisite scripts for Exchange Server 2013 and 2016, I realized that the code section for .NET was no longer working. It turns out that there are quite a few recommended hotfixes that are required for .NET 4.6.1 and .NET 4.6.2 to install properly. In order to facilitate the installation of this for Prerequisite scripts I had to strip out the code for .NET and rebuild it in a separate script. This required a non-Windows 2016 server which has .NET 4.6.2 installed by default as well as a server that did not have .NET 4.6.1. So, using a base loaded Windows 2012 R2 server I was able to work out the script.

.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)

netinstallmenu

All patches install silently. The only install that shows or has any sort of visual indicator is .NET installers.
netinstallmenu-01

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s