SamplesV2/SelfHostedIntegrationRuntime/AutomationScripts/script-update-gateway.ps1 (238 lines of code) (raw):
param (
[Parameter(Mandatory = $false)]
[string]
$version,
[Parameter(Mandatory = $false)]
[string]
$allowDowngrade,
[Parameter(Mandatory = $false)]
[string]
$servicePassword
)
$ErrorActionPreference = "Stop"
$ProductName = "Microsoft Integration Runtime"
$supportedVersion = [System.Version]::new("5.4.7793.1")
function Get-PushedIntegrationRuntimeVersion() {
$latestIR = Get-RedirectedUrl "https://go.microsoft.com/fwlink/?linkid=839822"
$item = $latestIR.split("/") | Select-Object -Last 1
if ($null -eq $item -or $item -notlike "IntegrationRuntime*") {
throw "Can't get pushed $ProductName info"
}
$regexp = '^IntegrationRuntime_(\d+\.\d+\.\d+\.\d+)\s*\.msi$'
$version = [regex]::Match($item, $regexp).Groups[1].Value
if ($null -eq $version) {
throw "Can't get version from $ProductName download uri"
}
Write-InfoMsg "Pushed $ProductName version is $version"
return $version
}
function Get-IntegrationRuntimeInstaller([string] $folder, [string] $version) {
$uri = Get-InstallerUrl $version
$output = Join-Path $folder "IntegrationRuntime.msi"
Write-InfoMsg "Start to download $ProductName installer of version $version from $uri"
(New-Object System.Net.WebClient).DownloadFile($uri, $output)
if (-Not (Test-Path $output -PathType Leaf)) {
throw "Cannot download $ProductName installer of version $version"
}
Write-InfoMsg "$ProductName installer has been downloaded to $output."
return $output
}
function Get-InstallerUrl([string] $version) {
$uri = Get-RedirectedUrl
$uri = $uri.Substring(0, $uri.LastIndexOf('/') + 1)
$uri += "IntegrationRuntime_$version.msi"
return $uri
}
function Get-RedirectedUrl {
$URL = "https://go.microsoft.com/fwlink/?linkid=839822"
$request = [System.Net.WebRequest]::Create($url)
$request.AllowAutoRedirect = $false
$response = $request.GetResponse()
If ($response.StatusCode -eq "Found") {
$response.GetResponseHeader("Location")
}
}
function New-TempDirectory {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
return (New-Item -ItemType Directory -Path (Join-Path $parent $name))
}
function Get-CurrentIntegrationRuntimeVersion() {
$baseFolderPath = [System.IO.Path]::GetDirectoryName((Get-CmdFilePath))
$filePath = [System.IO.Path]::Combine($baseFolderPath, "Microsoft.DataTransfer.GatewayManagement.dll")
$currentVersion = $null
if (Test-Path $filePath -PathType Leaf) {
$currentVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($filePath).FileVersion
Write-InfoMsg "Current $ProductName version is $currentVersion"
}
return $currentVersion
}
function Get-RegistryKeyValue ([string] $registryPath) {
$baseKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64)
return $baseKey.OpenSubKey($registryPath)
}
function Get-IntegrationRuntimeIdentityNumber {
$installedSoftwares = Get-ChildItem "hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
foreach ($installedSoftware in $installedSoftwares) {
$displayName = $installedSoftware.GetValue("DisplayName")
if ($DisplayName -eq "$ProductName Preview" -or $DisplayName -eq "$ProductName") {
return Split-Path $installedSoftware.Name -Leaf
}
}
return $null
}
function Backup-IntegrationRuntimeConfig ([string] $installPath) {
Write-InfoMsg "Start to backup $ProductName configuration files."
$cmd = Get-CmdFilePath
$process = Start-Process $cmd "-ucf ""$installPath"" store" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Failed to backup $ProductName configuration files. Exit code: $($process.ExitCode)"
}
Write-InfoMsg "Succeed to backup $ProductName configuration files."
}
function Restore-IntegrationRuntimeConfig ([string] $installPath) {
Write-InfoMsg "Start to restore $ProductName configuration files."
$cmd = Get-CmdFilePath
$process = Start-Process $cmd "-ucf ""$installPath"" recover true" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Failed to restore $ProductName configuration files. Exit code: $($process.ExitCode)"
}
Write-InfoMsg "Succeed to restore $ProductName configuration files."
}
function Get-CmdFilePath {
$registryKeyValue = Get-RegistryKeyValue "Software\Microsoft\DataTransfer\DataManagementGateway\ConfigurationManager"
$filePath = $registryKeyValue.GetValue("DiacmdPath")
if ([string]::IsNullOrEmpty($filePath)) {
throw "Cannot find CLI executable file."
}
return (Split-Path -Parent $filePath) + "\dmgcmd.exe"
}
function Get-IntegrationRuntimeServiceAccount {
$irService = Get-WmiObject win32_service | Where-Object { $_.Name -eq "DIAHostService" }
return $irService.startname
}
function Set-IntegrationRuntimeServiceAccount ([string] $account, [string] $password) {
$cmd = Get-CmdFilePath
$process = Start-Process $cmd "-ssa $account $password" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Failed to set service account of $ProductName. Exit code: $($process.ExitCode)"
}
Write-InfoMsg "Succeed to set service account of $ProductName."
}
function Get-IntegrationRuntimeExeFolder {
$registryKeyValue = Get-RegistryKeyValue "Software\Microsoft\DataTransfer\DataManagementGateway\ConfigurationManager"
return Split-Path $registryKeyValue.GetValue("DiacmdPath") -Parent
}
function Uninstall-IntegrationRuntime ([string] $identityNumber) {
Write-InfoMsg "Start to uninstall $ProductName with identity number: $identityNumber"
$process = Start-Process "msiexec.exe" "/x $identityNumber /quiet KEEPDATA=1" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Failed to uninstall $ProductName. Exit code: $($process.ExitCode). Please try to uninstall $ProductName manually"
}
Write-InfoMsg "Succeed to uninstall $ProductName."
}
function Install-IntegrationRuntime ([string] $installerPath, [string] $installedPath, [boolean] $skipStartService) {
Write-InfoMsg "Start to install $ProductName"
$installArgs = "/i $installerPath /quiet"
if (-not [string]::IsNullOrEmpty($installedPath)) {
$installArgs += " INSTALLLOCATION=""$installedPath"""
}
if ($skipStartService) {
$installArgs += " SKIPSTARTSERVICE=""Yes"""
}
Write-InfoMsg "Install arguments: $installArgs"
$process = Start-Process "msiexec.exe" $installArgs -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Failed to install $ProductName. Exit code: $($process.ExitCode). Please try to install $installPath manually"
}
Write-InfoMsg "Succeed to install $ProductName."
}
function Write-InfoMsg([string] $msg) {
Write-Host "[$(Get-UtcNowString)][Info] $msg"
}
function Write-ErrorMsg([string] $msg) {
Write-Host "[$(Get-UtcNowString)][Error] $msg" -ForegroundColor Red
}
function Get-UtcNowString {
$utcNow = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), 'UTC')
return $utcNow.ToString("yyyy-MM-dd HH:mm:ss UTC")
}
# Main
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-ErrorMsg "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!"
Exit 1001
}
if ([string]::IsNullOrWhiteSpace($version)) {
$version = Get-PushedIntegrationRuntimeVersion
}
$versionObject = $null
if (-Not [System.Version]::TryParse($version, [ref]$versionObject)) {
Write-ErrorMsg "Invalid version value: $version."
Exit 1002
}
if ($versionObject -lt $supportedVersion) {
Write-ErrorMsg "Update to version less than $supportedVersion isn't supported."
Exit 1003
}
Write-InfoMsg "The version to be installed is $version"
$identityNumber = Get-IntegrationRuntimeIdentityNumber
$installed = ($null -ne $identityNumber)
if ($installed -and ($version -ieq (Get-CurrentIntegrationRuntimeVersion))) {
Write-InfoMsg "Current installed $ProductName is $version, no operation needed."
Exit
}
$isDowngrade = ($installed -and ($versionObject -lt [System.Version]::Parse((Get-CurrentIntegrationRuntimeVersion))))
if ($isDowngrade -and ($allowDowngrade -ine "true")) {
Write-ErrorMsg "You're trying to downgrade $ProductName, please set '-allowDowngrade' to true to enable downgrade."
Exit 1004
}
$serviceAccount = $null
if ($installed -and ("NT SERVICE\DIAHostService" -ine (Get-IntegrationRuntimeServiceAccount))) {
$serviceAccount = Get-IntegrationRuntimeServiceAccount
Write-InfoMsg "$ProductName service account is $serviceAccount"
}
if (($null -ne $serviceAccount) -and $isDowngrade -and ($null -eq $servicePassword)) {
Write-ErrorMsg "$ProductName isn't run as default account. You need to provide password of $serviceAccount with option '-servicePassword' to process downgrade."
Exit 1005
}
$installedPath = $null
if ($installed) {
$installedPath = (Split-Path -Parent (Split-Path -Parent (Split-Path -Parent (Get-CmdFilePath))))
}
$tmpFolder = New-TempDirectory
$installerPath = Get-IntegrationRuntimeInstaller $tmpFolder $version
if (-Not (Test-Path -Path $installerPath -PathType Leaf)) {
Write-ErrorMsg "The installer $installerPath doesn't exist."
Exit
}
if ($installed -and $isDowngrade) {
$backupPath = Join-Path -Path $installedPath -ChildPath "$([System.Version]::Parse((Get-CurrentIntegrationRuntimeVersion)).Major).0"
Backup-IntegrationRuntimeConfig $backupPath
Write-InfoMsg "Uninstall old $ProductName."
Uninstall-IntegrationRuntime $identityNumber
}
Write-InfoMsg "Install $ProductName"
Install-IntegrationRuntime $installerPath $installedPath ($null -ne $serviceAccount)
if ($isDowngrade) {
try {
$restorePath = Join-Path -Path $installedPath -ChildPath "$($versionObject.Major).0"
Restore-IntegrationRuntimeConfig $restorePath
}
catch {
Write-ErrorMsg $_
}
if ($null -ne $serviceAccount) {
try {
Set-IntegrationRuntimeServiceAccount $serviceAccount $servicePassword
}
catch {
Write-ErrorMsg $_
}
}
}
Write-InfoMsg "Clean up downloaded $ProductName installer: $installerPath."
Remove-Item $installerPath
if ($null -eq $identityNumber) {
Write-InfoMsg "Install complete. You may need to open $ProductName to manually register node."
}