【问题标题】:Why my PowerShell script is not respecting the steps order? [duplicate]为什么我的 PowerShell 脚本不遵守步骤顺序? [复制]
【发布时间】:2019-06-18 01:39:40
【问题描述】:

我试图自己找到解决方案,但现在我没有想法。我写了一个脚本,我想用它来检查机器上是否安装了 Erlang:

# 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

但如果我执行它作为结果,最后一行将在Check_Program_Installed("Erlang") 之前执行。为什么 PowerShell 不尊重步骤优先级?

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

【问题讨论】:

  • 与您的问题无关,但您将 x86/x64 混淆了,这可能是进一步的潜在问题。
  • @notjustme 是对的:$x86_check -and $x64_check -eq $null 返回 true 如果程序安装为 32 位(而不是 64 位)但是函数返回(错误)“$programName 未安装在这台计算机上”。阅读Know your operator and enclosure precedence

标签: powershell scripting automation


【解决方案1】:

只需将 Format-Table 添加到 $x86_check 和 $64_check 最后。回答链接:https://social.technet.microsoft.com/Forums/en-US/5f88f7c9-fbce-4c45-a2fa-806d512a0233/powershell-output-wrong-order?forum=ITCG

# 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

【讨论】:

  • 嗨@Kristian Kanchev,为什么Format-Table 解决了这个问题?
  • 您好@FrancescoMantovani,Write-Host 是唯一直接写入控制台窗口而不是管道的本机 PowerShell 输出 cmdlet。我必须做一些阅读才能自己理解。我的逻辑是默认情况下您的脚本将信息提供为Format-Table,因此这将进入管道,因为Write-Host 没有,它忽略了这些步骤。但是,如果您将 Format-Table 放入脚本中并且默认情况下不使用它,它会将其输出到 cmdlet 而不仅仅是管道,从而使 Write-Host 遵循脚本中的步骤。但这是我发现的逻辑。
  • 除了@FrancescoMantovani,您还可以在这里阅读更多相关信息:link
【解决方案2】:

我已尝试复制您的代码并对其进行测试,但是我无法使实际的 Check_Program_Installed 函数工作,因此我很难验证。

但是,对于 PowerShell,了解管道很重要。

通常,您所做的所有事情都会发送到管道,并按照管道获取它的顺序出现在您的控制台中。

但是,Write-Host 不会将您的文本发送到管道,而是将其直接发送到控制台,因此这可能是一个简单的竞争条件,文本比管道对象更快地到达控制台。

如果您尝试使用Write-Output 而不是Write-Host 进行测试,我猜您会以正确的顺序得到它,因为Write-Output 通过管道将对象发送到控制台。

【讨论】:

  • 你说的对我来说是有道理的,但是 Kristian Kanchev 编写了有效的代码。谢谢
猜你喜欢
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
相关资源
最近更新 更多