It would help to know what you're entering as the display name, and what the uninstallstring value is from the registry. It would also be helpful to know if "$Un" is a scalar value (i.e., just one item) or an array (i.e., more than one item).
Just extracting the relevant parts of your code for a test produced the correct results:
$test ="Zoom Outlook Plugin"
$item = [PSCustomObject]@{displayname = "Zoom Outlook Plugin"; uninstallstring = "blah.exe /I"}
$un = $item | Where-Object {$_.displayname -eq $test} | Select-Object -Property uninstallstring
(($un.UninstallString)-replace"/I","/X") + " /qn"
Here's your script with some changes that will figure out what's happening:
$regKeys = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall*',
'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall*'
$test = read-host -Prompt "Please enter software by Display Name"
Write-Host "Will try to uninstall '$test'"
$Un = Get-ItemProperty -Path $regKeys |
Where-Object { $_.DisplayName -eq "$test"} |
Select-Object -Property uninstallstring
if ($un -is [array]){
Write-Host "Found $($un.count) items for removal: $($un.displayname -join ', ')"
}
elseif ($null -eq $un){
Write-Host "Didn't find any items for removal"
}
else {
Write-Host "Found 1 item for removal $($un.displayname)"
}
(($un.UninstallString)-replace"/I","/X") + " /qn" |
out-file "c:\RemoveOutlookplugin.bat" -Encoding ascii
Start-Sleep -Seconds 15
Invoke-Expression -Command "c:\RemoveOutlookplugin.bat"