0

I have this PowerShell script that logs off users with IDLE time greater that 1 hour:

#Force script to run.
Set-ExecutionPolicy Unrestricted -force
#Check connected users and save output.
quser|out-file C:\Users\Administrator\Documents\disconectAgora\quser.txt
#Read output with logged in users.
$file = Get-Content C:\Users\Administrator\Documents\disconectAgora\quser.txt

#Obtain IDLE time by using patters.
$pattern = "Disc(.*?)11"
#Obtaons session ID by using patther.
$pattern2 = "adminagora(.*?)Disc"


#Execute query using above patterns.
$result = [regex]::Match($file,$pattern).Groups[1].Value
$result2 = [regex]::Match($file,$pattern2).Groups[1].Value

#Trim file and save both session id and username.

$result = $result -replace(' ','')
$result |out-file C:\Users\Administrator\Documents\disconectAgora\getDCUser.txt

$result2 = $result2 -replace(' ','')
$result2 |out-file C:\Users\Administrator\Documents\disconectAgora\getDCUserID.txt

#If IDLE time is greater than 1 hour user is disconnected.
if ($result -gt '1:00'){    
    logoff $result2
    }
else{
    write-host "No users with IDLE time greater than 1 hour found.No users to be logged off."
    }

What I want to do is check if a cmd process is running or not, so the user can remain logged on untill this process has ended.

I tought that maybe by running this command get-process | where-object {$_.mainwindowhandle -ne 0} | select-object name, mainwindowtitle and using regex to get only cmd processes it might do the trick, but it is a very primitive approach.

If you guys have any clue as to how to go about doing this, please let me know.

As requested, here's the output of quser:

enter image description here

Long story short

I need a way to know if something is being executed by CMD other than checking the CPU usage:

enter image description here

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138

2 Answers2

1

To get cmd processes just run get-process -name cmd

To find any child processes within cmd you could use something like this:

Get-WmiObject win32_process | where {$_.ParentProcessId -eq ((Get-Process -name cmd).id)}

Upd. As @LievenKeersmaekers has noticed this could not work in case of several cmds running simultaneously. Fixed version:

(Get-Process -name cmd).id | foreach { Get-WmiObject win32_process -filter "ParentProcessId='$_'"}
montonero
  • 1,363
  • 10
  • 16
  • Yes, that helps but in essence what I want is some datathat lets me know if something is running on cmd. I could use the CPU usage as a reference, but I dont think is a reliable marker. – Jorge Luís Segura Oñate Dec 27 '18 at 12:15
  • It depends on what is exactly executed within cmd. In a general case it could be only done by a trial and error. – montonero Dec 27 '18 at 12:36
  • You could also find child processes of cmd. This could be a slight evidence that something is executing within cmd. – montonero Dec 27 '18 at 12:44
  • Note that this is not foolproof. If you have two or more `cmd` processes running and a busy child process on another than the first `cmd`, this will not return a result. – Lieven Keersmaekers Dec 27 '18 at 15:27
  • This will also not detect a cmd that by itself is running some code but your definition of a running process on `cmd` is not clear. What do you consider a running process? Because after all, every process returned by Get-Process is running. – Lieven Keersmaekers Dec 27 '18 at 15:29
  • 1
    @LievenKeersmaekers Thanks for noticing, I've made a change that should detect child processes for all running cmds. Regarding some code that is running by cmd itself - there's not much internal cmd commands that could take any significant time. – montonero Dec 28 '18 at 07:05
1

Following is a bit simplified and returns the users, other than adminagora, that have disconnected sessions for over an hour

(& quser) -split "`n" | ? {$_ -match "(?<!adminagora).*?Disc\s+\d:\d{2}"}

breakdown

(& quser) -split "`n"  -- Executes quser 
                          Splits each line on newline to pass through the pipeline
? {$_ -match           -- Where the current item matches the regex
(?<!adminagora)        -- Use a negative lookbehind to exclude adminagora
.*?Disc                -- match any characters as few times as possible up until Disc. 
\s+\d:\d{2}            -- match any space character followed by
                       -- a digit, a colon and two digits
Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
  • Wow, that does indeed simplify my script. But the main thing is how i determine if something is running on cmd, I could guide me thru the CPU usage, but I'm not to keen on that. – Jorge Luís Segura Oñate Dec 27 '18 at 12:18