The Pipeline
In the past, data was transferred from one command to
the next by using the pipeline, which makes it possible to string a
series of commands together to gather information from a system.
However, as mentioned previously, most shells have a major disadvantage:
The information gathered from commands is text based. Raw text needs to
be parsed (transformed) into a format the next command can understand
before being piped.
The point is that although
most UNIX and Linux shell commands are powerful, using them can be
complicated and frustrating. Because these shells are text based, often
commands lack functionality or require using additional commands or
tools to perform tasks. To address the differences in text output from
shell commands, many utilities and scripting languages have been
developed to parse text.
The result of all this parsing
is a tree of commands and tools that make working with shells unwieldy
and time consuming, which is one reason for the proliferation of
management interfaces that rely on GUIs. This trend can be seen among
tools Windows administrators use, too; as Microsoft has focused on
enhancing the management GUI at the expense of the CLI.
Windows administrators now
have access to the same automation capabilities as their UNIX and Linux
counterparts. However, PowerShell and its use of objects fill the
automation need Windows administrators have had since the days of batch
scripting and WSH in a more usable and less parsing-intense manner. To
see how the PowerShell pipeline works, take a look at the following
PowerShell example:
PS C:\> get-process powershell | format-table id -autosize
Id
--
3628
PS C:\>
Note
All pipelines end with the
Out-Default cmdlet. This cmdlet selects a set of properties and their
values and then displays those values in a list or table.
Modules and Snap-Ins
One of the main design goals
behind PowerShell was to make extending the default functionality in
PowerShell and sharing those extensions easy enough that anyone could do
it. In PowerShell 1.0, part of this design goal was realized through
the use of snap-ins. PowerShell snap-ins (PSSnapins) are dynamic-link
library (DLL) files that can be used to provide access to additional
cmdlets or providers. By default, a number of PSSnapins are loaded into
every PowerShell session. These default sets of PSSnapins contain the
built-in cmdlets and providers that are used by PowerShell. You can
display a list of these cmdlets by entering the command Get-PSSnapin at the PowerShell command prompt, as
follows:
PS C:\> get-pssnapin
Name : Microsoft.PowerShell.Core
PSVersion : 2.0
Description : This Windows PowerShell snap-in contains Windows PowerShell manage-
ment cmdlets used to manage components
of Windows PowerShell.
Name : Microsoft.PowerShell.Host
PSVersion : 2.0
Description : This Windows PowerShell snap-in contains cmdlets used by the Windows
PowerShell host.
...
PS C:\>
In theory, PowerShell
snap-ins were a great way to share and reuse a set of cmdlets and
providers. However, snap-ins by definition must be written and then
compiled, which often placed snap-in creation out of reach for many IT
professionals. Additionally, snap-ins can conflict, which meant that
attempting to run a set of snap-ins within the same PowerShell session
might not always be feasible.
That is why in PowerShell
2.0, the product team decided to introduce a new feature, called
modules, which are designed to make extending PowerShell and sharing
those extensions significantly easier. In its simplest form, a module is
just a collection of items that can be used in a PowerShell session.
These items can be cmdlets, providers, functions, aliases, utilities,
and so on. The intent with modules, however, was to allow “anyone”
(developers and administrators) to take and bundle together a collection
of items. These items can then be executed in a self-contained context,
which will not affect the state outside of the module, thus increasing
portability when being shared across disparate environments.
Remoting
With PowerShell 1.0, one of
its major disadvantages was the lack of an interface to execute commands
on a remote machine. Granted, you could use Windows Management
Instrumentation (WMI) to accomplish this and some cmdlets like
Get-Process and Get-Service, which enable you to connect to remote
machines. But, the concept of a native-based “remoting” interface was sorely missing when PowerShell was first
released. In fact, the lack of remote
command execution was a glaring lack of functionality that needed to be
addressed. Naturally, the PowerShell product team took this
functionality limitation to heart and addressed it by introducing a new
feature in PowerShell 2.0, called “remoting.”
Remoting, as its name suggests,
is a new feature that is designed to facilitate command (or script)
execution on remote machines. This could mean execution of a command or
commands on one remote machine or thousands of remote machines (provided
you have the infrastructure to support this). Additionally, commands
can be issued synchronously or asynchronously, one at time or through a
persistent connection called a runspace, and even scheduled or
throttled.
To use remoting, you
must have the appropriate permissions to connect to a remote machine,
execute PowerShell, and execute the desired command(s). In addition, the
remote machine must have PowerShell 2.0 and Windows Remote Management
(WinRM) installed, and PowerShell must be configured for remoting.
Additionally, when using
remoting, the remote PowerShell session that is used to execute commands
determines execution environment. As such, the commands you attempt to
execute are subject to a remote machine’s execution policies, profiles,
and preferences.
Warning
Commands that are
executed against a remote machine do not have access to information
defined within your local profile. As such, commands that use a function
or alias defined in your local profile will fail unless they are
defined on the remote machine as well.
How Remoting Works
In its most basic form,
PowerShell remoting works using the following conversation flow between
“a client” (most likely the machine with your PowerShell session) and “a
server” (remote host) that you want to execute command(s) against:
1. | A command
is executed on the client.
|
2. | That command is transmitted to the server.
|
3. | The server executes the command and then returns the
output to the client.
|
4. | The client displays or uses the returned output.
|
At a deeper level,
PowerShell remoting is very dependent on WinRM for facilitating the
command and output exchange between a “client” and “server.” WinRM,
which is a component of Windows Hardware Management, is a web-based
service that enables administrators to enumerate information on and
manipulate a remote machine. To handle remote sessions, WinRM was built
around a SOAP-based standards protocol called WS-Management. This
protocol is firewall-friendly, and was primarily developed for the
exchange of management information between systems that might be based
on a variety of operating systems on various hardware platforms.
When PowerShell uses WinRM to
ship commands and output between a client and server, that exchange is
done using a series of XML messages. The first XML message that is exchanged is a request to
the server, which contains the desired command to be executed. This
message is submitted to the server using the SOAP protocol. The server,
in return, executes the command using a new instance of PowerShell
called a runspace. Once execution of the command is complete, the output
from the command is returned to the requesting client as the second XML
message. This second message, like the first, is also communicated
using the SOAP protocol.
This translation into an
XML message is performed because you cannot ship “live” .NET objects
(how PowerShell relates to programs or system components) across the
network. So, to perform the transmission, objects are serialized into a
series of XML (CliXML) data elements. When the server or client receives
the transmission, it converts the received XML message into a
deserialized object type. The resulting object is no longer live.
Instead, it is a record of properties based on a point in time and, as
such, no longer possesses any methods.
Remoting Requirements
To use remoting, both the
local and remote computers must have the following:
Windows PowerShell 2.0 or later
Microsoft .NET Framework 2.0 or later
Windows Remote Management 2.0
Note
Windows Remote Management 2.0
is part of Windows 7 and Windows Server 2008 R2. For down-level versions
of Windows, an integrated installation package must be installed, which
includes PowerShell 2.0.
Configuring Remoting
By default, WinRM is installed
on all Windows Server 2008 R2 machines as part of the default operating
system installation. However, for security purposes, PowerShell remoting
and WinRM are, by default, configured to not allow remote connections.
You can use several methods to configure remoting, as described in the
following sections.
Method One
The first and easiest method
to enable PowerShell remoting is to execute the Enable-PSRemoting
cmdlet. For example:
PS C:\> enable-pssremoting
Once executed, the following
tasks are performed by the Enable-PSRemoting cmdlet:
Runs the
Set-WSManQuickConfig cmdlet, which performs the following tasks:
Starts the WinRM service.
Sets the startup type on the WinRM
service to Automatic.
Creates a listener to accept requests on any IP address.
Enables a firewall exception for WS-Management
communications.
Enables all registered Windows
PowerShell session configurations to receive instructions from a remote
computer.
Registers
the “Microsoft.PowerShell” session configuration, if it is not already
registered.
Registers
the “Microsoft.PowerShell32” session configuration on 64-bit computers,
if it is not already registered.
Removes the “Deny Everyone” setting from the
security descriptor for all the registered session configurations.
Restarts the WinRM
service to make the preceding changes effective.
Note
To configure PowerShell
remoting, the Enable-PSRemoting cmdlet must be executed using the Run As
Administrator option.
Method Two
The second method to
configure remoting is to use Server Manager. Use the following steps to
use this method:
1. | Open
Server Manager.
|
2. | In the
Server Summary area of the Server Manager home page, click Configure
Server Manager Remote Management.
|
3. | Next, select Enable Remote Management of This Server
from Other Computers.
|
4. | Click OK.
|
Method Three
Finally, the third method
to configure remoting is to use GPO. Use the following steps to use this
method:
1. | Create a
new GPO, or edit an existing one.
|
2. | Expand Computer Configuration, Policies, Administrative
Templates, Windows Components, Windows Remote Management, and then
select WinRM Service.
|
3. | Open the Allow Automatic Configuration of Listeners
Policy, select Enabled, and then define the IPv4 filter and IPv6 filter
as *.
|
4. | Click OK.
|
5. | Next, expand Computer Configuration, Policies, Windows
Settings, Security Settings, Windows Firewall with Advanced Security,
Windows Firewall with Advanced Security, and then Inbound Rules.
|
6. | Right-click Inbound Rules, and then click New Rule.
|
7. | In the New Inbound Rule Wizard, on the Rule Type page,
select Predefined.
|
8. | On the Predefined pull-down menu, select Remote Event
Log Management. Click Next.
|
9. | On
the Predefined Rules page, click Next to accept the new rules.
|
10. | On the Action page, select Allow the Connection, and
then click Finish. Allow the Connection is the default selection.
|
11. | Repeat steps 6 through 10 and create inbound rules for
the following predefined rule types:
|
Background Jobs
Another new feature that
was introduced in PowerShell 2.0 is the ability to use background jobs.
By definition, a background job is a command that is executed
asynchronously without interacting with the current PowerShell session.
However, once the background job has finished execution, the results
from these jobs can then be retrieved and manipulated based on the task
at hand. In other words, by using a background job, you can complete
automation tasks that take an extended period of time to run without
impacting the usability of your PowerShell session.
By default, background jobs
can be executed on the local computer. But, background jobs can also be
used in conjunction with remoting to execute jobs on a remote machine.
Note
To use background jobs
(local or remote), PowerShell must be configured for remoting.