![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Run tasks asynchronously: external files vs. script blocks I need to run few chained tasks asynchronously AND pass parameters down to the chain. (At the very bottom is “short” description, what I’m trying to do) I can run tasks asynchronously using external files, but can not do the same with script blocks... Below is an example: There are two files there f1.ps1 and f2.ps1 This example works with external files. To change it to work with scriptblocks all you have to do is uncomment all lines started with #2 AND comment corresponding previous lines (#1). [[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]] # f1.ps1 [scriptblock] $f2_script = { param( [string] $p1 ) "hello world parameter1: $p1 input: $input" } [string] $f2_file = "./f2.ps1" #------------------------------------------------------------------------------ #1 function invokeAsync([string] $command, [DateTime] $a) { #2 function invokeAsync([scriptblock] $script, [DateTime] $a) { [System.Management.Automation.Runspaces.RunspaceConfiguration] $config = [System.Management.Automation.Runspaces.RunspaceConfiguration]::Create(); [System.Management.Automation.Runspaces.Runspace] $runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($host, $config); $runspace.Open() #1 [System.Management.Automation.Runspaces.Command] $cmd = new-object System.Management.Automation.Runspaces.Command($command, $false, $false); #2 [System.Management.Automation.Runspaces.Command] $cmd = new-object System.Management.Automation.Runspaces.Command($script, $true, $false); [System.Management.Automation.Runspaces.CommandParameterCollection] $cpc = $cmd.Parameters; $cmd.Parameters.Add("p1", $a); [System.Management.Automation.Runspaces.Pipeline] $pipeline = $runspace.CreatePipeline(); $pipeline.Commands.Add($cmd); foreach($private:x in $input) { $pipeline.Input.Write($x) > $null } $pipeline.Input.Close(); if($true) { # if($false) { foreach($private:x in $pipeline.Commands) { Write-Host ("CommandText {0}" -f $x.CommandText) Write-Host ("IsScript {0}" -f $x.IsScript) Write-Host ("UseLocalScope {0}" -f $x.UseLocalScope) } } $pipeline.InvokeAsync(); while($pipeline.PipelineStateInfo.State -eq [System.Management.Automation.Runspaces.PipelineState]::Running) { Start-Sleep -milli 100 } foreach($private:result in $pipeline.Output.ReadToEnd()) { Write-Host ("1-- Value {0}" -f $result) } foreach($private:result in $pipeline.Error.ReadToEnd()) { Write-Host ("2-- Value {0}" -f $result) } } #------------------------------------------------------------------------------ #-- Main script --------------------------------------------------------------- #------------------------------------------------------------------------------ [DateTime] $private:a = [DateTime]::Now; #1 ($a, $a) | invokeAsync $f2_file $a #2 ($a, $a) | invokeAsync $f2_script $a #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ [[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]] # f2.ps1 param( [string] $p1 ) "hello world parameter1: $p1 input: $input" #"hello world parameter1: $args input: $input" [[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]] ------------------------------------------------------------------------- ------------------------------------------------------------------------- ------------------------------------------------------------------------- Below is “short” description, what I’m trying to do: Start backup databases on several servers simultaneously. Like this Server A backup db A1 A2 A3 Server B backup db B1 B2 Etc. Due to some limitations I backup only one db from each server simultaneously. I.e. A –A1 & B – B1 will run at the same time. Once first backup is completed immediately 1. start archiving it ASYNCHRONOUSLY 2. start statistic recalculating for this db ASYNCHRONOUSLY 3. continue backing up next database. Once all tasks is done, generate a report with all timing, when each task is started and completed plus all totals including running totals. I.e. A – A1 backup started … completed … duration … archiving started … completed … duration … statistics … A – A1 database total … A server total Backup total… Running tasks asynchronously is the easy part. Gathering totals in one place is more difficult. Actually, it’s done already. But some questions are still there... |
My System Specs![]() |
| | #2 (permalink) |
| | RE: Run tasks asynchronously: external files vs. script blocks "OK" wrote: > I can run tasks asynchronously using external files, but can not do the same > with script blocks... > > Running tasks asynchronously is the easy part. Gathering totals in one place > is more difficult. Actually, it’s done already. But some questions are still > there... Can you be more clear on what is actually NOT working? What are the results you are expecting and what are the results that you get? Using your example with script files (#1), the output I'm getting is: ################ CommandText ./f2.ps1 IsScript False UseLocalScope False ################ Using scriptblocks (#2), the output looks like: ################ CommandText param( [string] $p1) "hello world parameter1: $p1 input: $input" IsScript True UseLocalScope False ################ However, the following is a completely different approach on solving the problem of timing asynchronously running tasks. Maybe this can help you with your problem without raising more questions. ;-) Note that escaping the scriptblock strings $sb1 and $sb2 is a little bit weird, but it should be possible to replace this part with external script files so that the new process will be executed as something like: "powershell.exe -noprofile -command C:\script1.ps1" Of course you can also directly specify external applications to be run. ################################ # start-jobdemo.ps1 ################################ $scriptstarttime = get-date "starting script: $scriptstarttime" "-"*40 $sb1 = '&{''hello from ''+$pid; 0..10|%{''-'' + $_ + ''-''; sleep 1}}' $sb2 = '&{''hello from ''+$pid; 0..20|%{''-'' + $_ + ''-''; sleep 1}}' $externalWindow = $true $StartInfo1 = new-object System.Diagnostics.ProcessStartInfo $StartInfo1.FileName = "powershell.exe" $StartInfo1.Arguments = "-noprofile -command $sb1" $StartInfo1.UseShellExecute = $externalWindow $p1 = [System.Diagnostics.Process]::Start($StartInfo1) $p1starttime = get-date "process1 started: $p1starttime" $StartInfo2 = new-object System.Diagnostics.ProcessStartInfo $StartInfo2.FileName = "powershell.exe" $StartInfo2.Arguments = "-noprofile -command $sb2" $StartInfo2.UseShellExecute = $externalWindow $p2 = [System.Diagnostics.Process]::Start($StartInfo2) $p2starttime = get-date "process2 started: $p2starttime" $p1finished = $false $p2finished = $false while (($p1finished -eq $false) -or ($p2finished -eq $false)) { sleep 2 #"-"*40 #"p1 exited?: $($p1.hasexited) / $(get-date)" if (($p1.hasexited -eq $true) -and ($p1finished -eq $false)) { $p1endtime = get-date; "process1 finished: $p1endtime" $p1finished = $true } #"p2 exited?: $($p2.hasexited) / $(get-date)" if (($p2.hasexited -eq $true) -and ($p2finished -eq $false)) { $p2endtime = get-date; "process2 finished: $p2endtime" $p2finished = $true } } "-"*40 $scriptendtime = get-date "script finished: $scriptendtime" "-"*40 "process1 total time: $($p1endtime - $p1starttime)" "process2 total time: $($p2endtime - $p2starttime)" "-"*40 "script total time: $($scriptendtime - $scriptstarttime)" ################################ -- greetings dreeschkind |
My System Specs![]() |
| | #3 (permalink) |
| | RE: Run tasks asynchronously: external files vs. script blocks >$StartInfo1 = new-object System.Diagnostics.ProcessStartInfo That’s the way I did it before. :-) Now consider following scenario: Process A starts many B processes. Each process B starts processes C and D. Process A needs to track all of them and finally create timing report. There are ways to do it, but (IMO!) using [System.Management.Automation.Runspaces] is much more elegant with parameters and results passing up and down the pipes. About results from my example: You should have TWO files in the same folder f1.ps1 f2.ps1 you run f1.ps1 and it calls f2.ps1 the output I’m getting: #1 ################ CommandText ./f2.ps1 IsScript False UseLocalScope False 1-- Value hello world parameter1: 10/30/2006 21:02:55 input: 10/30/2006 21:02:55 10/30/2006 21:02:55 ################ I.e. in you case you not getting results back! BTW: Is there a way to attach .zip to my post? #2 ################ CommandText param( [string] $p1) "hello world parameter1: $p1 input: $input" IsScript True UseLocalScope False ################ In the second case I can not get scriptblock to execute asynchronously. And I can do it synchronously easily: &$script $a $a | &$script ################ hello world parameter1: 10/30/2006 21:08:26 input: hello world parameter1: input: 10/30/2006 ################ So the question remains open: Is there a way to asynchronously execute a scriptblock? (It’s rather theoretical, I use files anyway :-) |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Run tasks asynchronously: external files vs. script blocks this is something by background pipeline cmdlets can achieve, i better get it ported and updated to powershell RC2 soon. |
My System Specs![]() |
| | #5 (permalink) |
| | Re: Run tasks asynchronously: external files vs. script blocks > > Now consider following scenario: > Process A starts many B processes. > Each process B starts processes C and D. > Process A needs to track all of them and finally create timing > report. > Perhaps Live Search http://search.live.com/results.aspx?...rationEvent%22 |
My System Specs![]() |
| | #6 (permalink) |
| | Re: Run tasks asynchronously: external files vs. script blocks >this is something by background pipeline cmdlets can achieve, >i better get it ported and updated to powershell RC2 soon. Interesting. I’ve never heard about them. Are they based on [System.Management.Automation.Runspaces]? "klumsy@xtra.co.nz" wrote: > this is something by background pipeline cmdlets can achieve, i better > get it ported and updated to powershell RC2 soon. > > |
My System Specs![]() |
| | #7 (permalink) |
| | Re: Run tasks asynchronously: external files vs. script blocks Are there any examples in C#/PS available? "Flowering Weeds" wrote: > > > > > Now consider following scenario: > > Process A starts many B processes. > > Each process B starts processes C and D. > > Process A needs to track all of them and finally create timing > > report. > > > > Perhaps > > Live Search > http://search.live.com/results.aspx?...rationEvent%22 > > > > > > |
My System Specs![]() |
| | #8 (permalink) |
| | Re: Run tasks asynchronously: external files vs. script blocks http://www.karlprosser.com/coder/?cat=12 -- greetings dreeschkind "OK" wrote: > >this is something by background pipeline cmdlets can achieve, > >i better get it ported and updated to powershell RC2 soon. > Interesting. I’ve never heard about them. Are they based on > [System.Management.Automation.Runspaces]? > > > "klumsy@xtra.co.nz" wrote: > > > this is something by background pipeline cmdlets can achieve, i better > > get it ported and updated to powershell RC2 soon. > > > > |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Using PowerShell script to create a list of Scheduled tasks | PowerShell | |||
| How to pass values from script to external batch files | PowerShell | |||
| Running an external process asynchronously | PowerShell | |||
| Vista Blocks Word 2003 Saving Files | Vista security | |||
| Vista blocks access to downloaded program files | Vista security | |||