Columnize text in PowerShell

I am new to PowerShell (Bash is usually my thing) who is currently trying to get qwinsta output to show who is registered as rdpwd (rdesktop) user so that I can check each username for a list on behalf of the user and if they do not match, log out.

I am currently working on two issues:

  • I cannot split the qwinsta output, remaining only with the username - I tried the "split" function, but so far I get either syntax problems or strange results; It seems that one hand is that '\ s +' matches the letter S instead of a space; in other cases, I managed to split into the second column, but only the output from row 1 appears
  • Until I come, I feel that I will also have problems with the second step, namely: looping through an array of non-log-offable users (which should be obtained from the local user group)

Now I will focus on problem 1!

The text I have is:

SESSIONNAME       USERNAME        ID     STATE   TYPE      DEVICE
services                          0      Disc
console                           1      Conn
rdp-tcp#0         user.name1      2      Active  rdpwd
rdp-tcp#1         user.name2      3      Active  rdpwd
rdp-tcp#1         user.name3      4      Active  rdpwd
rdp-tcp                           65536  Listen

The output I want is:

user.name1
user.name2
user.name3

(For the purpose of creating a loop, in short, "foreach user in list, if not localgroup, logoff user".)

So far I have been getting to the text selection using "rdpwd", but using all sorts of "split" options, I have no further progress.

I am happy to share what I already have, but, alas, I do not think that this will help anyone!

Any help would be most appreciated. :)

+4
source share
11

, , ConvertFrom-Csv:

$(qwinsta.exe) -replace "^[\s>]" , "" -replace "\s+" , "," | ConvertFrom-Csv | select username

> , . ConvertFrom-Csv .

, , \s+, , , .

, , exe:

$o = @()
$op = $(qwinsta.exe)

$ma = $op[0] | Select-String "(?:[\s](\w+))" -AllMatches
$ErrorActionPreference = "Stop"

for($j=1; $j -lt $op.length; $j++) {
    $i = 0
    $obj = new-object pscustomobject
    while ($i -lt $ma.matches.count) { 
      $prop = $ma.matches[$i].groups[1].value; 
      $substrStart = $ma.matches[$i].index 
      $substrLen = $ma.matches[$i+1].index - $substrStart
      try {
        $obj | Add-Member $prop -notepropertyvalue $op[$j].substring($substrStart,$substrLen).trim() 
      }
      catch [ArgumentOutOfRangeException] {
        $substrLen = $op[$j].length - $substrStart 
        if($substrLen -gt 0) {
          $obj | Add-Member $prop -notepropertyvalue $op[$j].substring($substrStart,$substrLen).trim()
        }
        else {
          $obj | Add-Member $prop -notepropertyvalue ""
        }
      }
      $i++
    }
    $o += ,$obj
}

$o | ? { $_.type -eq 'rdpwd'} | select username

USERNAME
--------
user.name1
user.name2
user.name3
+3

, , string .split(). . Powershell -split :

(@'
SESSIONNAME       USERNAME        ID     STATE   TYPE      DEVICE
services                          0      Disc
console                           1      Conn
rdp-tcp#0         user.name1      2      Active  rdpwd
rdp-tcp#1         user.name2      3      Active  rdpwd
rdp-tcp#1         user.name3      4      Active  rdpwd
rdp-tcp                           65536  Liste
'@).split("`n") |
foreach {$_.trim()} | sv x


$x -match 'rdpwd' |
foreach { ($_ -split '\s+')[1] }

user.name1
user.name2
user.name3
+2

. , , , Arco, PowerShell. , $data , get-content, qwinsta.exe ($data = (qwinsta.exe) -split "`r`n", )

$headerString = $data[0]
$headerElements = $headerString -split "\s+" | Where-Object{$_}
$headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}

$results = $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    
    }
    [pscustomobject]$props
} 

$results | Select-Object sessionname,username,id,state,type,device | Format-Table -auto

. , . $headerIndexes, , , . , , , .

$results psobject. , .

SESSIONNAME USERNAME   ID    STATE  TYPE  DEVICE
----------- --------   --    -----  ----  ------
services               0     Disc               
console                1     Conn               
rdp-tcp#0   user.name1 2     Active rdpwd       
rdp-tcp#1   user.name2 3     Active rdpwd       
rdp-tcp#1   user.name3 4     Active rdpwd       
rdp-tcp                65536 Listen             

, type - rdpwd

$results | Where-Object{$_.type -eq "rdpwd"} | Select-Object -ExpandProperty username
+1

, , .

.

$Sessions=qwinsta.exe
$SessionCount=$Sessions.count
[int]$x=1
do
    {$x++
     if(($Sessions[$x]) -ne $null){$Sessions[$x].subString(19,21).Trim()}
    }until($x -eq $SessionCount)
0

, bash:

$ awk '$NF=="rdpwd"{print $2}' file 
user.name1
user.name2
user.name3

: , "powershell", awk, , "powershell" - , awk - .

0

[: , .]

:

# Get-SessionData.ps1
$sessionData = qwinsta
$headerRow = $sessionData | select-object -first 1
# Get column names
$colNames = $headerRow.Split(' ',[StringSplitOptions]::RemoveEmptyEntries)
# First column position is zero
$colPositions = @(0)
# Get remainder of column positions
$colPositions += $colNames | select-object -skip 1 | foreach-object {
  $headerRow.IndexOf($_)
}
$sessionData | select-object -skip 1 | foreach-object {
  # Create output object
  $output = new-object PSCustomObject
  # Create and populate properties for all except last column
  for ( $i = 0; $i -lt $colNames.Count - 1; $i++ ) {
    $output | add-member NoteProperty $colNames[$i] ($_[$($colPositions[$i])..$($colPositions[$i + 1] - 1)] -join "").Trim()
  }
  # Create property for last column
  $output | add-member NoteProperty $colNames[$colNames.Count - 1] ""
  # Remainder of text on line, if any, is last property
  if ( ($_.Length - 1) -gt ($colPositions[$colPositions.Count - 1]) ) {
    $output.$($colNames[$colNames.Count - 1]) = $_.Substring($colPositions[$colPositions.Count - 1]).Trim()
  }
  $output
}

, , ..

, , , TYPE rdpwd:

Get-SessionData | where-object { $_.TYPE -eq "rdpwd" } |
  select-object -expandproperty USERNAME

:

user.name1
user.name2
user.name3
0

explorer ? ( - , , ):

Get-WmiObject -ComputerName "Machine" -Class win32_process | Where-Object {$_.Name -match "explorer"} | ForEach-Object {($_.GetOwner()).User}

, .

0

Matt answer , ( , ). , , . , , , , , , , - .

function Convert-TextColumnsToObject([String]$data)
{
    $splitLinesOn=[Environment]::NewLine
    $columnPreproc="\s{2,}"
    $headerString = $data.Split($splitLinesOn) | select -f 1
    #Preprocess to handle headings with spaces
    $headerElements = ($headerString -replace "$columnPreproc", "|") -split "\|" | Where-Object{$_}
    $headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}
    $results = $data.Split($splitLinesOn) | 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    
        }
        [pscustomobject]$props
    }

    return $results
} 

:

$data= @"
    DRIVER              VOLUME NAME
    local               004e9c5f2ecf96345297965d3f98e24f7a6a69f5c848096e81f3d5ba4cb60f1e
    local               081211bd5d09c23f8ed60fe63386291a0cf452261b8be86fc154b431280c0c11
    local               112be82400a10456da2e721a07389f21b4e88744f64d9a1bd8ff2379f54a0d28
    "@ 

$obj=Convert-TextColumnsToObject $data
$obj | ?{ $_."VOLUME NAME" -match "112be" }
0

4,5 6 .

awk 'NR>3&&NR<7{print $2}' file

    user.name1
    user.name2
    user.name3
0

, , , () () .

PowerShell -split, , awk Unix:

Windows, awk, Gawk Windows, awk , . Unix ( PowerShell) awk.
Ed's, , .

qwinsta | % { if (($fields = -split $_)[4] -eq 'rdpwd') { $fields[1] } }
  • -split $_ ($_) , .

  • (...)[4] -eq 'rdpwd'checks the fifth field (as usual, indexes 0) for the value of interest.

  • In the case of a match, it $fields[1]then displays the second field, (assumed to be non-empty) username.

0
source

easy way

get a list of active users

$logonusers = qwinsta /server:ts33 | Out-String -Stream | Select-String "Active"

clears all information up, except for users, using the -replace command

$logonusers = $logonusers -replace("rdp-tcp") -replace("Active") -
replace("rdpwd") -replace("#") -replace '\s+', ' ' -replace '[0-9]',' '

$logonusers

then list all active users.

-1
source

All Articles