簡體   English   中英

如何在Powershell腳本中輸出被調用命令的所有輸出

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM