In a blog post yesterday, I talked about the new background job feature in PowerShell Version 2 CTP. One thing I did not entirely appreciate till today (and it should be blindingly obvious), a PSJob produces objects just like any other cmdlet. That means if your the background script produces objects of any kind, the Receive-PSJob cmdlet can retrieve them for manipulation locally. As should be obvious the remoting feature of PowerShell V2 works the same way (you remote a script to a system and get back objects).
Here's a demo of this (with a lot of lines cut out for brevity!)
[ 0]PS D:\foo\v2 > #
[ 1]PS D:\foo\v2 > # Examine PowerShell V2 jobs feature
[ 2]PS D:\foo\v2 > # Demonstrates Start-PSJob, Get-PSJob, Wait-PSJob, Receive-PSJob
[ 3]PS D:\foo\v2 > #
[ 4]PS D:\foo\v2 > # start a job, see it is running,
[ 5]PS D:\foo\v2 > #
[ 6]PS D:\foo\v2 > $job = Start-PSJob "Get-Process" -Name "Job-2"
[ 7]PS D:\foo\v2 > Get-PSJob
SessionId Name State HasMoreData Command
--------- ---- ----- ----------- -------
1 demo Completed True get-process
9 Job-2 Running True Get-Process
[ 8]PS D:\foo\v2 > #
[ 9]PS D:\foo\v2 > #now wait for it to finish
[10]PS D:\foo\v2 > Wait-Psjob $job
SessionId Name State HasMoreData Command
--------- ---- ----- ----------- -------
9 Job-2 Completed True Get-Process
[11]PS D:\foo\v2 > #
[12]PS D:\foo\v2 > # now get output
[13]PS D:\foo\v2 > #
[14]PS D:\foo\v2 > $procs=receive-PSJob $job -keep
[15]PS D:\foo\v2 > $procs
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
240 8 74584 54684 230 1,077.59 4888 AcroRd32
116 5 1220 1480 32 1.14 3092 alg
43 2 1320 852 29 700.95 3828 ApntEx
93 3 1744 1816 37 2,261.53 3960 Apoint
{ And a whole lot of lines snipped for brevity}
[16]PS D:\foo\v2 > #
[17]PS D:\foo\v2 > # look familiar?
[18]PS D:\foo\v2 > #
[19]PS D:\foo\v2 > $procs | gm
TypeName: Deserialized.System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
{ And a whole lot more lines also snipped for brevity}
[20]PS D:\foo\v2 > #
[21]PS D:\foo\v2 > # so...
[22]PS D:\foo\v2 > #
[23]PS D:\foo\v2 > $procs | sort handles -desc | select -first 5 |ft name, handles, wm,ws,priorityclass -auto
Name Handles wm WS PriorityClass
---- ------- -- -- -------------
svchost 9125 30830592 Normal
OUTLOOK 5444 55250944 Normal
searchindexer 1685 43831296 Normal
explorer 1306 43503616 Normal
csrss 1289 6451200 Normal
This is really pretty cool!! You get the PSjobs to run and collect objects and then analyze them locally/remotely. There are some things missing from this CTP, like no NEW-PSJOB, and the input to Receive-PSJob is a job object, not the job-object's id. This means Get-Psjob 9 would return the job noted in the above example, but Receive-PSJob 9 does not (yet) work.
Another point - the objects returned are de-serialized objects, thus you only get their properties - there is no direct way I can see to return the methods (although I'm sure someone will figure it out). So while you can stop or start a process using the objects returned from get-process, the deserialised objects returned from PS job don't have those methods to call. I'm not sure if this is a good thing or not . But I'd bet that rehydrating live objects across a network is non-trivial!
But it's still a great start!
No comments:
Post a Comment