This PowerShell function will help Windows administrators use the output of “query user” or “quser” as a PowerShell array.
query user: raw output
“query user” or “quser” output in Windows looks like this:
1 2 3 | USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME username1 1 Disc 19:12 9/22/2023 8:38 AM username2 console 2 Active none 9/27/2023 3:51 PM |
This format is not very helpful for PowerShell. PowerShell admins would prefer this data to be an array.
Get-QUser: a PowserShell function
Using Trim() and Replace() I was able to easily convert the raw output to a comma-delimited format. But there is one pesky problem: Sometimes the value for SESSIONNAME is empty.
When SESSIONNAME is empty for a row, all of the data shifts one column to the left. My Get-QUser fuction attempts to find those rows and add in an empty space.
I also thought it would be helpful to add two columns with calculated values. I added IDLE_MINTUES and IDLE_HOURS.
Get-QUser: demo
Here’s the result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Get-QUser -Computer COMPUTERNAME USERNAME : username1 SESSIONNAME : ID : 1 STATE : Disc IDLE_TIME : 19:08 LOGON_TIME : 9/22/2023 8:38 AM IDLE_MINUTES : 1148 IDLE_HOURS : 19.13 USERNAME : username2 SESSIONNAME : console ID : 2 STATE : Active IDLE_TIME : none LOGON_TIME : 9/27/2023 3:51 PM IDLE_MINUTES : 0 IDLE_HOURS : 0 |
Get-QUser PowerShell Function
Here’s the funtion. I hope it helps.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | <# .SYNOPSIS A function to get the output of quser as a comma-separated array with additional calculated idle time. .DESCRIPTION This function runs quser on a specified computer (or the local computer if no computer name is provided), and returns the output as a comma-separated array. If quser doesn't output a value for SESSIONNAME, an extra comma is added to ensure each row has exactly six values. Additionally, it calculates idle time in minutes and hours. .PARAMETER ComputerName The name of the computer to run quser on. If no computer name is provided, the function defaults to the local computer. .EXAMPLE PS C:\> Get-QUser -ComputerName "RemoteComputerName" This command runs quser on the computer named "RemoteComputerName" and returns the output as a comma-separated array with additional calculated idle time. .EXAMPLE PS C:\> Get-QUser This command runs quser on the local computer and returns the output as a comma-separated array with additional calculated idle time. #> function Get-QUser { param ( [string]$ComputerName = $env:COMPUTERNAME ) # Get the raw output of quser $QuserRaw = Invoke-Command -ComputerName $ComputerName -ScriptBlock { quser } # Modify the output by making it comma delimited $QuserCSV = $QUserRaw.Trim().Replace(" ",",").Replace(", ",",").Replace(" ,",",").Replace(",,,,,",",").Replace(",,,,",",").Replace(",,,",",").Replace(",,",",") # Convert the CSV string to an array $QuserArray = $QuserCSV -split "`n" # Iterate over each row in the array to find any row with only five data values and add an extra comma for SESSIONNAME for ($i=0; $i -lt $QuserArray.Length; $i++) { # Count the number of commas in the row $commaCount = ([regex]::Matches($QuserArray[$i], ",")).Count # If there are only four commas, replace the first comma with two commas if ($commaCount -eq 4) { $firstCommaIndex = $QuserArray[$i].IndexOf(",") $QuserArray[$i] = $QuserArray[$i].Insert($firstCommaIndex + 1, ",") } } # Convert string array to CSV object and remove first row (header) $QuserArray = $QuserArray | ConvertFrom-Csv -Header "USERNAME","SESSIONNAME","ID","STATE","IDLE_TIME","LOGON_TIME" $QuserArray = $QuserArray | Select-Object -Skip 1 # Add IDLE_MINUTES and IDLE_HOURS columns foreach ($row in $QuserArray) { if ($row.IDLE_TIME -match "(\d+)\+(\d+):(\d+)") { # Format is days+hours:minutes $idleMinutes = [int]$matches[1]*24*60 + [int]$matches[2]*60 + [int]$matches[3] } elseif ($row.IDLE_TIME -match "(\d+):(\d+)") { # Format is hours:minutes $idleMinutes = [int]$matches[1]*60 + [int]$matches[2] } elseif ($row.IDLE_TIME -match "(\d+)") { # Format is minutes $idleMinutes = [int]$matches[1] } else { # Unknown format, set to 0 $idleMinutes = 0 } # Add calculated values to new columns $row | Add-Member -NotePropertyName IDLE_MINUTES -NotePropertyValue $idleMinutes $idleHours = [math]::Round($idleMinutes / 60, 2) $row | Add-Member -NotePropertyName IDLE_HOURS -NotePropertyValue $idleHours } # Output the corrected array with added columns return $QuserArray } |