我正在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
Run Code Online (Sandbox Code Playgroud)
当我调用getUsersAndGroupsafter时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:
Run Code Online (Sandbox Code Playgroud)
当我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 ------------
Run Code Online (Sandbox Code Playgroud)
非常感谢你的帮助!
tl; 医生:
通过显式使用格式化cmdlet 强制将同步输出输出到控制台:
getUsersAndGroups | Out-Host
getRunningProcesses | Out-Host
Run Code Online (Sandbox Code Playgroud)
注意:您也可以使用其中一个Format-*cmdlet,这也可以强制进行同步输出;否则,可以强制使用cmdlet。例如getUsersAndGroups | Format-Table。
请注意,这主要是一个显示问题,你就不会需要这个解决方法在文件中捕获输出或通过它在通过管道。
用MCVE(最小,完整和可验证的示例)演示问题会很有帮助:
Write-Host "-- before"
[pscustomobject] @{ one = 1; two = 2; three = 3 }
Write-Host "-- after"
Run Code Online (Sandbox Code Playgroud)
在PSv5 +中,将产生:
-- before
-- after
one two three
--- --- -----
1 2 3
Run Code Online (Sandbox Code Playgroud)
发生了什么?
在Write-Host呼叫产生的输出同步。
Write-Host绕过正常的成功输出流,并且(实际上)直接写入控制台- 大多数情况下,即使有合法的使用,Write-Host也应避免。该隐含的输出-从没有捕捉从语句的输出[pscustomobject] @{ one = 1; two = 2; three = 3 }-是出乎意料的不同步现象:
Write-Host通话。这个有用的答案说明了为什么会发生这种情况。简而言之:
隐式输出的格式取决于要输出的对象的类型。在眼前的情况下,Format-Table被隐式使用。
在Psv5 +中,隐式应用Format-Table现在最多等待 300毫秒。为了确定合适的列宽。
要测试具有全名的给定类型是否<FullTypeName>具有与其关联的表格式数据,可以使用以下命令:
# Outputs $true, if <FullTypeName> has predefined table-formatting data.
Get-FormatData <FullTypeName> -PowerShellVersion $PSVersionTable.PSVersion |
Where-Object {
$_.FormatViewDefinition.Control.ForEach('GetType') -contains [System.Management.Automation.TableControl]
}
Run Code Online (Sandbox Code Playgroud)不幸的是,这意味着随后的命令将在该时间窗口内执行,并且可能产生不相关的输出(通过绕行输出命令(例如Write-Host)),或者在 Format-Table输出开始之前提示用户输入。
注意:此答案最初错误地归咎于PSv5 + 300毫秒。延迟,可能会导致令人惊讶的标准输出格式设置行为(即,如果应用了表格格式,则发送到管道的第一个对象将确定管道中所有对象的显示格式-请参见此答案)。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |