我该如何输出所有的PowerShell脚本名为命令的输出(How can I output all

2019-10-22 14:25发布

我已经适应现有Powershell的脚本来查询使用服务器进行登录(或断开连接)的用户会话的列表quser /server:{servername}并输出结果到CSV文件中。 它输出的任何登录的用户,但它并没有捕捉到的是,有0个用户或不访问服务器(服务器脱机,RPC不可用等)。 我假设是因为这些其他条件的“错误”,而不是命令的输出。

所以,如果它击中的服务器没有它的用​​户在输出运行脚本的控制台“没有用户存在*”。 如果它击中它不能达到一个服务器输出“错误0x000006BA列举sessionnames”和在第二行的“错误[1722]:RPC服务器是不可用”。 在控制台中运行该脚本。 所以,这两个条件都不显示在output.csv文件。

我想知道,如果有人可以建议我怎么也捕捉到CSV这些条件为“$电脑有没有用户”和“$电脑无法接通”

这里是脚本

$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中的服务器,其中出口为CSV不支持-append。 我不担心因为输出作品我需要什么,但如果有人有更好的建议,这个随意评论。

Answer 1:

因此,我们有一些更新的脚本。 如果有任何错误使用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 

这个问题的部分原因是,因为这不是一个PowerShell命令,以捕获标准错误解析它需要differnetly工作。 与玩$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其中有一个计算表达式,这样你可以有你想要的标题。

新建输出

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


文章来源: How can I output all the output of a called command in Powershell script