Get the Handle Count of a process

i am running the following to get the HandleCount of a process (cmd.exe) and need a way to test what is returned (typically 2 or 3 entries). how can i test the result of this query:

Get-Process cmd | Format-List HandleCount

i need this to test to see if cmd.exe is running a powershell window with a particular handle count (in my case it is 80).

if the process doesn’t return a HandleCount of 80, then i need it to run the powershell script.

note that i have two task scheduler tasks, one for login and one for unlock. it is the unlock task that is failing because it needs more info about the cmd processes.

i did try this but i can’t get the logic to work, fyi, new to powershell. so sure it is something simple.

$Processes = Get-WMIObject -Class Win32_Process -Filter "Name='cmd.exe'" 

If $Processes.Count = 3 Then  
    EXIT
End If

but that is too basic of an If statment, needs to be more like
If $Processes.HandleCount = 80 then Exit

how can i get this to work?

DAN,
Welcome to the forum. :wave:t4:

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org <---- Click :point_up_2:t4: :wink:

You should always read the help for the cmdlets you’re about to use completely including the examples to learn how to use them.

In PowerShell the equal sign (=) is the assignment operator. :point_up_2:t4: :wink: … not acomparison operator.

Format cmdlets are only for display purposses in the console. You should not use them if you want to use the output for further steps. :point_up_2:t4:

I actually did not get what you want to achieve. Do you like to check for 80 or for 3 and why would you like to exit the script if you find it?

responding in order of comments
thanks for the preformat solution.
i did read the cmdlet for Get-Process, not sure of the If though. will pay more attention to that in the future
good to know about the equal sign. so i should substitute -eq for = then?
if i want to use the output for further steps (like getting the HandleCount of the cmd.exe process, how would i do that?
so i ran the Get-Process script and found out that there were two cmd.exe processes running. after reading the output of Format-List *, i realized that the cmd.exe process that was running a powershell script had a handle count of 80. (initially i was testing for process.count but needed to dive deeper to get the correct result). so abandoning the Count for HandleCount. since it is returning two processes, i need to test for the presence of the ps script. if it is found, then i need to exit the ps script and not run the rest of the commands (meaning the correct ps script is currently running, so don’t run another).

Basically i have two task scheduler tasks running. one is for the initial log on. that runs the script that monitors a folder (the one with purchase orders in it) and does an action whenever a file is created in the folder. then sometimes i lock my machine (or it times out) when i leave for awhile. if i unload, then test for cmd.exe with handle count of 80. if it finds that process running, then exit the ps script and don’t fun any further ciommands.

is this helpful in getting a variable to return a value?

hmmm … not really … actually that raises more questions … :smirk:

Why are you using CMD to run a PowerShell script?

And what’s the second one?

It depends pretty much what you want to do with the output. You could filter it with a

for example and do further steps with the filtered objects.

You may describe what you actually want to do - not the way you think you should go … the big picture … There could be a better way. :wink:

so i have made changes to two cmd files and two ps1 files and it all works.

for the big picture, i need a way during initial log in and unlock to make sure that a powershell script is running. never know when my cmd window will close (either accidently or on purpose) so need to make sure that the script is always running.

my log in script just runs a powershell command. nothing fancy there. now my unlock script has all the logic in it to make sure that if the process is NOT running, then run it. i had to do that cause when i lock the computer, and then unlock it later, it was running the powershell script twice and not knowing that. so made a batch file to list all the cmd.exe processes (in a text file) and then another batch file to count the numbers of lines that are in the first txt file (in a text file) that contain a string. once the second file has the line count, then the unlock powershell script gets the last character of the second text file and sets that to a variable. Then i can check the variable and if not at a certain value, then it runs the the rest of the script (which just runs powershell).

the question that i have is: can this be done a better way?

I am prettys sure about this. :smirk:

But you still did not tell what you’re actually trying to do. You still tell about some arbitrary CMD files and PowerShell scripts without telling what those scripts do. And I am pretty sure that you’re overcomplicating this task very much.

If it’s not top secret or illegal I’d like to encourage you to share your scripts here (formatted as code please)

Wihtout seeing them I’d think since it is pretty unlikely that a CMD/Batch script cannot do what a PowerShell script can do. So I’d try to get rid of these CMD/Batch scripts first. Usulally that simplifies a task. :point_up_2:t4:

i will post all code below. but question is how to call a powershell script from either a login or unlock task scheduler event? don’t know how to do that other than cmd file.

here are the two cmd files
first is startupLogin.cmd, the TS runs this on initial login

@echo off
PowerShell -Command "Set-ExecutionPolicy Unrestricted CurrentUser" 
PowerShell StartMonitoring2.ps1

second is startupLock.cmd, this fires when the computer is unlocked

@echo off
REM go through tasklist and find all the cmd.exe and put in file
tasklist /v /fo csv | findstr /i "cmd.exe" > cmd.txt
REM put the running total in a file
find /c "cmd.exe" cmd.txt > LinesInCmdTxt.txt
REM run powershell which will read LinesInCmdTxt.txt and return the last character of line 2 (this tells how many lines are in it)
PowerShell -Command "Set-ExecutionPolicy Unrestricted CurrentUser" 
PowerShell StartMonitoring3.ps1

now the ps1 files,
first is StartMonitoring2.ps1

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = ""
    $watcher.Filter = ""
    $watcher.IncludeSubdirectories = $false
    $watcher.EnableRaisingEvents = $true  

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $action = { $Path = $Event.SourceEventArgs.FullPath
                $Filename = $Event.SourceEventArgs.Name
                $Attachment = $Event.SourceEventArgs.FullPath
                $To = ''
                $From = ''
                $TestTo = ''
                $Bcc = ''
                $Message1 = ' '
                $Message2 = ' '
                $BodyMsg = $Message1+$Filename
                $BodyAsHtml = ''
                $Priority = 'High'
                $SubjectLine = $Message2+$Filename
                $secpasswd = ConvertTo-SecureString "" -AsPlainText -Force
                $cred = New-Object System.Management.Automation.PSCredential ($From, $secpasswd)
                Send-MailMessage -SmtpServer smtp.yourserver.com -Credential $cred -UseSsl -From $From -To $TestTo -BodyAsHtml $BodyAsHtml -Subject $SubjectLine -Attachment $Attachment 
                
              }    

### DECIDE WHICH EVENTS SHOULD BE WATCHED 
    Register-ObjectEvent $watcher "Created" -Action $action
    while ($true) {sleep 5}

and the lock ps1 - StartMonitoring3.ps1

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = ""
    $watcher.Filter = ""
    $watcher.IncludeSubdirectories = $false
    $watcher.EnableRaisingEvents = $true  

    $content = Get-Content LinesInCmdTxt.txt
    $DataLine = $content[1]

### if you will have more than 9 cmd's running then change
### ($DataLine.Get_Length()-1) to ($DataLine.Get_Length()-2)
    $DataLine = $DataLine.Substring($DataLine.Get_Length()-1)

    If ($DataLine -gt 1){EXIT}

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $action = { $Path = $Event.SourceEventArgs.FullPath
                $Filename = $Event.SourceEventArgs.Name
                $Attachment = $Event.SourceEventArgs.FullPath
                $To = ''
                $From = ''
                $TestTo = ''
                $Bcc = ''
                $Message1 = ' '
                $Message2 = ' '
                $BodyMsg = $Message1+$Filename
                $BodyAsHtml = ''
                $Priority = 'High'
                $SubjectLine = $Message2+$Filename
                $secpasswd = ConvertTo-SecureString "" -AsPlainText -Force
                $cred = New-Object System.Management.Automation.PSCredential ($From, $secpasswd)
                Send-MailMessage -SmtpServer smtp.yourserver.com -Credential $cred -UseSsl -From $From -To $TestTo -BodyAsHtml $BodyAsHtml -Subject $SubjectLine -Attachment $Attachment 
                
              }    

### DECIDE WHICH EVENTS SHOULD BE WATCHED 
    Register-ObjectEvent $watcher "Created" -Action $action
    while ($true) {sleep 5}

you will have to fill in all the smtp info to test but this is what is working on my computer at work. so add two tasks to the scheduler, one for login, one for unlock and you should see the same results as me. let me know

Wow … that’s a lot of convoluted and confusing code …that’s gonna take a while. But on one basic thing I can say something already.

When you run

PowerShell /?

PowerShell will tell you how to call it. :wink: How do you actually figure things out usually? :thinking:

So in a task scheduler task you would provide

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

as the executable and add everything else you want it to do as arguments … like this

-NoProfile -ExecutionPolicy Bypass -File "<FullPath>\StartMonitoring2.ps1"

Of course if you have soemthing in your profile you need in your scripts you should omit the argument -NoProfile. :point_up_2:t4:

1 Like

And why do you actually need two separate tasks for that? As long as you’re looged on to the computer the task should keep running. Why should it stop when you lock your workstation?

Regardless of that … in the other thread you mentioned the path for your FileSystemWatcher is W:\PO Files. Is that a local folder? If not - it is highly recommended to run the FSW locally on the computer where the watched folder is. That would reduce the network load caused by your construct significantly.

My question wasn’t how to get help for Powershell, it was how to put multiple lines of logic in one line of a task scheduler event. i can see from your comments that for the login event, i could put the powershell logic in one line and i understand that. but the unlock event needs to run multiple programs and do logic comparisons. my question was how to put all those commands into one line of a TS event.

as for why would i have to check to see if the command window closed, i do a lot of things on my computer, sometimes accidently close the dos window. need a way for the unlock event to confirm that a PS script is running and if not, then run it.

as for code being convoluted, maybe. but not confusing. one command for login, one for unlock. the login event is very straight forward, the unlock has to check for processes running. does that make sense?

anyway’s all is working as i intended. if there is a more straightforward way to do this, i am all ears. otherwise, ok to close post.