I am hunting for long-running Crystal Reports on a PeopleSoft report server. Obviously there are a number of ways to see these, e.g., the PeopleSoft process monitor or Oracle data dictionary v$ views. I need a way to see these at the Windows process level, so I can kill them.
The PowerShell way to get process information is get-process. How did I learn this? Well, I googled it. That's a limitation of the command line: it's not all that discoverable. In contrast to a GUI, it's often hard to just poke around the tool itself to find stuff out. This page at Microsoft shows a number of things you can do with get-process.
Aside: get-process is a cmdlet (pronounced commandlet), which are the basic building-blocks in PowerShell.
By default, it shows all processes, and eight columns of attributes, none of which has anything to do with start time:
PS C:\temp\ps1> get-process Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 88 3 2124 4300 39 5.39 308 Avconsol 86 3 2248 4096 44 25.66 1280 Avsynmgr 89 3 1916 3552 421 1.58 3468 bash 65 4 19216 18972 74 4.23 200 chrome 713 15 42024 56864 138 481.77 1372 chrome 61 3 8948 2448 60 0.80 1700 chrome 61 5 17168 3148 73 4.50 1916 chrome 61 3 11548 4684 65 10.64 2056 chrome 62 3 54004 15736 121 13.83 2228 chrome ...
Yes, I have a lot of Chrome tabs open. You don't know the half of it...
To find out what other attributes get-process can report, pipe it to cmdlet get-member:
PS C:\temp\ps1> get-process | get-member TypeName: System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- Handles AliasProperty Handles = Handlecount Name AliasProperty Name = ProcessName NPM AliasProperty NPM = NonpagedSystemMemorySize PM AliasProperty PM = PagedMemorySize VM AliasProperty VM = VirtualMemorySize WS AliasProperty WS = WorkingSet add_Disposed Method System.Void add_Disposed(EventHandler value) ...
StartTime Property System.DateTime StartTime {get;}
Get used to "get-member." I know I'll be using it all the time.
To see that property, pipe it to the cmdlet Select-Object. We'll also send it a process name with a wildcard to just see PeopleSoft-related processes:
PS C:\temp\ps1> get-process ps* | select-object Id, ProcessName, StartTime Id ProcessName StartTime -- ----------- --------- 3484 psadmin 3/26/2009 8:48:36 AM 2024 psaesrv 5/27/2009 5:41:20 PM 2328 psaesrv 5/26/2009 5:58:13 PM 3116 psaesrv 5/19/2009 12:23:18 PM 3344 psdstsrv 5/28/2009 3:32:49 AM 3472 psdstsrv 4/2/2009 6:05:18 AM 2344 psmonitorsrv 5/28/2009 6:05:17 AM 3132 psprcsrv 4/2/2009 6:05:19 AM 3388 pssqr 5/28/2009 1:13:50 PM
Here we can see some App Engine servers, various report server processes like distribution servers, and an SQR. No Crystal Reports at all. I was hoping for a zombie so we could kill it. Another day.
So we can report on the start time, but how do we filter on it? Let's say we want to see everthing started in the last two hours:
PS C:\temp\ps1> $now = Get-Date PS C:\temp\ps1> $then = $now.AddSeconds(-7200) PS C:\temp\ps1> get-process | where-object {$_.StartTime -gt $then} Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 31 1 1888 2608 12 0.03 2480 pssqr 79 4 5220 10056 44 0.06 1624 sqlplus 78 5 12816 16828 66 0.20 2576 sqrw
Grab the current time with Get-Date; calculate a time two hours ago (7200 seconds = 2 hours), and, via cmdlet Where-Object, show all processes started after that. Here we see that the report server has recently launched an SQR and a SQL*Plus script.
I could easily have asked for just the Crystal Reports, though since there weren't any running, it's a good thing I didn't.
In part three I may finally get around to killing the zombies.