Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
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.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista Tutorial - Run tasks asynchronously: external files vs. script blocks

Reply
 
Old 10-30-2006   #1 (permalink)
OK
Guest


 
 

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 SpecsSystem Spec
Old 10-30-2006   #2 (permalink)
dreeschkind
Guest


 
 

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 SpecsSystem Spec
Old 10-30-2006   #3 (permalink)
OK
Guest


 
 

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 SpecsSystem Spec
Old 10-31-2006   #4 (permalink)
klumsy@xtra.co.nz
Guest


 
 

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 SpecsSystem Spec
Old 10-31-2006   #5 (permalink)
Flowering Weeds
Guest


 
 

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 SpecsSystem Spec
Old 11-01-2006   #6 (permalink)
OK
Guest


 
 

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 SpecsSystem Spec
Old 11-01-2006   #7 (permalink)
OK
Guest


 
 

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 SpecsSystem Spec
Old 11-05-2006   #8 (permalink)
dreeschkind
Guest


 
 

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 SpecsSystem Spec
Reply

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


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46