Phidiax Tech Blog

Adventures in custom software and technology implementation.

BizTalk Server 2020 and BizTalk Server 2016 (including CU7) : Auto-Install Script for SFTP Requirement of WinSCP

Background

In the BizTalk installation documentation it outlines the fact that you need WinSCP. Michael Stephenson wrote a great article that goes into the how and why. He also included a simple script to automatically install the right version.

UPDATE: This script now automatically detects BizTalk Server 2020, BizTalk Server 2016 Cumulative Update 5 and the older versions of BizTalk Server 2016 before Cumulative Update 5 and downloads and installs the correct version. Thanks to Nicolas Blatter, a good friend, fellow former VTS and integration export who pointed out the change in behavior.

UPDATE: This script was re-written to handle BizTalk Server 2020, but also Cumulative Update 7 which changed the WinSCP Version. This was a significant rewrite to more properly handle environments that have Feature Pack 1, 2 and 3 and the latest cumulative updates.

Solution

As I love to script, I wanted to build something that was a little more robust and flexible. Here is the extended script which tries to figure out as much as possible automatically and gives error messages that might help you track down the problem.

#Parameters
Param([Parameter(Mandatory = $false)][string]$nugetDownloadFolder = (Get-Item Env:TEMP).Value + "\nuget")
Write-Debug ('$nugetDownloadFolder :' + $nugetDownloadFolder)
$Continue = $true
function SearchForCU {
    # Parameter help description
    Param([string] $CumulativeUpdateID)
    Write-Debug "Checking for CU $CumulativeUpdateID"
    $CUFound = $false
    $CUNameTemplate = "*BizTalk Server 2016 *KB*$CumulativeUpdateID*"
    Write-Debug "Cumulative Update Template $CUNameTemplate"
    
    $SearchResult = Get-ChildItem -path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -like $CUNameTemplate }
    if ($SearchResult) {
        Write-Host "Found BizTalk Cumulative Update " SearchResult.GetValue("DisplayName")
        $CUFound = $true
    }
    return $CUFound
}
$consoleWidth = $Host.UI.RawUI.WindowSize.Width - 2
$upString = "^" * $consoleWidth
$hashString = "#" * $consoleWidth
$bangString = "!" * $consoleWidth
$equalString = "=" * $consoleWidth

Write-Host $equalString

$nugetDownloadFolderExists = Test-Path $nugetDownloadFolder
if (-not $nugetDownloadFolderExists) {
    Write-Host $hashString
    Write-Debug ('The $nugetDownloadFolder doesn`t exist, creating the folder ' + $nugetDownloadFolder)
    New-Item -Path $nugetDownloadFolder -ItemType "Directory"
}
$nugetDownloadFolderExists = Test-Path $nugetDownloadFolder
if (-not $nugetDownloadFolderExists) {
    $Continue = $false
    Write-Error $bangString
    Write-Error "An attempt to use the '" $nugetDownloadFolder "' directory for a download target failed."
}
if ($Continue) {
    $bizTalkInstallFolder = (Get-Item Env:BTSINSTALLPATH).Value
    if (-not $bizTalkInstallFolder) {
        Write-Debug ('The Env:BTSINSTALLPATH doesn`t exist, checking to see if the path is in the registry HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0@InstallPath')
        $bizTalkInstallFolder = (get-itemPropertyValue 'HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0' -Name 'InstallPath')
        if (-not $bizTalkInstallFolder) {
            Write-Error $bangString
            Write-Error "BizTalk was not located by checking the environment variable BTSINSTALLPATH and"
            Write-Error " the Registry key for BizTalk, exiting the process"
            Write-Error "Confirm that BizTalk is installed"
            Write-Error $upString
            Write-Error $bangString
        }
    }
    $bizTalkInstallFolderExists = Test-Path $bizTalkInstallFolder
    if ($Continue -and -not $bizTalkInstallFolderExists) {
        $Continue = $false
        Write-Error "The BizTalk Installation was found in the registry"
        Write-Error " The folder $bizTalkInstallFolder does not exist, "
        Write-Error " even though it was discovered in the registry or the BTSINSTALLPATH environment setting"
        Write-Error $upString
        Write-Error $bangString
    }
}
if ($Continue) {
    $bizTalkProductCode = (get-itemPropertyValue 'HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0' -Name 'ProductCodeCurrent')
    $bizTalkProductName = (get-itemPropertyValue 'HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0' -Name 'ProductName')
    $bizTalkProductVer = (get-itemPropertyValue 'HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0' -Name 'ProductVersion')
    Write-Host $hashString
    Write-Host "Located $bizTalkProductName and verion $bizTalkProductVer"
    Write-Host "  installed in $bizTalkInstallFolder"
    Write-Host $hashString
    $winSCPVersion = "5.7.7"
    if ($bizTalkProductCode -eq '{205F5836-7512-4A06-9E74-ADC8AFA0EEC5}') {
        # BizTalk Server 2020
        #CU name Build version	KB number Release day       WinSCP Version
        #NonUC   3.13.717.0    NA         January 15, 2020  WinSCP 5.15.4
        Write-Host $hashString
        $winSCPVersion = "5.15.4"
        Write-Host "Detected BizTalk Server 2020 and this download process will use WinSCP $winSCPVersion"
    }
    elseif ($bizTalkProductCode -eq '{B084F3A7-3E8F-4E7B-B673-EED1715D28ED}') {
        Write-Host $hashString
        Write-Host "Detected BizTalk Server 2016, testing to see which Cumulative Update is installed"
        Write-Host $hashString
        # BizTalk Server 2016
        #
        #CU name Build version	KB number Release day       WinSCP Version
        #CU7     3.12.859.2    4528776   January 22, 2020   WinSCP 5.15.9
        #CU6     3.12.843.2    4477494   February 28, 2019  WinSCP 5.13.1
        #CU5     3.12.834.2    4132957   June 25, 2018      WinSCP 5.13.1
        #CU4     3.12.823.2    4051353   January 30, 2018   WinSCP 5.7.7
        #CU3     3.12.815.2    4039664   September 01, 2017 WinSCP 5.7.7
        #CU2     3.12.807.2    4021095   May 26, 2017       WinSCP 5.7.7
        #CU1     3.12.796.2    3208238   January 26, 2017   WinSCP 5.7.7
        #NonCU   3.12.xxx.x    NA        October 11, 2016   WinSCP 5.7.7
        $CUfound = $false
        Write-Host $hashString
        if (SearchForCU("4536185")) {
            # running BizTalk Server 2016 CU7 and FP 3 with new WinSCP Version
            $winSCPVersion = "5.15.9"
            Write-Host "Detected BizTalk Server 2016 with CU7 and FP3 and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4528776")) {
            # running BizTalk Server 2016 CU7 with new WinSCP Version
            $winSCPVersion = "5.15.9"
            Write-Host "Detected BizTalk Server 2016 with CU7 and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4294900")) {
            # running BizTalk Server 2016 CU6 and FP 3 with new WinSCP Version
            $winSCPVersion = "5.13.1"
            Write-Host "Detected BizTalk Server 2016 with CU6 and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4477494")) {
            # running BizTalk Server 2016 CU6 with new WinSCP Version
            $winSCPVersion = "5.13.1"
            Write-Host "Detected BizTalk Server 2016 with CU6 and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4132957")) {
            # running BizTalk Server 2016 CU5 with new WinSCP Version
            $winSCPVersion = "5.13.1"
            Write-Host "Detected BizTalk Server 2016 with CU5 and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4051353")) {
            # running BizTalk Server 2016 CU4, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU4, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4094130")) {
            # running BizTalk Server 2016 CU4, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU4, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4039664")) {
            4536185
            # running BizTalk Server 2016 CU3, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU3, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4054819")) {
            4536185
            # running BizTalk Server 2016 CU3, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU3, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4014788")) {
            4536185
            # running BizTalk Server 2016 CU3, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU3, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("4021095")) {
            # running BizTalk Server 2016 CU2, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU2, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
        elseif (SearchForCU("3208238")) {
            # running BizTalk Server 2016 CU1, using original WinSCP Version
            $winSCPVersion = "5.7.7"
            Write-Host "Detected BizTalk Server 2016 with CU1, and this download process will use WinSCP $winSCPVersion"
            $CUFound = $true
        }
                
    }
    if (-not $CUFound) {
        # running BizTalk Server 2016 without any Cumulative Updates, using original WinSCP Version
        $winSCPVersion = "5.7.7"
        Write-Host "Detected BizTalk Server 2016 with no cumulative updates installed, and this download process will use WinSCP $winSCPVersion"
    }
    if ($winSCPVersion -eq "5.15.9") {
        $winSCPexe = "WinSCP.5.15.9\tools\WinSCP.exe"
        $winSCPdll = "WinSCP.5.15.9\lib\net\WinSCPnet.dll"
    }
    elseif ($winSCPVersion -eq "5.15.4") {
        $winSCPexe = "WinSCP.5.15.4\tools\WinSCP.exe"
        $winSCPdll = "WinSCP.5.15.4\lib\net\WinSCPnet.dll"
    }
    elseif ($winSCPVersion -eq "5.13.1") {
        $winSCPexe = "WinSCP.5.13.1\tools\WinSCP.exe"
        $winSCPdll = "WinSCP.5.13.1\lib\net\WinSCPnet.dll"
    }
    elseif ($winSCPVersion -eq "5.7.7") {
        $WinSCPexe = "WinSCP.5.7.7\content\WinSCP.exe"
        $winSCPdll = "WinSCP.5.7.7\lib\WinSCPnet.dll"
    }
}

if ($Continue) {
    #Download NuGet
    $sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
    Write-Host $hashString
    Write-Host "Downloading Nuget from $sourceNugetExe and storing it in the folder $nugetDownloadFolder"
    $targetNugetExe = "$nugetDownloadFolder\nuget.exe"
    Write-Debug "Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe"
    Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe
    $targetNugetExeExists = Test-Path $targetNugetExe
    if (-not $targetNugetExeExists) {
        $Continue = $false
        Write-Error "The download of the Nuget EXE from " $sourceNugetExe " did not succeed"
        Write-Error $bangString
    }
}
if ($Continue) {
    #Download the right version of WinSCP
    Write-Host $hashString
    Write-Host "Downloading WinSCP version $winSCPVersion from NuGet $sourceNugetExe and storing it in $nugetDownloadFolder"
    Write-Debug "$getWinSCP = '$targetNugetExe' Install WinSCP -Version $winSCPVersion -OutputDirectory '$nugetDownloadFolder'"
    $getWinSCP = "'$targetNugetExe' Install WinSCP -Version $winSCPVersion -OutputDirectory '$nugetDownloadFolder'"
      
    Write-Debug "Invoke-Expression `"& $getWinSCP"
    Invoke-Expression "& $getWinSCP"
    $WinSCPDownload = "$nugetDownloadFolder\$winSCPexe"
    $WinSCPDllDownload = "$nugetDownloadFolder\$winSCPdll"
    $WinSCPExists = Test-Path $WinSCPDownload
    $WinSCPDLLExists = Test-Path $WinSCPDllDownload
    if (-not $WinSCPExists -or -not $WinSCPDLLExists) {
        $Continue = $false
        Write-Error "WinSCP $winSCPVersion was not properly downloaded"
        Write-Error $bangString
    }
}
if ($Continue) {
    #Copy WinSCP items to BizTalk Folder
    Write-Host $hashString
    Write-Host "Copying WinSCP version $winSCPVersion to BizTalk Folder"
    write-debug "Copy-Item $WinSCPDownload $bizTalkInstallFolder"
    Copy-Item $WinSCPDownload $bizTalkInstallFolder
    write-debug "Copy-Item $WinSCPDllDownload $bizTalkInstallFolder"
    Copy-Item $WinSCPDllDownload $bizTalkInstallFolder
    $WinSCPBTSExists = Test-Path "$bizTalkInstallFolder\WinSCP.exe"
    $WinSCPDLLBTSExists = Test-Path "$biztalkInstallFolder\WinSCPnet.dll"
    if (-not $WinSCPBTSExists) {
        $Continue = $false
        Write-Error "The WinSCP.exe file version $winSCPVersion was not properly copied to the target folder " $bizTalkInstallFolder
        Write-Error $bangString
    }
    if (-not $WinSCPDLLBTSExists) {
        $Continue = $false
        Write-Error "The WinSCPnet.dll file version $winSCPVersion was not properly copied to the target folder " $bizTalkInstallFolder
        Write-Error $bangString
    }
}
  
if (-not $Continue) {
    Write-Error $bangString
    Write-Error "Something went wrong during installation and the installation is not working"
    Write-Error "Please inspect the errors above and resolve them"
    Write-Error "Exiting"
    Write-Error $bangString
}
else {
    Write-Host $hashString
    Write-Host -ForegroundColor Green "WinSCP has been properly installed for BizTalk's SFTP Adapter"
    Write-Host -ForegroundColor Green $upString
    Write-Host $equalString
}

Comments (1) -

  • Iwe Kardum

    1/24/2019 1:40:38 AM | Reply

    Wonderful script! Works perfectly!

Loading

Privacy Policy  |  Contact  |  Careers

2009-2017 Phidiax, LLC - All Rights Reserved