我正在Windows 10上的5.1版本中编写PowerShell脚本,该脚本获取有关本地系统(以及最终其子网)的某些信息,并将它们输出到文本文件中。起初,我在一个功能中拥有所有方面。输出getUsersAndGroups
和getRunningProcesses
函数时遇到了输出问题,getUsersAndGroups
的输出会被注入getRunningProcesses
的输出。
这两个功能是:
# Powershell script to get various properties and output to a text file
Function getRunningProcesses()
{
# Running processes
Write-Host "Running Processes:
------------ START PROCESS LIST ------------
"
Get-Process | Select-Object name,fileversion,productversion,company
Write-Host "
------------- END PROCESS LIST -------------
"
}
Function getUsersAndGroups()
{
# Get Users and Groups
Write-Host "Users and Groups:"
$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
$adsi.Children | where {$_.SchemaClassName -eq 'user'} | Foreach-Object {
$groups = $_.Groups() | Foreach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$_ | Select-Object @{n='Username';e={$_.Name}},@{n='Group';e={$groups -join ';'}}
}
}
getRunningProcesses
getUsersAndGroups
当我在getUsersAndGroups
之后调用getRunningProcesses
时,输出看起来像这样(根本不输出getUsersAndGroups
):
Running Processes:
------------ START PROCESS LIST ------------
Name FileVersion ProductVersion Company
---- ----------- -------------- -------
armsvc
aswidsagenta
audiodg
AVGSvc
avgsvca
avguix 1.182.2.64574 1.182.2.64574 AVG Technologies CZ, s.r.o.
conhost 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
csrss
csrss
dasHost
dwm
explorer 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
hkcmd 8.15.10.2900 8.15.10.2900 Intel Corporation
Idle
igfxpers 8.15.10.2900 8.15.10.2900 Intel Corporation
lsass
MBAMService
mDNSResponder
Memory Compression
powershell_ise 10.0.14393.103 (rs1_release_inmarket.160819-1924) 10.0.14393.103 Microsoft Corporation
RuntimeBroker 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
SearchFilterHost
SearchIndexer
SearchProtocolHost
SearchUI 10.0.14393.953 (rs1_release_inmarket.170303-1614) 10.0.14393.953 Microsoft Corporation
services
ShellExperienceHost 10.0.14393.447 (rs1_release_inmarket.161102-0100) 10.0.14393.447 Microsoft Corporation
sihost 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
smss
spoolsv
sqlwriter
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost
svchost 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
System
taskhostw 10.0.14393.0 (rs1_release.160715-1616) 10.0.14393.0 Microsoft Corporation
ToolbarUpdater
wininit
winlogon
WtuSystemSupport
WUDFHost
------------ END PROCESS LIST ------------
Users and Groups:
当我在getUsersAndGroups
之前调用getRunningProcesses
时,getUsersAndGroups
的输出被注入getRunningProcesses
,更糟糕的是,根本没有列出正在运行的进程,而是大量空白线。
如何分隔或控制getUsersAndGroups
的输出,使其在getRunningProcesses
的输出之前输出?
注入输出的输出如下所示:
Running Processes:
------------ START PROCESS LIST ------------
Username Group
-------- -----
Administrator Administrators
debug255 Administrators;Hyper-V Administrators;Performance Log Users
DefaultAccount System Managed Accounts Group
Guest Guests
------------ END PROCESS LIST ------------
非常感谢你的帮助!
答案 0 :(得分:4)
<强> TL; DR:强>
使用格式化cmdlet 显式强制同步输出到控制台:
getUsersAndGroups | Format-Table
getRunningProcesses | Format-Table
请注意,这主要是 display 问题,而不需要此解决方法来捕获文件中的输出或通过管道传递它。
使用MCVE (Minimal, Complete, and Verifiable Example)
来演示问题很有帮助Write-Host "-- before"
[pscustomobject] @{ one = 1; two = 2; three = 3 }
Write-Host "-- after"
在PSv5 +中,这会产生:
-- before
-- after
one two three
--- --- -----
1 2 3
发生了什么事?
Write-Host
次调用同步生成输出 。
Write-Host
绕过正常的成功输出流并且(实际上)直接写入控制台 - mostly, even though there are legitimate uses, Write-Host
should be avoided。 隐式输出 - 从未捕获语句[pscustomobject] @{ one = 1; two = 2; three = 3 }
的输出 - 意外地不同步:
Write-Host
来电。This helpful answer解释了为什么会发生这种情况;简而言之:
隐式输出的格式基于输出的对象类型;在这种情况下,Format-Table
被隐式使用。
在 Psv5 + 中, 隐式已应用Format-Table
现在等待最多300 msecs。为了确定合适的色谱柱宽度。
不幸的是,这意味着后续命令在该时间窗口内执行,并可能产生不相关的输出(通过管道 - 绕过输出命令,如Write-Host
)或提示在 Format-Table
输出开始之前输入用户。
注意:这个答案最初错误地“归咎于”PSv5 + 300毫秒。延迟可能令人惊讶的标准输出格式化行为(发送到管道的第一个对象确定管道中所有对象的显示格式 - 请参阅我的this answer。