Skip to content

Commit 9622452

Browse files
committed
main
1 parent 8cc4e3f commit 9622452

File tree

6 files changed

+200
-4
lines changed

6 files changed

+200
-4
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Background Job
2+
3+
A background job is a job running on another PowerShell process(sub-shell) created by the current PowerShell instance.
4+
5+
- `Start-Job`: start a background job(process job)
6+
- `-ScriptBlock`: specify custom action for the job
7+
- `-FilePath`: run from a script file
8+
- `-Name`: specify name for the job
9+
- `-InitializationScript`: preparation for the action run in current PowerShell process
10+
- `-WorkingDirectory`: specify cwd for the job
11+
- `-ArgumentList`: arguments to be passed into the process
12+
- `-PSVersion`: run in specific version
13+
14+
- `&`: syntactic shorthand for `Start-Job`
15+
16+
- `Receive-Job`: retrieve job state from a job object.
17+
- `-Wait` synchronously wait for the job.
18+
19+
## Start a Job
20+
21+
`Start-Job` creates a new background job and returns a `System.Management.Automation.PSRemotingJob` to represent the state of the job.
22+
23+
```ps1
24+
Start-Job -ScriptBlock { foo }
25+
```
26+
27+
### Using `&` <Badge type="info" text="PowerShell 6+" />
28+
29+
Using `&` to create a background job is only equivalent to `Start-Job -ScriptBlock { ... }`
30+
31+
```ps1
32+
$job = gps pwsh &
33+
# equivalent to
34+
$job = sajb { gps pwsh }
35+
```
36+
37+
`&` can be recognized as a statement terminator, so you don't have to use an extra `;` for multiple expression inline.
38+
39+
```ps1
40+
gps pwsh &; rcjb $job -Wait
41+
gps pwsh & rcjb $job -Wait # ; can be elided # [!code highlight]
42+
```
43+
44+
### Passing Arguments
45+
46+
Closure is not allowed for `-ScriptBlock`.
47+
48+
```ps1
49+
$foo = 'pwsh'
50+
$job = sajb { gps $foo }
51+
rcjb $job # receive error message # [!code error]
52+
53+
$job = sajb { gps $args } -ArgumentList pwsh,notepad # [!code highlight]
54+
rcjb $job # ok # [!code highlight]
55+
```
56+
57+
### Run as Job from other Cmdlet
58+
59+
There's some other cmdlet supports `-AsJob` switch to perform action as backgraound jobs, like `ForEach-Object` and `Invoke-Command`.
60+
61+
```ps1
62+
# Run a job in the remote
63+
Invoke-Command -HostName <host> -UserName <usr> -ScriptBlock { foo } -AsJob
64+
```
65+
66+
67+
### Querying Jobs
68+
69+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Job Manipulation
2+
3+
- `Receive-Job`: retrieve output from existing job
4+
- `Get-Job`: query existing jobs
5+
- `Remove-Job`: remove job from background
6+
- `Stop-Job`: terminate the job
7+
- `Wait-Job`: block the thread until one or all jobs are in a terminated state
8+
9+
Jobs has few identifier, such as name, id, instance id. All these cmdlet supports the corresponding parameters to specify the identity of jobs.
10+
They might not be pointed out explicitly for all sections
11+
12+
## Parent & Child Jobs
13+
14+
Each background job has at least one child job, the parent job does not return or execute anything, child jobs takes the real work.
15+
16+
```ps1
17+
$job = sajb { foo }
18+
$job.ChildJobs
19+
```
20+
21+
## Job Type
22+
23+
- `BackgroundJob`
24+
- `ThreadJob`
25+
- `RemoteJob`
26+
27+
## Querying Job
28+
29+
`Get-Job` returns all parent background jobs by default.
30+
31+
- `-IncludeChildJob`: list both parent jobs and child jobs, you might notice the job id is successive.
32+
- `-ChildJobState`: filter by child job state
33+
- `-Command`: get all jobs that executes a command satisfies the pattern in literal.
34+
```ps1
35+
gkb -Command 'gps *'
36+
```
37+
- `-State`: get all jobs with specific state.
38+
```ps1
39+
gjb -State Completed,Running
40+
```
41+
- `-Name`: get by job name
42+
- ...
43+
44+
## Remove Job
45+
46+
`Remove-Job` is not interesting and various, its parameters are pretty similar to `Get-Job` and it's commonly used together with `Get-Job` too.
47+
48+
```ps1
49+
gjb | rjb # remove all job
50+
```
51+
52+
## Terminate Job
53+
54+
`Stop-Job`, has the same form as `Remove-Job`, to terminate a running job.
55+
56+
## Retrieve Job Result
57+
58+
`Receive-Job` returns all results from the child jobs of a job.
59+
The return type of job result is not certain. It depends on the action you specified.
60+
61+
- `-Name`: retrieve result from given job name
62+
- `-Id`: retrieve result from given job id
63+
- `-Job`: retrieve result from given job object, positional
64+
- `-Keep`: preserve the job object after inspection
65+
```ps1
66+
rcjb $job -Keep # some result
67+
rcjb $job # some result, consumed here # [!code highlight]
68+
rcjb $job # no result # [!code highlight]
69+
$job -eq $null # False, the object is still available
70+
```
71+
- `-Wait`: synchronously block the thread to wait for the job to complete and finally get the result.
72+
```ps1
73+
rcjb $job -Wait # session blocked
74+
# result here
75+
```
76+
77+
## Wait for Job
78+
79+
`Wait-Job` can wait for jobs until they reach a terminated state like `Completed`, `Failed`, `Stopped`, `Suspended`, `Disconnected`
80+
81+
- `-Any`: wait until any job terminated
82+
- `-Timeout`: wait until timeout were reached
83+
- `-Force`: wait for `Suspended` and `Disconnected`
84+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Thread Job
2+
3+
Thread job is running on the same process of PowerShell instance, so it's faster than other job types.
4+
5+
## Create Thread Job <Badge type="info" text="PowerShell 6+" />
6+
7+
Thread job utils was added since PowerShell 6, if you want to use it in lower version, install the module with this command:
8+
9+
```ps1
10+
inmo ThreadJob -Scope CurrentUser
11+
```
12+
13+
The usage of `Start-ThreadJob` is similar to `Start-Job`. A `-ScriptBlock` or `-FilePath` should be specified as the action of the job.
14+
`Start-ThreadJob` returns a `ThreadJob` to represent the state of the job.
15+
16+
```ps1
17+
$job = Start-ThreadJob { foo }
18+
$job.GetType().Name # ThreadJob
19+
```
20+
21+
## Multiple Thread Jobs <Badge type="info" text="PowerShell 7+" />
22+
23+
`ForEach-Object` supports creating parallel thread job from pipeline input since PowerShell 7.
24+
25+
- `-Parallel`: perform each action on pipeline item in parallel, requires a scripblock.
26+
- `-AsJob`: return an object with child jobs.
27+
28+
`-AsJob` returns a `PSTaskJob` object that contains all child jobs representing each action on pipeline item.
29+
30+
```ps1
31+
1..10 | foreach -Parallel { echo $_ } -AsJob | rcjb -Wait
32+
```

docs/document/PowerShell/docs/Object Manipulation/4.ForEach.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ Evaluating from a method member is available, you can even pass parameters by `-
3636
(1..3 | % GetType | select -first 1) -is [System.Type] # True
3737
3838
'1,2,3' | foreach -MemberName Split -ArgumentList ','
39-
# or
39+
# or this, ',' is passed as ValueFromRemainingArguments for -ArgumentList
4040
'1,2,3' | foreach Split ','
4141
```
4242

4343
## Value Transformation
4444

45-
The way `ForEach-Object` behaves is collecting implicitly returned values as an array. Every implicitly returned value will be collected as a item.
45+
The way `-Process` behaves is collecting implicitly returned values as an array. Every implicitly returned value will be collected as a item.
4646

4747
> [!NOTE]
4848
> See: `help % -Parameter MemberName`

docs/document/PowerShell/docs/Object Manipulation/5.Select.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ gps | select -ExpandProperty Name
9292
> # or use another alias of ForEach-Object %
9393
> gps | % Name
9494
> ```
95+
>EDIT: Well actually you can do the same thing without `foreach` and `select`, use memeber accessor might solve the problem already except there's property name conflict.
96+
>```ps1
97+
>(gps).Name
98+
># equivalent to
99+
>gps | foreach Name
100+
>```
95101
96102
### Append Extra NoteProperty
97103

docs/document/PowerShell/docs/What to Learn for New cmdlet.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Positional parameter matters for understanding the examples listed on documentations since the example might elide parameter name.
66
We can take advantages of `Get-Help` and `Select-String` to capture those parameters that have a explicit order.
7-
The `-Context` includes 3 lines above and 5 lines below the display the whole info of the parameter.
7+
The `-Context` includes 3 lines above and 5 lines below the matched line to display the whole info of the parameter.
88

99
```ps1
1010
help <cmd> | sls 'Position\??\s*\d' -Context 3,5
@@ -37,10 +37,15 @@ $ help sls | sls 'Position\??\s*\d+' -Context 3,5
3737
Accept wildcard characters? false
3838
```
3939

40-
## Find Parameters Accepts Pipeline
40+
## Find Parameters Accept Pipeline
4141

4242
Similar to finding position parameter.
4343

4444
```ps1
4545
help <cmd> | sls 'Accept pipeline input\??\s*true.*$' -Context 5,4
4646
```
47+
48+
## Path Specific Parameter
49+
50+
Commonly named parameters for path are `-Path`, `-FilePath`, `-LiteralPath`.
51+
So once the cmdlet supports one of them, you should aware it probably supports one or more of others.

0 commit comments

Comments
 (0)