5

I tried to find the solution by myself but now I'm out of ideas. I wrote a script that I want to use to check if Erlang is installed on a machine:

# Check if a Software ins installed
function Check_Program_Installed($programName) {
$x86_check = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
Get-ItemProperty |
        Where-Object {$_.DisplayName -like "*$programName*" } |
            Select-Object -Property DisplayName, UninstallString)

if(Test-Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')  
{
$x64_check = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") |
Get-ItemProperty |
        Where-Object {$_.DisplayName -like "*$programName*" } |
            Select-Object -Property DisplayName, UninstallString)
}
if ($x86_check -and $x64_check -eq $null){ 
    write-host "$programName is not installed on this computer" -ForegroundColor Green 
    #continue
    }
elseif ($x86_check -or $x64_check -ne $null){
    write-host "On this computer is installed " -ForegroundColor Red     
    $x86_check
    $x64_check

    }
}

# Erlang check
Write-Host "Checking if Erlang exist    " -NoNewline
Check_Program_Installed("Erlang")

Write-Host "The End: the script ends here" -ForegroundColor Yellow

But if I execute it as result the very last line is executed before Check_Program_Installed("Erlang"). Why PowerShell is not respecting the step priority?

enter image description here

Checking if Erlang exist        On this computer is installed

The End: the script ends here
DisplayName          UninstallString
-----------          ---------------
Erlang OTP 21 (10.2) C:\Program Files\erl10.2\Uninstall.exe
Francesco Mantovani
  • 10,216
  • 13
  • 73
  • 113
  • 4
    Related (required reading): [PowerShell Write-Host not synchronous](https://serverfault.com/questions/693549/powershell-write-host-not-synchronous) – JosefZ Jan 24 '19 at 10:52
  • 1
    Not related to your issue but you've got x86/x64 mixed up and this could be a potential problem further along. – notjustme Jan 24 '19 at 11:26
  • 1
    @notjustme is right: `$x86_check -and $x64_check -eq $null` returns _true_ if a program **is installed as 32-bit** (and not 64-bit) however the function returns (wrong) "$programName **is not installed** on this computer". Read [Know your operator and enclosure precedence](https://poshoholic.com/2009/07/08/essential-powershell-know-your-operator-and-enclosure-precedence/) – JosefZ Jan 24 '19 at 11:53

2 Answers2

6

Just add Format-Table to $x86_check and $64_check at the end. Link to answer.

# Check if a Software ins installed
function Check_Program_Installed($programName) {
$x86_check = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
Get-ItemProperty |
        Where-Object {$_.DisplayName -like "*$programName*" } |
            Select-Object -Property DisplayName, UninstallString) | Format-Table

if(Test-Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')  
{
$x64_check = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") |
Get-ItemProperty |
        Where-Object {$_.DisplayName -like "*$programName*" } |
            Select-Object -Property DisplayName, UninstallString) | Format-Table
}
if ($x86_check -and $x64_check -eq $null){ 
    write-host "$programName is not installed on this computer" -ForegroundColor Green 
    #continue
    }
elseif ($x86_check -or $x64_check -ne $null){
    write-host "On this computer is installed " -ForegroundColor Red     
    $x86_check
    $x64_check

    }

}

# Erlang check
Write-Host "Checking if Erlang exist    " -NoNewline
Check_Program_Installed("Erlang")
Write-Host "The End: the script ends here" -ForegroundColor Yellow
  • Hi @Kristian Kanchev, why `Format-Table` fixed the issue? – Francesco Mantovani Jan 27 '19 at 05:35
  • 1
    Hi @FrancescoMantovani, well `Write-Host` is the only native PowerShell output cmdlet that writes directly to the console window, rather than to a pipeline. I had to do some reading to understand it for myself. And my logic would be by default your script provides the info as `Format-Table`, so this goes to the pipline, since `Write-Host` does not, it disregards the steps. But if you put Format-Table in the script and not let it be used by default it will output it to the cmdlet and not only the pipeline, making Write-Host follow the steps in the script. But this is my logic from what i found. – Kristian Kanchev Jan 27 '19 at 12:05
  • 1
    In addition @FrancescoMantovani you can read more about it here: [link](https://www.itprotoday.com/powershell/what-do-not-do-powershell-part-1) – Kristian Kanchev Jan 27 '19 at 12:06
4

I have tried copying your code and testing it, however I cannot make the actual Check_Program_Installed function work, so it is hard for me to validate.

However, for PowerShell it is important to understand the pipeline.

Normally with everything you do, it is send to the pipeline and will appear in your console in the order that the pipeline got it.

However Write-Host does not send your text to the pipeline, it sends it directly to the console, so it could be a simple race condition where the text gets to the console faster than the pipeline object.

If you try to test using Write-Output instead of Write-Host I would guess you get it in the correct order, since Write-Output sends an object to the console through the pipeline.