I've looked at many solutions online, but none relate to my specific situation. I have following PowerShell command output:
PS C:\Users\Administrator> Query User | Select-String "rdp"
>administrator rdp-tcp#7 2 Active . 4/28/2022 10:22 AM
If I were using bash, it would be a simple case of using awk to select the 2nd column (which is the one I require).
Can anyone help me with how I would achieve the same result in PowerShell?
CodePudding user response:
You may just use $ENV:SESSIONNAME
to get that string.
If you want to play with a bit of code to "emulate" awk, you can use
((Query User) -match 'rdp' -split '\s ')[1]
Note:
(Query User)
- The string returned byQuery User
...... -match 'rdp'
- is first matched withrdp
, and once the match is obtained,... -split '\s '
- it is split with one or more whitespaces.(...)[1]
- Then, the second item is returned using indexing,[1]
(since array indices are zero-based).
CodePudding user response:
Wiktor Stribiżew's answer provides an effective solution for a single matching line (which may be all that is needed in this case).
To generalize and elaborate on the AWK angle:
If fields need to be extracted from multiple lines, you need multiple calls to the
-split
operator.- It is the unary form, of
-split
, as used below, that behaves AWK-like with respect to field splitting, in that any nonempty run of whitespace separates fields, with leading and trailing whitespace getting ignored.
- It is the unary form, of
For processing multiple lines one by one, you can use the
switch
statement, which is AWK-inspired too.
The equivalent of this AWK command, which extracts the 2nd field from each line containing the string "rdp":
query user | awk '/rdp/ { print $2 }'
is this switch
statement:
switch -Regex (query user) { 'rdp' { (-split $_)[1] } }
Note:
0
-based array indexing applies in PowerShell, because the-split
operator returns an array of tokens; by contrast, AWK's field numbering start with$1
($0
representing the whole line). That is, field$2
in AWK corresponds to array index1
in PowerShell.Add
-CaseSensitive
if needed; PowerShell is case-INsensitive by default.
Optional reading: grep
vs. Select-String
:
Another Unix-utility solution option is to use grep
, as follows:
query user | grep -Eo '\brdp[^ ] '
PowerShell's grep
analog is Select-String
.
As of PowerShell 7.2.2, there is a pending, green-lighted future improvement to Select-String
that would allow returning just the matched part of matching lines, analogous to grep
's -o
; community members are welcome to implement it - see GitHub issue #7712.
# FUTURE improvement.
query user | Select-String -OnlyMatching '\brdp[^ ] '
For now, a more verbose solution is required:
query user | Select-String '\brdp[^ ] ' | ForEach-Object { $_.Matches.Value }