Today, I read the Scripting guy's several masterpieces about runspace, so I know the new ones, and some of them are more clear.
https://blogs.technet.microsoft.com/heyscriptingguy/2015/11/26/beginning-use-of-powershell-runspaces-part-1/
Runspace, which has been used more frequently in PowerShell over the past two years, has largely replaced traditional job background operations due to his high efficiency. Whether it is a multi-threaded implementation, or a background operation, or an intrusion script, runspace performance can be more than dozens of times times the job.
Now look at a few examples, how to achieve.
Example 1 synchronous operation of a PowerShell instance
Create an instance of PowerShell, and then add a piece of code and invoke execute.
$PowerShell = [Powershell]::create () [void] $PowerShell. Addscript ({get-date start-sleep-seconds) $PowerShell. Invo Ke ()
Note the points:
powershell is not just a scripting language, we can system.management.automation.powershell The methods provided to create an instance, add scripts and parameters.
The use of Powershell as a platform reference https://blogs.msdn.microsoft.com/powershell/2013/10/01/paap-windows-powershell-as-a-platform-part-1/
I used [void] to avoid outputting too much information about eight bad things (such as current runspace information, etc.) to pollute my output.
I added a command to wait 10 seconds in this script, and when we execute the invoke command, we see that the screen has been stuck for 10 seconds before we return to the current time. This synchronous operation should be avoided when performing multi-threaded and background operations, and later we will say how to implement asynchronous operations.
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M02/83/FE/wKioL1eDHSnz19gLAAAlf_ymGvo443.png "title=" 1.PNG " alt= "Wkiol1edhsnz19glaaalf_ymgvo443.png"/>
You can see that the execution of the invoke directly returns a result, which, in fact, is the same as the effect I entered get-date directly on the console, which is not appropriate for the background operation.
Example 2, asynchronously manipulating Runspace and PowerShell instances.
$Runspace = [Runspacefactory]::createrunspace () $PowerShell =[powershell]::create () $PowerShell. Runspace = $Runspace $ Runspace.open () [void] $PowerShell. Addscript ({get-date start-sleep-seconds) $AsyncObject = $PowerShell. Begininvok E ()
This time, we create a Runspace object, bind it to an instance of PowerShell, run the Runspace, and then add a script to the PowerShell instance as above. Note that an important improvement is the use of the BeginInvoke () method, which returns an asynchronous object. The difference between asynchronous and synchronous is that the synchronization will death at some point until the output results, and the asynchronous will automatically switch out, the periodic check results, and so on, and then switch back to get the results.
A simple and interesting example of C # Lao Wang bathing is vivid. Compare synchronous and asynchronous operations
Http://www.cnblogs.com/lxblog/archive/2012/12/11/2813893.html
Back to the previous script, let's look at what the Async object returned by BeginInvoke is. Because I set it to wait 10 seconds, so I can see his iscomleted property is False
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/83/FE/wKiom1eDHGuR0FQyAAAfUmP6AwI619.png "style=" float: none; "title=" 2.PNG "alt=" Wkiom1edhgur0fqyaaafump6awi619.png "/>
After 10 seconds, it becomes true, indicating that the operation has ended.
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M01/83/FD/wKioL1eDHG6jj0T7AAAfbnD7N48773.png "style=" float: none; "title=" 3.PNG "alt=" Wkiol1edhg6jj0t7aaafbnd7n48773.png "/>
Now we call EndInvoke this asynchronous object switch back to get the result
$Data = $PowerShell. EndInvoke ($AsyncObject) $Data
Success in getting results
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/83/FD/wKioL1eDHHGjsth7AAAXBigfK94941.png "style=" float: none; "title=" 4.PNG "alt=" Wkiol1edhhgjsth7aaaxbigfk94941.png "/>
Don't forget to turn off this example at the end.
$PowerShell. Dispose ()
Example 3 passing parameters to a PowerShell platform
$name = ' James ' $title = ' Manager ' $PowerShell =[powershell]::create () [void] $PowerShell. Addscript ({Param ($Param 1, $Par AM2) [pscustomobject]@{Param1 = $Param 1 Param2 = $Param 2}}). Addargument ($name). Addargument ($title) #Invoke the Command$powershell.invoke () $PowerShell. Dispose ()
For example, I define 2 variables, which I can pass through the addargument to the script block, and of course the script block must define the corresponding parameters and then pass in the variables sequentially.
Example 4 if there are too many arguments, I can pass the parameters by defining the hash table and AddParameters, which is more concise.
$ParamList = @{param1 = ' Kevin ' Param2 = ' receptionist '} $PowerShell = [Powershell]::create () [void] $PowerShell. ADDSC Ript ({Param ($Param 1, $Param 2) [pscustomobject]@{name = $Param 1 title = $Param 2}}). AddParameters ($ParamList) #Invoke the Command$powershell.invoke () $PowerShell. Dispose ()
Example 5 integration of the above knowledge points, a complete example, such as the use of runspace pool to achieve multi-threaded ping
This is an example that I have written before. http://beanxyz.blog.51cto.com/5570417/1760880
$Throttle = 20 #threads #脚本块, send an ICMP packet test to the specified computer, save the result in an object and receive a computer name parameter $ scriptblock = { param ( [string] $Computer ) $a =test-connection -computername $Computer -count 1 $RunResult = new-object psobject -property @{ ipv4adress= $a .ipv4address.ipaddresstostring computername= $Computer } Return $RunResult} #创建一个资源池, specify how many runspace can be executed at the same time, this represents a minimum of 1, up to 20 $RunspacePool = [runspacefactory]::createrunspacepool (1, $Throttle) $RunspacePool. Open () $Jobs = @ () #获取Windows 2012 Server information, create a single PowerShell instance for each server, each of which performs a ping operation asynchronously and saves the asynchronous object in result # Finally, all the results are saved in a Jobs object. #注意这里绑定Is the runspacepool, not the individual runspace (get-adcomputer -filter {operatingsystem -like "* 2012* "}) .name | % { #Start-sleep -seconds 1 $Job = [powershell]::create (). Addscript ($ScriptBlock). Addargument ($_) $Job .runspacepool = $RunspacePool $Jobs += new-object psobject -property @{ server = $_ Pipe = $Job result = $Job. BeginInvoke () }} #循环输出等待的信息 .... until all jobs are complete Write-Host "Waiting ..." -NoNewlineDo { Write-Host "." -NoNewline Start-Sleep -Seconds 1} While ( $ jobs.result.iscompleted -contains $false) write-host "All jobs completed! " #解锁, output results of asynchronous operations $Results = @ () foreach ($Job in $Jobs) { $Results += $Job. Pipe.endinvoke ($Job. Result)} $Results
Example 6, finally see how debug Runspace. PowerShell 5 provides a command Debug-runspace can track the currently executing command or script just like normal Debug.
Create a runspace directly, and you can see that his state is available
$rs =[runspacefactory]::createrunspace () $rs. Name= "Myrunspace" $rs. Open () get-runspace
650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M01/83/FE/wKioL1eDLWSASkHOAAAnZLVt6qQ278.png "title=" 6.PNG " Style= "Float:none;" alt= "Wkiol1edlwsaskhoaaanzlvt6qq278.png"/>
Bind this runspace to an instance of PowerShell, bind a script, execute asynchronously
$ps =[powershell]::create () $ps. runspace= $rs $ps.addscript (' C:\users\yli\documents\github\Powershell\ Restart-wsuscomputers.ps1 ') > $null $async= $ps. BeginInvoke () Get-runspace
You can see his state turned into a busy.
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/83/FF/wKiom1eDLWfR40SEAAAzHxLES2M166.png "title=" 7.PNG " Style= "Float:none;" alt= "Wkiom1edlwfr40seaaazhxles2m166.png"/>
Let's debug this time.
Debug-runspace Myrunspace
He automatically switches to my script page, and press F10 to follow the line automatically.
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M02/83/FE/wKioL1eDLWqCliC0AAC9V7VbQZ0394.png "style=" float: none; "title=" 8.PNG "alt=" Wkiol1edlwqclic0aac9v7vbqz0394.png "/>
If you need to terminate debug, enter detach on the console.
Resources
1. https://blogs.msdn.microsoft.com/powershell/2015/09/08/powershell-runspace-debugging-part-1/
2. https://blogs.msdn.microsoft.com/powershell/2013/10/01/paap-windows-powershell-as-a-platform-part-1/
3. http://www.cnblogs.com/lxblog/archive/2012/12/11/2813893.html
4. https://blogs.technet.microsoft.com/heyscriptingguy/2015/11/26/beginning-use-of-powershell-runspaces-part-1/
This article is from the "Mapo Tofu" blog, please be sure to keep this source http://beanxyz.blog.51cto.com/5570417/1825300
Creation, use and error checking of PowerShell runspace