I'm a PowerShell novice (Bash is my thing normally) who's currently trying to obtain qwinsta output to show who is logged in as an 'rdpwd' (rdesktop) user so that I can check each username against a list of usernames, and if they do not match, log them off.
I am currently working through two problems:
I'll focus on problem 1 for now!
The text I've got 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
(With the aim of then creating a loop that says, in brief terms, "foreach user in list, if not in localgroup, logoff user".)
So far, I've got as far as selecting text with 'rdpwd', but using all manner of variations on "split", I have not got further forward than that.
I'm happy to share what I've got already, but alas I don't think it'll help anyone!
Any assistance would be most appreciated. :)
Honestly I'd look up a better way to do this, but you can fudge it with some text manipulation and the ConvertFrom-Csv
cmdlet:
$(qwinsta.exe) -replace "^[\s>]" , "" -replace "\s+" , "," | ConvertFrom-Csv | select username
Firstly replace any leading spaces or >
characters with nothing, then replace any white spaces with a comma. Then you can pipe to ConvertFrom-Csv
and work with the data as an object.
Actually, the above has some issues, mostly with the \s+
because if a column is blank it does not get correctly recognised as a blank field, and the next text is incorrectly promoted to the current field.
The below is a full blown parser for this command, and would probably work for any sort of tabulated output from a native windows 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
Can't tell for sure, but it sounds like you're trying to do a regex split using the string .split()
method. That doesn't work. Use the Powershell -split
operator to do a regex 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With