powershell 脚本不会在“切换”菜单中运行

dced5bon  于 2023-01-17  发布在  Shell
关注(0)|答案(1)|浏览(166)
function Show-Menu { #Create the Show-Menu function
    param ([string]$Title = 'Functions') #Sets title
    Clear-Host
    Write-Host "`t6: Reboot History." -foregroundcolor white
    Write-Host "`tQ: Enter 'Q' to quit."
} #close of create show menu function

#Begin Main Menu
do
 {
    Show-Menu #Displays created menu above
    
    $Selection = $(Write-Host "`tMake your selection: " -foregroundcolor Red -nonewline; Read-Host)
    
    
    switch ($selection) #Begin switch selection
    {

#===Reboot History===
    '6' {
                $Workstation = $(Write-Host "Workstation\IP Address" -nonewline -foregroundcolor DarkGreen) + $(Write-Host "(Use IP for remote users)?: " -NoNewline; Read-Host)
                $DaysFromToday = Read-Host "How many days would you like to go back?"
                $MaxEvents = Read-Host "How many events would you like to view?"
                
                $EventList = Get-WinEvent -ComputerName $Workstation -FilterHashtable @{
                    Logname = 'system'
                    Id = '41', '1074', '1076', '6005', '6006', '6008', '6009', '6013'
                    StartTime = (Get-Date).AddDays(-$DaysFromToday)
                } -MaxEvents $MaxEvents -ErrorAction Stop
 
 
                foreach ($Event in $EventList) {

                    if ($Event.Id -eq 1074) {
                        [PSCustomObject]@{
                            TimeStamp    = $Event.TimeCreated
                            Event        = $Event.Id
                            ShutdownType = 'Restart'
                            UserName     = $Event.Properties.value[6]
                        }
                    }

                    if ($Event.Id -eq 41) {
                        [PSCustomObject]@{
                            TimeStamp    = $Event.TimeCreated
                            Event        = $Event.Id
                            ShutdownType = 'Unexpected'
                            UserName     = ' '
                        }
                    }
                }
                pause
        }
    }
    }
 until ($selection -eq 'q') #End of main menu

如果我从交换机中删除脚本并单独运行它,它会运行得非常好,但只要我从交换机调用它,它仍然会询问工作站/IP、天数和最大事件数,但只是什么也不输出。
下面是它工作时的样子:

How many days would you like to go back?: 90
How many events would you like to view?: 999

TimeStamp              Event ShutdownType UserName
---------              ----- ------------ --------
12/23/2022 12:20:55 AM  1074 Restart      Username
12/20/2022 1:00:01 AM   1074 Restart      Username
12/17/2022 12:21:54 AM  1074 Restart      Username
12/13/2022 8:57:40 AM   1074 Restart      Username

这是我在switch菜单中运行它时得到的结果

Workstation\IP Address(Use IP for remote users)?: IP Address
How many days would you like to go back?: 90
How many events would you like to view?: 999

Press Enter to continue...:

我试过只做1天和1个事件,但结果相同。没有错误或任何指示故障的东西,所以不知道如何排除故障。我过去遇到过类似的交换机问题,通过对作用域的研究解决了这些问题,但我不认为这是相同的情况,因为它完全包含在交换机本身中。
我很困惑,有什么想法吗?和往常一样,对我的剧本的任何见解都是非常感谢的,即使它不能解决手头的问题。

nfeuvbwi

nfeuvbwi1#

JosefZ提供了关键指针:

  • 强制 * synchronous * 显示输出,例如使用Out-Host
  • 如果您忽略了这样做,那么pause语句将-令人惊讶地-在foreach语句发出的[pscustomobject]示例之前 * 执行,这是由于隐式应用的Format-Table的异步行为-有关详细信息,请参见this answer

下面是一个简单的例子:

switch ('foo') {

  default {

    # Wrap the `foreach` statement in . { ... }, 
    # so its output can be piped to Out-Host. 
    . { 
      foreach ($i in 1..3) {
        [pscustomobject] @{ prop = $i } 
      }
    } |
      Out-Host # Without this, "pause" will run FIRST.
    pause

  }
}

注:

  • 对于Out-Host,要将所有输出 * 一起 * 格式化,它必须从foreach循环接收 * 所有 * 输出,作为单个管道的一部分。
  • 因为foreach是一个 * 语言语句 *(而不是 * 命令 *,如相关的ForEach-Object * cmdlet *),因此不能直接在pipeline的开头使用,上面将其 Package 在script block中({ ... }),通过.调用,点源运算符,它直接在调用者的上下文中执行脚本块,并将输出流式传输到管道。
  • 这个限制可能令人惊讶,但它植根于PowerShell语法的基础-参见GitHub issue #10967。
  • 一种不需要. { ... }解决方案的全管道替代方案是:
1..3 | 
  ForEach-Object {
    [pscustomobject] @{ prop = $_ }  # Note the automatic $_ var.
  } |
  Out-Host

相关问题