![](/img/trans.png)
[英]"echo on" in powershell or how do I make Powershell output the command lines of all the commands, INCLUDING the native ones invoked by the script?
[英]How can I output all the output of a called command in Powershell script
我已經修改了現有的Powershell腳本,以使用quser /server:{servername}
查詢服務器列表中已登錄(或斷開連接)的用戶會話,並將結果輸出到CSV文件中。 它確實會輸出所有已登錄的用戶,但不會捕獲具有0個用戶或不可訪問的服務器(服務器脫機,rpc不可用等)。 我假設這是因為這些其他條件是“錯誤”,而不是命令輸出。
因此,如果命中沒有用戶的服務器,它將在運行腳本的控制台中輸出“ *沒有用戶存在”。 如果遇到無法訪問的服務器,則會輸出“錯誤0x000006BA枚舉會話名稱”,並在第二行顯示“錯誤[1722]:RPC服務器不可用”。 在運行腳本的控制台中。 因此,這些條件都不會顯示在output.csv文件中。
我想知道是否有人可以建議我如何在CSV中捕獲這些條件,因為“ $ Computer沒有用戶”和“ $ Computer無法訪問”
這是腳本
$ServerList = Read-Host 'Path to Server List?'
$ComputerName = Get-Content -Path $ServerList
foreach ($Computer in $ComputerName) {
quser /server:$Computer | Select-Object -Skip 1 | ForEach-Object {
$CurrentLine = $_.Trim() -Replace '\s+',' ' -Split '\s'
$HashProps = @{
UserName = $CurrentLine[0]
ServerName = $Computer
}
# If session is disconnected different fields will be selected
if ($CurrentLine[2] -eq 'Disc') {
$HashProps.SessionName = $null
$HashProps.Id = $CurrentLine[1]
$HashProps.State = $CurrentLine[2]
$HashProps.IdleTime = $CurrentLine[3]
$HashProps.LogonTime = $CurrentLine[4..6] -join ' '
} else {
$HashProps.SessionName = $CurrentLine[1]
$HashProps.Id = $CurrentLine[2]
$HashProps.State = $CurrentLine[3]
$HashProps.IdleTime = $CurrentLine[4]
$HashProps.LogonTime = $CurrentLine[5..7] -join ' '
}
New-Object -TypeName PSCustomObject -Property $HashProps |
Select-Object -Property ServerName,UserName,State,LogonTime |
ConvertTo-Csv -NoTypeInformation | select -Skip 1 | Out-File -Append .\output.csv
}
}
有人好奇為什么我使用的是ConvertTo-CSV
而不是Export-CSV
,這會更干凈,因為我從中運行此服務器的服務器運行的是Powershell 2.0,而Export-CSV不支持-Append。 我並不擔心輸出會滿足我的需求,但是如果有人對此有更好的建議,請隨時發表評論。
因此,我們對該腳本進行了一些更新。 如果使用quser
發生任何錯誤,我們會將其捕獲為特殊條目,其中服務器名稱將顯示為"Error contacting $computer"
和其他將為錯誤提供上下文的文本。
$ServerList = Read-Host 'Path to Server List?'
$ComputerNames = Get-Content -Path $ServerList
$ComputerNames | ForEach-Object{
$computer = $_
$results = quser /server:$Computer 2>&1 | Write-Output
If($LASTEXITCODE -ne 0){
$HashProps = @{
UserName = ""
ServerName = "Error contacting $computer"
SessionName = ""
Id = ""
State = $results | Select-String -Pattern '\[.+?\]' | Select -ExpandProperty Matches | Select -ExpandProperty Value
IdleTime = ""
LogonTime = ""
}
switch -Wildcard ($results){
'*[1722]*'{$HashProps.UserName = "RPC server is unavailable"}
'*[5]*'{$HashProps.UserName = "Access is denied"}
default{$HashProps.UserName = "Something else"}
}
} Else {
$results | Select-Object -Skip 1 | ForEach-Object {
$CurrentLine = $_.Trim() -Replace '\s+',' ' -Split '\s'
$HashProps = @{
UserName = $CurrentLine[0]
ServerName = $Computer
}
# If session is disconnected different fields will be selected
if ($CurrentLine[2] -eq 'Disc') {
$HashProps.SessionName = $null
$HashProps.Id = $CurrentLine[1]
$HashProps.State = $CurrentLine[2]
$HashProps.IdleTime = $CurrentLine[3]
$HashProps.LogonTime = $CurrentLine[4..6] -join ' '
} else {
$HashProps.SessionName = $CurrentLine[1]
$HashProps.Id = $CurrentLine[2]
$HashProps.State = $CurrentLine[3]
$HashProps.IdleTime = $CurrentLine[4]
$HashProps.LogonTime = $CurrentLine[5..7] -join ' '
}
}
}
New-Object -TypeName PSCustomObject -Property $HashProps
} | Select-Object -Property ServerName,UserName,State,LogonTime |
Export-Csv -NoTypeInformation .\output.csv
問題的部分原因在於,由於這不是捕獲stderr的PowerShell cmdlet才能解析它,因此需要以不同方式工作。 也可以選擇使用$erroractionpreference
進行操作,但這是初稿。 我們使用2>&1
將錯誤捕獲到$results
以從屏幕上隱藏消息。 然后,我們使用If
來查看最后一個命令是否成功。
發生錯誤時
我在錯誤文本中使用了switch語句。 因此,您可以根據$results
返回的文本來定制輸出
一些小的變化
您其余的大多數代碼都是相同的。 我將對象創建移至If
語句之外,以便可以記錄錯誤並將其更改為Export-CSV
因為PowerShell將為您解決該問題的詳細信息。
除非您打算隨着時間的推移多次傳遞此功能,否則您想捕獲到同一文件中。
導出前的控制台輸出
ServerName UserName State LogonTime
---------- -------- ----- ---------
serverthing01 bjoe Active 4/9/2015 5:42 PM
Error contacting c4093 RPC server is unavailable [1722]
Error contacting c4094 Access is denied [5]
您可以看到每個服務器都有輸出,即使最后兩個有沒有正確輸出的單獨原因。 如果您看到"Something else"
,則表示該錯誤沒有附加特定的消息。
發生這種情況時,請查看“ State
下的內容,並顯示錯誤號。 然后,您只需要相應地更新Switch
。
我不知道要為多個用戶刪除多余的行的問題是什么,但是我已經有了用於位置分隔文本的動態解析代碼,因此將其引入此處。
Function ConvertFrom-PositionalText{
param(
[Parameter(Mandatory=$true)]
[string[]]$data
)
$headerString = $data[0]
$headerElements = $headerString -split "\s+" | Where-Object{$_}
$headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}
$data | Select-Object -Skip 1 | ForEach-Object{
$props = @{}
$line = $_
For($indexStep = 0; $indexStep -le $headerIndexes.Count - 1; $indexStep++){
$value = $null # Assume a null value
$valueLength = $headerIndexes[$indexStep + 1] - $headerIndexes[$indexStep]
$valueStart = $headerIndexes[$indexStep]
If(($valueLength -gt 0) -and (($valueStart + $valueLength) -lt $line.Length)){
$value = ($line.Substring($valueStart,$valueLength)).Trim()
} ElseIf ($valueStart -lt $line.Length){
$value = ($line.Substring($valueStart)).Trim()
}
$props.($headerElements[$indexStep]) = $value
}
New-Object -TypeName PSCustomObject -Property $props
}
}
$ServerList = Read-Host 'Path to Server List?'
$ComputerNames = Get-Content -Path $ServerList
$HashProps = @{}
$exportedprops = "ServerName","UserName","State",@{Label="LogonTime";Expression={$_.Logon}}
$ComputerNames | ForEach-Object{
$computer = $_
$results = quser /server:$Computer 2>&1 | Write-Output
If($LASTEXITCODE -ne 0){
$HashProps = @{
UserName = ""
ServerName = "Error contacting $computer"
SessionName = ""
Id = ""
State = $results | Select-String -Pattern '\[.+?\]' | Select -ExpandProperty Matches | Select -ExpandProperty Value
Idle = ""
Time = ""
Logon = ""
}
switch -Wildcard ($results){
'*[1722]*'{$HashProps.UserName = "RPC server is unavailable"}
'*[5]*'{$HashProps.UserName = "Access is denied"}
default{$HashProps.UserName = "Something else"}
}
New-Object -TypeName PSCustomObject -Property $HashProps
} Else {
ConvertFrom-PositionalText -data $results | Add-Member -MemberType NoteProperty -Name "ServerName" -Value $computer -PassThru
}
} | Select-Object -Property $exportedprops |
Export-Csv -NoTypeInformation .\output.csv
這里最大的區別是我們使用ConvertFrom-PositionalText
解析quser
的詳細信息。 需要將$HashProps = @{}
歸零,這會導致多個遍歷運行之間產生沖突的結果。 總體而言,該函數的輸出和偽錯誤數據具有相同的參數集。 使用$exportedprops
具有計算表達式的$exportedprops
,以便您可以擁有所需的標頭。
新輸出
ServerName USERNAME STATE LogonTime
---------- -------- ----- ---------
server01 user1 Disc 3/12/2015 9:38 AM
server01 user2 Active 4/9/2015 5:42 PM
Error contacting 12345 Access is denied [5]
Error contacting 12345 RPC server is unavailable [1722]
svrThg1 user3 Active 4/9/2015 5:28 PM
svrThg1 user4 Active 4/9/2015 5:58 PM
svrThg1 user-1 Active 4/9/2015 9:50 PM
svrThg1 bjoe Active 4/9/2015 10:01 PM
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.