490
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
to aggregate collections of jobs under a single master, or executive, job. We’ll get to 
those situations in a minute. For now, just know that background jobs always consist 
of a parent job and one or more child jobs.
For jobs started using 
Start-Job
or the 
-AsJob
parameter on 
Invoke-Command
the parent job is the executive. It doesn’t run any commands or return any results.
NOTE
The executive does no actual work—it just supervises. All the 
work is done by the subordinates. That sounds familiar somehow….
This collection of child jobs is stored in the 
ChildJobs
property of the parent 
Job 
object. The child 
Job
objects have a name, 
ID
, and instance 
ID
that differ from the 
parent job so that you can manage the parent and each child job individually or as a 
single unit.
To see the parent and all the children in a 
Job
, use the 
Get-Job
cmdlet to get the 
parent 
Job
object, and then pipe it to 
Format-List
, which displays the 
Name
and 
ChildJobs
as properties of the objects. Here’s what this looks like:
PS (1) > Get-Job | Format-List -Property Name, ChildJobs 
Name          : Job1 
ChildJobs     : {Job2}
You can also use a 
Get-Job
command on the child job, as shown in the following 
command
PS (2) > Get-Job job2
Id    Name   State      HasMoreData   Location    Command 
--    ----   -----      -----------   --------    -------
    Job2   Completed  True          localhost   Get-Process
and so on until you get to a 
Job
that has no children.
Child jobs with Invoke-Command
Let’s look at the scenario where you need to have more than one child job. When 
Start-Job
is used to start a job on a local computer, the job always consists of the 
executive parent job and a single child job that runs the command. When you use the 
-AsJob
parameter on 
Invoke-Command
to start a job on multiple computers, you 
have the situation where the job consists of an executive parent job and one child job 
for each command running on a remote server, as shown in figure 12.12.
When  you  use 
Invoke-Command
to explicitly run 
Start-Job
on the remote 
machines, the result is the same as a local command run on each remote computer. 
The command returns a job object for each computer. The 
Job
object consists of an 
executive parent job and one child job that runs the command.
The parent job represents all the child jobs. When you manage a parent job, you 
also manage the associated child jobs. For example, if you stop a parent job, all child
Pdf move pages - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
change pdf page order preview; pdf reorder pages
Pdf move pages - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
change page order pdf acrobat; reorder pdf pages reader
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
491
jobs are also stopped. Similarly, when you get the results of a parent job, you’re also 
getting the results of all child jobs.
Most of the time, you don’t need to be concerned with the fact that there are par-
ent and  child  jobs;  but it’s possible  to  manage  the  child  jobs individually.  This 
approach is typically only used when you want to investigate a problem with a job or 
get the results of only one of a number of child jobs started by using the 
-AsJob 
parameter of 
Invoke-Command
The following command uses 
Invoke-Command
with 
-AsJob
to start background 
jobs on the local computer and two remote computers. The command saves the job 
in the 
$j
variable:
PS (1) > $j = Invoke-Command -ComputerName localhost, Server01, Server02 `
-Command {Get-Date} -AsJob
When you display the 
Name
and 
ChildJob
properties of the object in 
$j
, it shows 
that  the  command  returned  a 
Job
object with three child jobs, one for each 
computer:
PS (2) > $j | Format-List name, childjobs
Name      : Job3
ChildJobs : {Job4, Job5, Job6}
When you display the parent job, it shows that the overall job was considered to 
have failed:
PS (3) > $j
Id   Name    State   HasMoreData     Location             Command 
--   ----    -----   -----------     --------             -------
   Job3    Failed  True            localhost,server... Get-Date
Child job #3
Child job #4
Parent job
(executive)
Child job #2
Invoke-Command -Computer $list { Get-Date } -AsJob
User
Child job #1
Get-Date
Get-Date
Get-Date
Get-Date
Figure 12.12 The relationship between the executive job and the nested jobs created 
when 
Invoke-Command -AsJob
is used to run commands on multiple remote 
computers. The user calls 
Invoke-Command
to start a job with multiple nested jobs, 
one for each target node in 
$list
.
C# TIFF: How to Reorder, Rearrange & Sort TIFF Pages Using C# Code
Using this C#.NET Tiff image management library, you can easily change and move the position of any two or more Tiff file pages or make a totally new order for
change page order in pdf online; moving pages in pdf
C# Word - Sort Word Pages Order in C#.NET
page reorganizing library control, developers can swap or adjust the order of all or several Word document pages, or just C# DLLs: Move Word Page Position.
move pages in pdf online; pdf rearrange pages
492
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
But on further investigation, when you run 
Get-Job
on each of the child jobs, you 
find that only one of them has failed:
PS (4) > Get-Job job4, job5, job6
Id   Name   State      HasMoreData     Location           Command 
--   ----   -----      -----------     --------           -------
   Job4   Completed  True            localhost          get-date
   Job5   Failed     False           Server01           get-date
   Job6   Completed  True            Server02           get-date
To get the results of all child jobs, use the 
Receive-Job
cmdlet to obtain the results 
of the parent job. But you can also get the results of a particular child job, as shown in 
the following command:
PS (5) > Receive-Job -Job 6 -Keep | 
>> Format-Table ComputerName,DateTime -AutoSize
ComputerName DateTime
------------ --------
Server02     Thursday, March 13, 2008 4:16:03 PM
In this example, you’re using the 
-Keep
parameter, which allows you to read, but not 
remove, output from a job. When you use 
-Keep
, the output from the job is retained 
in the output buffer for that job. You’re using it here so that when you do a 
Receive-
Job
on the executive job, you’ll get the output of all jobs in a single collection. In 
effect, this is a way of “peeking” at the output of one of the child jobs. By using child 
jobs, you have much more granular control over the set of activities you have running.
The way you’ve been working with jobs so far has been much like when you were 
using 
Invoke-Command
and specifying the name of a computer. Each time you con-
tacted the computer, 
Invoke-Command
created a new session. You’re doing much the 
same  thing when  you use 
Start-Job
 With 
Invoke-Command
, you were able  to 
improve your efficiency by creating sessions. In the next section you’ll see how ses-
sions work with jobs.
12.5.5
Running jobs in existing sessions
Each background job runs in its own PowerShell session, paralleling the way each 
remote command is also executed in its own session. As was the case with remoting, 
this session can be a temporary one that exists only for the duration of the back-
ground job, or it can be run in an existing 
PSSession
. But the way to do this isn’t 
obvious because the 
Start-Job
cmdlet doesn’t have a 
-Session
parameter. Instead 
you have to use 
Invoke-Command
with the 
-Session
and 
-AsJob
parameters. Here’s 
what that looks like. First, create a 
PSSession
object:
PS (1) > $s = New-PSSession
Now pass that session object to 
Invoke-Command
with 
-AsJob
specified:
PS (2) > $j = Invoke-Command -Session $s -AsJob {$PID}
C# PowerPoint - Sort PowerPoint Pages Order in C#.NET
library control, developers can swap or adjust the order of all or several PowerPoint document pages, or just change the C# DLLs: Move PowerPoint Page Position.
move pages in pdf file; how to move pages in a pdf
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
RasterEdge XDoc.PDF allows you to easily move PDF document pages position, including sorting pages and swapping two pages. Copying and Pasting Pages.
how to move pages within a pdf; how to reorder pdf pages in reader
C
ONSIDERATIONS
WHEN
RUNNING
COMMANDS
REMOTELY
493
The scriptblock that you’re passing  in returns the process 
ID
of the session.  Use 
Receive-Job
to retrieve it:
PS (3) > Receive-Job $j 
10808
You can call 
Invoke-Command
without 
-AsJob
with the same session object and 
scriptblock:
PS (4) > Invoke-Command -Session $s {$PID} 
10808
You get the same process 
ID
back, which is expected because the session is persistently 
associated with the same process.
Keep in mind that when a job is run in an existing 
PSSession
, that session can’t be 
used to run additional tasks until the job has completed. This means that you have to 
create multiple 
PSSession
objects if you need to run multiple background tasks but 
want to avoid the overhead of creating new processes for each job. As always, it’s up to 
the script author to decide how best to manage resources for their script.
12.6
C
ONSIDERATIONS
WHEN
RUNNING
COMMANDS
REMOTELY
When you run commands on multiple computers, you need to be aware, at least to 
some extent, of how the execution environment can differ on the target machines. 
For example, the target machine may be running a different version of the operating 
system, or it may have a different processor. There may also be differences in which 
applications are installed, how files are arranged, or where things are placed in the 
Registry. In this section, we’ll look at a number of these issues.
Start-Job and sessions
So why is there no -Session parameter on Start-Job? This parameter did exist 
at one point in the development of PowerShell v2. At that time, jobs and remoting 
used the same message 
transport
, not just the same basic infrastructure. Using the 
same transport was found to be problematic for a number of reasons: 
• It was inefficient for communication with local jobs.
• It required that the remoting service be enabled on the local machine, which 
has security implications.
• It required users to be running with admin privileges to be able to use the job 
feature. 
To resolve these issues, the existing WSMan-based transport used by jobs was 
replaced with anonymous pipes. This change solved these problems, but it had the 
unfortunate side effect that jobs could no longer be directly run with in PSSession 
instances because the PSSession object was tied to WSMan remoting.
C# PDF insert text Library: insert text into PDF content in C#.net
int pageIndex = 0; // Move cursor to (400F, 100F). String outputFilePath = Program.RootPath + "\\" output.pdf"; doc.Save(outputFilePath);
move pdf pages online; reverse page order pdf online
VB.NET PDF insert text library: insert text into PDF content in vb
Dim pageIndex As Integer = 0 ' Move cursor to (400F, 100F). Dim outputFilePath As String = Program.RootPath + "\\" output.pdf" doc.Save(outputFilePath).
reorder pdf pages; how to rearrange pages in a pdf reader
494
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
12.6.1
Remote session startup directory
When a user connects to a remote computer, the system sets the startup directory for 
the remote session to a specific value. This value will change depending on the ver-
sion of the operating system on the target machine:
• If the machine is running Windows Vista, Windows Server 2003 R2, or later, 
the default starting location for the session is the user’s home directory, which is 
typically C:\Users\<UserName>.
• On Windows Server 2003, the user’s home directory is also used but resolves to 
a slightly different path: C:\Documents and Settings\<UserName>.
• On Windows 
XP
, the default user’s home directory is used instead of the connect-
ing user’s. This typically resolves to C:\Documents and Settings\Default User.
The default starting location can be obtained from either the 
$ENV:HOMEPATH
envi-
ronment or the PowerShell 
$HOME
variable. By using these variables instead of hard-
coded paths in your scripts, you can avoid problems related to these differences. Next, 
we’ll examine issues related to startup and profiles.
12.6.2
Profiles and remoting
Most PowerShell users eventually create a custom startup script or profile that they use 
to customize their environment. These customizations typically include defining con-
venience functions and aliases. Although profiles are a great feature for customizing 
local interactive sessions, if the convenience commands they define are used in scripts 
that you want to run remotely, you’ll encounter problems. This is because your profiles 
aren’t run automatically in remote sessions, and that means the convenience com-
mands defined in the profile aren’t available in the remote session. In fact, the 
$PRO-
FILE
variable, which points to the profile file, isn’t even populated for remote sessions.
As a best practice, for production scripting you should make sure your scripts 
never become contaminated with elements defined by your profiles. One way to test 
this is to run the script from 
PowerShell.exe
with the 
-NoProfile
option, which 
looks like this:
powershell -NoProfile -File myscript.ps1
This command will run the script without loading your profile. If the script depends 
on anything defined in the profile, it will generate errors.
But for remote interactive sessions, it’d be nice to have the same environment 
everywhere. You can accomplish this by using 
Invoke-Command
with the 
-FilePath 
parameter to send your profile file to the remote machine and execute it there. The 
set of commands you need to accomplish this are as follows:
$c = Get-Credential 
$s = New-PSSession -Credential $ -ComputerName targetComputer 
Invoke-Command -Session $s -FilePath $PROFILE 
Enter-PSSession $s
C# PDF Image Extract Library: Select, copy, paste PDF images in C#
Get image information, such as its location, zonal information, metadata, and so on. Able to edit, add, delete, move, and output PDF document image.
how to move pages in pdf files; move pages in a pdf file
VB.NET PDF Library SDK to view, edit, convert, process PDF file
Rapidly and multiple PDF document (pages) creation and edit methods file formats; merge, append, and split PDF files; insert, delete, move, rotate, copy
reordering pdf pages; how to rearrange pages in a pdf file
C
ONSIDERATIONS
WHEN
RUNNING
COMMANDS
REMOTELY
495
First, you get the credential for the target machine (this typically won’t be needed in 
the domain environment). Next, you create a persistent session to the remote com-
puter. Then you use 
-FilePath
on 
Invoke-Command
to execute the profile file in 
the  remote  session.  Finally,  with  the  session  properly  configured,  you  can  call 
Enter-PSSession
to start your remote interactive session with all of your normal 
customizations.
Alternatively, sometimes you may want to run a profile on the remote machine 
instead of your local profile. Because 
$PROFILE
isn’t populated in your remote ses-
sion, you’ll need to be clever to make this work. The key is that, although 
$PROFILE 
isn’t set, 
$HOME
is. You can use this to compose a path to your profile on the remote 
computer. The revised list of commands looks like this:
$c = Get-Credential 
$s = New-PSSession -Credential $ -ComputerName targetComputer
Invoke-Command -Session $s {
. "$home\Documents\WindowsPowerShell\profile.ps1" } 
Enter-PSSession $s
This command dot-sources (see section 8.1.4) the profile file in the user’s directory 
on the remote machine into the session. Note that this script won’t work on XP or 
Windows Server 2003 because the document directory on those versions of Windows 
is Documents and Settings instead of Documents. For those operating systems, the 
set of steps would look like this:
$c = Get-Credential 
$s = New-PSSession -Credential $ -ComputerName targetComputer
Invoke-Command -Session $s {
. "$home\Documents and Setting\WindowsPowerShell\profile.ps1" } 
Enter-PSSession $s
In this section you learned how to cause your profile to be used to configure the 
remote session environment. At the end of the section, we revisited the idea that some 
system paths will vary depending on the operating system version. In the next sec-
tion, we’ll examine another area where these variations can cause problems.
12.6.3
Issues running executables remotely
PowerShell remoting allows you to execute the same types of commands remotely as 
you can locally, including external applications or executables. The ability to remotely 
execute commands like 
shutdown
to restart a remote host or 
ipconfig
to get net-
work settings is critical for system management. 
For the most part, console-based commands will work properly because they read 
and write only to the standard input, output, and error pipes. Commands that won’t 
work are ones that directly call the Windows Console 
API
s, like console-based editors 
or text-based menu programs. The reason is that no console object is available in the 
remote session. Because these applications are rarely used anymore, this fact typically
496
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
won’t have a big impact. But there are some surprises. For example, the 
net
com-
mand will work fine most of the time, but if you do something like this (which 
prompts for a password)
PS (1) > net use p: '\\machine1\c$'  /user:machine1\user1 * 
Type the password for \\machine1\c$:
in a remote session you’ll get an error:
[machine1]: > net use p: '\\machine1\c$'  /user:machine1\user1 * 
net.exe : System error 86 has occurred.
+ CategoryInfo          : NotSpecified: (System error 86 has 
occurred.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
The specified network password is not correct. 
Type the password for \\machine1\c$: 
[machine1]: > 
This command prompted for a password and returned an empty string. 
The other kind of program that won’t work properly are commands that try to 
open a user interface (also known as “try to pop 
GUI
”) on the remote computer.
If the remote command starts a program that has a 
GUI
interface, the program 
starts but no window will appear. If the command eventually completes, control will 
be returned to the caller and things will be more or less fine. But if the process is 
blocked waiting for the user to provide some input to the invisible 
GUI
, the com-
mand will hang and you must stop it manually by pressing 
C
trl-
C
. If the keypress 
doesn’t work, you’ll have to use some other mechanism to terminate the process.
For example, if you use 
Invoke-Command
to start Notepad on a remote machine, 
the process will start on the remote computer but the Notepad window will never 
appear. At this point, the command will appear to be “hung” and you’ll have to press 
C
trl-
C
to stop the command and regain control.
Now let’s look at more areas where accessing the console can cause problems and 
how to avoid these problems.
12.6.4
Reading and writing to the console
As you saw in the previous section, executables that read and write directly to the 
console won’t work properly. The same considerations apply to scripts that do things 
like call the 
System.Console
API
s directly themselves. For example, call the 
[Con-
sole]::WriteLine()
and 
[Console]::ReadLine()
API
s in a remote session:
[machine1]: > [Console]::WriteLine("hi") 
[machine1]: > 
[machine1]: > [Console]::ReadLine() 
[machine1]: >
Neither of these calls worked properly. When you called the 
[Console]::Write-
Line()
API
, nothing was displayed, and when you called the 
[Console]::Read-
Line()
API
, it returned immediately instead of waiting for input.
C
ONSIDERATIONS
WHEN
RUNNING
COMMANDS
REMOTELY
497
It’s still possible to write interactive scripts, but you have to use the PowerShell 
host cmdlets and 
API
s:
[machine1]: > Write-Host Hi
Hi 
[machine1]: > 
[machine1]: > Read-Host "Input" 
Input: some input 
some input
If you use these cmdlets as shown in the example, you can read and write to and from 
the host, and the remoting subsystem will take care of making everything work.
TIP
To ensure that scripts will work in remote environments, don’t 
call the console 
API
s directly. Use the PowerShell host 
API
s and cmd-
lets instead.
With console and 
GUI
issues out of the way, let’s explore how remoting affects the 
objects you’re passing back and forth.
12.6.5
Remote output vs. local output
Much of the power in PowerShell comes from the fact that it passes objects around 
instead of strings. In this section you’ll learn how remoting affects these objects.
When PowerShell commands are run locally, you’re working directly with the 
“live” .
NET
objects, which means that you can use the properties and methods on these 
objects to manipulate the underlying system state. The same isn’t true when you’re 
working with remote objects. Remote objects are serialized—converted into a form 
that can be passed over the remote connection—when they’re transmitted between the 
client and the server. Although a small number of types are transmitted in such a way 
that they can be fully re-created by the receiving end, the majority of the types of 
objects you work with aren’t. Instead, when they’re deserialized, they’re turned into 
property bags—collections of data properties with the same names as the original prop-
erties. This property bag has a special property, 
TypeNames
, which records the name 
of the original type. This difference in operation is illustrated in figure 12.13. 
Typically, you can use deserialized objects just as you’d use live objects, but you 
must be aware of their limitations. Another thing to be aware of is that the objects 
that are returned through remoting will have had properties added that allow you to 
determine the origin of the command.
PowerShell serialization
Because you can’t guarantee that every computer has the same set of types, the Power-
Shell team chose to limit the number of types that serialize with fidelity, where the 
remote  type  is  the  same  type  as  the  local  type.  To  address  the  restrictions  of  a 
bounded set of types, types that aren’t serialized with fidelity are serialized as collec-
tions of properties, also called property bags. The serialization code takes each object
498
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
and adds all its properties to the property bag. Recursively, it looks at values of each 
the members. If the member value isn’t one of the ones supported with fidelity, a new 
property bag is created, and the members of the member’s values are added to the 
new property bag, and so on. This approach preserves structure if not the actual type 
and allows remoting to work uniformly everywhere.
Default serialization depth
The approach we just described allows any object to be encoded and transferred to 
another system. But there’s another thing to consider: objects have members that con-
tain objects that contain members, and so on. The full tree of objects and members 
can be complex. Transferring all the data makes the system unmanageably slow. This 
is addressed by introducing the idea of serialization depth. The recursive encoding of 
members stops when this serialization depth is reached. The default for objects is 1.
The final source of issues when writing portable, remotable scripts has to do with 
processor architectures and the operating system differences they entail. We’ll work 
through this final set of issues in the next (and last) section of this chapter.
12.6.6
Processor architecture issues
We’ve looked at a number of aspects of the remote execution environment that may 
cause problems: operating system differences and issues with session initialization, 
GUI
s,  and  console interactions.  The  last potential  source  of problems  that  we’ll 
explore is the fact that the target machine may be running on a different processor 
architecture (i.e., 64-bit vs. 32-bit) than the local machine. If the remote computer is 
running a 64-bit version of Windows and the remote command is targeting a 32-bit
Remote machine
Local machine
Pipeline
processor
Remoting
serializer
Invoke-Command machine { Get-Process }
ProcessInfo.NET objects
PSObjectproperty bags
Pipeline
processor
User runs local Get-Process
Get-Process
ProcessInfo.NET objects
User runs remote Get-Process
User
User
Remoting
deserializer
Serialized objects
Figure 12.13 The differences in the way objects 
that are returned for the local and remote invoca-
tion cases. In the local case, live .NET objects are 
returned. When a remote command is invoked, 
the objects returned by the remote command are 
serialized on the remote machine and returned to 
the invoker as property bags: collections of 
properties attached to 
PSObject
instances.
C
ONSIDERATIONS
WHEN
RUNNING
COMMANDS
REMOTELY
499
session configuration, such as Microsoft.PowerShell32, the remoting infrastructure 
loads a Windows 32-bit on a Windows 64-bit 
(WOW64)
process, and Windows auto-
matically  redirects  all  references  to  the  $
ENV:W
indir
\S
ystem32  directory  to  the 
$
ENV:WINDIR\S
ys
WOW64
directory. For the most part, everything will still work 
(that’s the point of the redirection), unless you try to invoke an executable in the 
System32 directory that doesn’t have a corresponding equivalent in the 
S
ys
WOW64 
directory. Let’s see what this looks like. First, run defrag on a 64-bit 
OS
targeting the 
32-bit configuration. This results in the following output:
PS (1) > Invoke-Command -ConfigurationName Microsoft.PowerShell32 ` 
>> -ComputerName localhost -command { defrag.exe /? } 
>>
The term 'defrag.exe' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling 
of the name, or if a path was included, verify that the path is 
correct and try again.
+ CategoryInfo          : ObjectNotFound: (defrag.exe:Strin
g) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Because there was no corresponding 
defrag.exe
in the SysWoW64 directory, the 
command wasn’t found. Now target the 32-bit configuration:
PS (2) > Invoke-Command -ConfigurationName microsoft.powershell ` 
>> -ComputerName localhost -command { defrag.exe /? } 
>>
Description:  Locates and consolidates fragmented files on local
volumes to improve system performance.
Syntax:  Defrag.exe <volume> -a [-v]
Defrag.exe <volume> [{-r | -w}] [-f] [-v]
Defrag.exe       -c [{-r | -w}] [-f] [-v] 
:
And everything works properly.
NOTE
Depending on how your system is configured and the version/ 
SKU of Windows you’re using (e.g., Vista vs. Windows 7, Enterprise 
vs. Ultimate), this technique may work in both cases. 
To find the processor architecture for the session, you can check the value of the 
$ENV:PROCESSOR_ARCHITECTURE
variable. The following command finds the pro-
cessor architecture of the session in the 
$s
variable. Try this, first with the 32-bit con-
figuration:
PS (10) > Invoke-Command -ConfigurationName microsoft.powershell32 ` 
>> -ComputerName localhost { $ENV:PROCESSOR_ARCHITECTURE } 
>> 
x86
Documents you may be interested
Documents you may be interested