csv - How can I output all the output of a called command in Powershell script -
i have adapted existing powershell script query list of servers logged in (or disconnected) user sessions using quser /server:{servername}
, output results csv file. output logged in users doesn't capture servers had 0 users or weren't accessible (server offline, rpc not available, etc.). i'm assuming because these other conditions "errors" rather command output.
so if hits server no users outputs "no user exists *" in console running script. if hits server can't reach outputs "error 0x000006ba enumerating sessionnames" , on second line "error [1722]:the rpc server unavailable." in console running script. neither of these conditions show in output.csv file.
i wanted know if suggest how capture these conditions in csv "$computer has no users" , "$computer unreachable"
here script
$serverlist = read-host 'path 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 disconnected different fields 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 } }
anyone curious why i'm using convertto-csv
rather export-csv
cleaner, because servers i'm running running powershell 2.0 in export-csv doesn't support -append. i'm not concerned output works need, if has better suggestion feel free comment.
so have updates script. if there error using quser
capture special entry server name read "error contacting $computer"
, other text give context error..
$serverlist = read-host 'path 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 unavailable"} '*[5]*'{$hashprops.username = "access 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 disconnected different fields 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
part of issue since not powershell cmdlet capturing stderr in order parse needs work differnetly. playing $erroractionpreference
option first draft. use 2>&1
capture error $results
hide message screen. use if
see if last command succeeded.
in event of error
i used switch statement error text. can tailor output based on the text returned in $results
some minor changes
most of rest of code same. moved object creation outside if
statement errors logged , changed export-csv
powershell work out details of you.
unless intend have multiple passes of function on time want capture same file.
console output before export
servername username state logontime ---------- -------- ----- --------- serverthing01 bjoe active 4/9/2015 5:42 pm error contacting c4093 rpc server unavailable [1722] error contacting c4094 access denied [5]
you can see there output each server though last 2 had separate reasons not having proper output. if ever see "something else"
there error did not have specific message attached error.
when happens under state
, error number displayed. need update switch
accordingly.
significant update
i not sure issue dropping lines multiple users have dynamic parsing code positionally delimited text bringing in here.
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 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 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 unavailable"} '*[5]*'{$hashprops.username = "access 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
biggest difference here use convertfrom-positionaltext
parse details quser
. needed 0 out $hashprops = @{}
causing conflicting results across mutliple runs. measure got output of function , dummy error data have same parameter sets. used $exportedprops
has calculated expression have headers wanted.
new output
servername username state logontime ---------- -------- ----- --------- server01 user1 disc 3/12/2015 9:38 server01 user2 active 4/9/2015 5:42 pm error contacting 12345 access denied [5] error contacting 12345 rpc server 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