脚本无法在"切换"菜单中运行


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 "WorkstationIP 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

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

WorkstationIP 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...: 

我试过只做一天和一项活动,但结果是一样的。没有错误或任何指示故障的内容,因此不确定如何对此进行故障排除。我过去也遇到过类似的交换机问题,通过对作用域的一些研究解决了这些问题,但我不认为这是同一种情况,因为它完全包含在交换机本身中。

我不知所措,有什么想法吗?和往常一样,我们非常感谢对我的脚本的任何深入了解,即使它不能解决手头的问题。

JosefZ提供了关键指针:

  • 强制同步以显示输出,例如使用Out-Host

  • 如果忽略了这一点,pause语句将出人意料地在foreach语句发出的[pscustomobject]实例之前执行,这是由于隐式应用的Format-Table格式的异步行为-有关详细信息,请参阅此答案。

这里有一个简化的例子:

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-Objectcmdlet),因此无法在管道开始时直接使用,因此上面将其封装在脚本块({ ... })中,该脚本块通过点源运算符.调用,其直接在调用方的上下文中执行脚本块,并将输出流式传输到管道。

    • 这个限制可能令人惊讶,但它植根于PowerShell语法的基础-请参阅GitHub问题#10967。

    • 不需要. { ... }解决方案的全管道替代方案是:

      1..3 | 
      ForEach-Object {
      [pscustomobject] @{ prop = $_ }  # Note the automatic $_ var.
      } |
      Out-Host 
      

最新更新