Streamline Your Relay Server Migration Process

1. Introduction

My colleagues and I recently discussed a use case involving a customer with over 1,200 Pull Relay servers that need to be reinstalled after migrating to SaaS.

As I’ve highlighted in my previous blogs, all auxiliary On-Prem components are reconfigured post-migration. However, manually handling 1,200+ servers is simply not feasible. In this blog, I’ll walk through how we can automate the uninstallation and reinstallation of Pull Relay servers following the migration.

The provided scripts have been thoroughly tested and should work seamlessly in most environments. If they don’t align perfectly with your setup, you may need to make minor adjustments—but the overall framework is ready to use.

2. Process

Once the migration is complete and the UEM console configuration is in place, you’ll need to uninstall the Pull Relay first and then reinstall it to ensure the new configuration takes effect.

You will have to use a 3rd party tool like SCCM or something similar (Maybe Antivirus could also work) to push the scripts to the endpoint servers

Uninstall Script

<#  
    Script: Uninstall-OmnissaRelay.ps1
    Purpose: Uninstall Omnissa Relay Service from multiple remote servers
    Usage:  
        1. Create a text file "servers.txt" with one server name per line.
        2. Run PowerShell as Administrator.
        3. Execute: .\Uninstall-OmnissaRelay.ps1
#>

# Path to list of servers
$ServerList = Get-Content -Path "C:\servers.txt"

# Log file
$LogFile = "C:\Uninstall-OmnissaRelay-$(Get-Date -Format 'yyyyMMdd_HHmmss').log"

# Omnissa Relay service name
$ServiceName = "AirWatch_Pull_Service"   # Check exact display name in services.msc

# Omnissa Relay uninstall display name in Programs & Features
$ProductName = "WS1 Relay Server Cloud Connector 4.1.0 for Windows"   # Adjust if the name differs

foreach ($Server in $ServerList) {
    Write-Host "Processing server: $Server" -ForegroundColor Cyan
    try {
        # Test connectivity
        if (Test-Connection -ComputerName $Server -Count 1 -Quiet) {
            # Stop the service if running
            Invoke-Command -ComputerName $Server -ScriptBlock {
                param($ServiceName)
                if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) {
                    Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
                }
            } -ArgumentList $ServiceName
            
            # Find uninstall command
            $UninstallString = Invoke-Command -ComputerName $Server -ScriptBlock {
                param($ProductName)
                $product = Get-WmiObject -Class Win32_Product |
                           Where-Object { $_.Name -like "*$ProductName*" }
                if ($product) { $product.IdentifyingNumber }
            } -ArgumentList $ProductName

            if ($UninstallString) {
                # Run uninstall
                Invoke-Command -ComputerName $Server -ScriptBlock {
                    param($GUID)
                    Start-Process "msiexec.exe" -ArgumentList "/x $GUID /qn /norestart" -Wait
                } -ArgumentList $UninstallString
                Add-Content $LogFile "$Server : SUCCESS - Uninstalled"
                Write-Host "[$Server] Uninstall SUCCESS" -ForegroundColor Green
            }
            else {
                Add-Content $LogFile "$Server : SKIPPED - Product not found"
                Write-Host "[$Server] Product not found" -ForegroundColor Yellow
            }
        }
        else {
            Add-Content $LogFile "$Server : FAILED - No ping"
            Write-Host "[$Server] Cannot reach server" -ForegroundColor Red
        }
    }
    catch {
        Add-Content $LogFile "$Server : ERROR - $_"
        Write-Host "[$Server] ERROR: $_" -ForegroundColor Red
    }
}

Write-Host "=== Uninstall process completed. Check log: $LogFile ===" -ForegroundColor Magenta

Next, you will have to use the below script to install it again

# Workspace ONE Pull Relay Server Silent Install Script (InstallShield EXE version)
# Update these variables as needed
$InstallerPath = "C:\Temp\WS1_Pull_Service_4.1.0_for_Windows.exe"      # Path to your EXE
$ConfigXmlPath = "C:\Temp\PullServiceInstaller.config"  # Path to your XML
$InstallDir    = "C:\Airwatch"

# Ensure install directory exists
if (-not (Test-Path $InstallDir)) {
    New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null
}

Write-Host "Copying PullServiceConfiguration.xml..."
Copy-Item -Path $ConfigXmlPath -Destination "$InstallDir\PullServiceConfiguration.xml" -Force

Write-Host "Installing Relay Server silently from InstallShield EXE..."
# InstallShield silent syntax: /s /v"/qn INSTALLDIR=..."
$exeArgs = '/s /v"/qn "'

Start-Process -FilePath $InstallerPath -ArgumentList $exeArgs -Wait -NoNewWindow

Write-Host "Starting Workspace ONE Pull Relay Service..."
Start-Service -Name "AirWatchPullRelayService" -ErrorAction SilentlyContinue

Write-Host "Checking service status..."
$service = Get-Service -Name "AirWatchPullRelayService" -ErrorAction SilentlyContinue
if ($service -and $service.Status -eq "Running") {
    Write-Host "✅ Pull Relay Server is installed and running." -ForegroundColor Green
} else {
    Write-Host "❌ Pull Relay Server installation completed, but service is not running." -ForegroundColor Red
}

Write-Host "Script execution complete."

Note: If the customer is using Push Relays, these must be converted to Pull Relays and thoroughly tested before the migration to prevent any last-minute issues on cutover day.

I’ve also prepared a script to uninstall Push Relay servers. While it is still in the testing phase, it should work as expected. However, it’s recommended to run it on a few servers first before performing a large-scale deployment.

Uninstall Push Relay Servers

# Path to server list (one per line: hostname or IP)
$ComputerList = Get-Content "C:\Temp\RelayServers.txt"

# App name as shown in Programs & Features
$AppName = "Workspace ONE Push Relay Server"

# Log file
$LogFile = "C:\Temp\PushRelay_Uninstall_Log.txt"
New-Item -Path $LogFile -ItemType File -Force | Out-Null

foreach ($Computer in $ComputerList) {
    Write-Host "Connecting to $Computer ..." -ForegroundColor Cyan
    Add-Content $LogFile "`n[$(Get-Date)] --- $Computer ---"

    try {
        # Query installed apps remotely
        $UninstallString = Invoke-Command -ComputerName $Computer -ScriptBlock {
            Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                             HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
            Where-Object { $_.DisplayName -like "*Workspace ONE Push Relay*" } |
            Select-Object -ExpandProperty UninstallString -First 1
        }

        if ($UninstallString) {
            Write-Host "Found Push Relay uninstall command on $Computer" -ForegroundColor Yellow
            Add-Content $LogFile "Found uninstall string: $UninstallString"

            # Run uninstall silently
            Invoke-Command -ComputerName $Computer -ScriptBlock {
                param($Cmd)
                if ($Cmd -like "*.exe*") {
                    # For EXE uninstallers (InstallShield style)
                    Start-Process -FilePath $Cmd -ArgumentList "/s /v`"/qn`"" -Wait -NoNewWindow
                } else {
                    # For MSI fallback
                    Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $Cmd /qn /norestart" -Wait -NoNewWindow
                }
            } -ArgumentList $UninstallString

            Write-Host "✅ Successfully uninstalled from $Computer" -ForegroundColor Green
            Add-Content $LogFile "Success"
        }
        else {
            Write-Host "⚠ Push Relay not found on $Computer" -ForegroundColor DarkYellow
            Add-Content $LogFile "Not Installed"
        }
    }
    catch {
        Write-Host "❌ Error uninstalling on $Computer : $_" -ForegroundColor Red
        Add-Content $LogFile "Error: $_"
    }
}

3. Conclusion

This approach should streamline the uninstall and reinstall process for the Relays.

Once thoroughly tested, running it in parallel across all servers can complete the task within minutes, significantly reducing the overall effort and saving valuable time.

Hope this helps! You can reach out in case you have any questions!

Leave a comment