Read Windows Server 2008 R2 Unleashed Online
Authors: Noel Morimoto
PSSnapin freshtastic, as follows:
PS C:\> Remove-PSSnapin freshtastic
Once the third-party snap-in has been unregistered, you will once again use
InstallUtil.exe with a /U switch to unregister the DLL, as follows:
PS C:\> & “$env:windir\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe” /U
freshtastic-automation.dll
Once the uninstall has completed, you can verify that the library file was successfully
unregistered by entering the command Get-PSSnapin -registered and verifying that no
ptg
third-party libraries are listed.
Using Modules
In Windows Server 2008 R2, a set of base modules are loaded when the operating system
is installed. Additionally, modules can be added or removed using the Add Features
Wizard in Server Manager.
Default Module Locations
There are two default locations for modules. The first location is for the machine, as follows:
$pshome\Modules (C:\Windows\system32\WindowsPowerShell\v1.0\Modules)
The second location is for the current user:
$home\Documents\WindowsPowerShell\Modules
(UserProfile%\Documents\WindowsPowerShell\Modules)
Installing New Modules
As mentioned previously, new modules can be added using the Add Features Wizard in
Server Manager. Additionally, other modules should come with an installation program
756
CHAPTER 21
Automating Tasks Using PowerShell Scripting
that will install the module for you. However, if need be, you can also manually install a
new module. To do this, use the following steps:
1. Create a new folder for the module that is being installed. For example:
PS C:\> New-Item -type directory -path
$home\Documents\WindowsPowerShell\Modules\Spammer1000
2. Copy the contents of the module into the newly created folder.
Using Installed Modules
After a module has been installed on a machine, it can then be imported into a
PowerShell session for usage. To find out what modules are available for use, use the Get-
Module cmdlet:
PS C:\> Get-Module -listAvailable
Or, to list modules that have already been imported into the current PowerShell session,
just use the Get-Module cmdlet without the listAvailable switch parameter:
PS C:\> Get-Module
ptg
Next, to import a module into a PowerShell session, use the Import-Module cmdlet. For
example, if the ActiveDirectory module has been installed, the following command
would be used:
PS C:\> Import-Module ActiveDirectory
NOTE
A complete path to the module folder must be provided for modules that are not locat-
ed in one of the default modules locations or any additional module locations that have
been defined for the current PowerShell session. This is required when using the
Import-Module cmdlet to define the module location used by the cmdlet.
Additionally, if you want to import all modules that are available on a machine into a
PowerShell session, one of two methods can be used. The first method is to execute the
following command, which lists all modules and then pipes that to the Import-Module
cmdlet:
PS C:\> Get-Module -listAvailable | Import-Module
The second method is to right-click the Windows PowerShell icon in the taskbar, and
then select Import System Modules. Additionally, you can also use the Windows
PowerShell Modules shortcut, which is found in Control Panel, System and Security,
Administrative Tools.
Using Windows PowerShell
757
NOTE
21
By default, modules are not loaded into any PowerShell session. To load modules by
default, the Import-Module cmdlet should be used in conjunction with a PowerShell pro-
file configuration script.
Removing a Module
The act of removing a module causes all the commands added by a module to be deleted
from the current PowerShell session. When a module is removed, the operation only
reverses the Import-Module cmdlet’s actions and does not uninstall the module from a
machine. To remove a module, use the Remove-Module cmdlet, as shown here:
PS C:\> Remove-Module ActiveDirectory
Using Remoting
When using remoting, three different modes can be used to execute commands. These
modes are as follows:
.
1 to 1—
Referred to as Interactive mode. This mode enables you to remotely manage
ptg
a machine similar to using an SSH session.
.
Many to 1—
Referred to as the Fan-In mode. This mode allows multiple administra-
tors to manage a single host using an interactive session.
.
1 to Many—
Referred to as the Fan-Out mode. This mode allows a command to exe-
cute across a large number of machines.
More information about each mode is provided in the following sections.
Interactive Remoting
With interactive remoting, the PowerShell session you are executing commands within
looks and feels very much like an SSH session, as shown in the following example:
PS C:\> enter-pssession abc-util01
[abc-util01]: PS C:\Users\administrator.COMPANYABC\Documents>
The key to achieving this mode of remoting is a PowerShell feature called a runspace.
Runspaces by definition are instances of the System.Management.Automation class, which
defines the PowerShell session and its host program (Windows PowerShell host, cmd.exe,
and so on). In other words, a runspace is an execution environment in which
PowerShell runs.
Not widely discussed in PowerShell 1.0, runspaces in PowerShell 2.0 are the method by
which commands are executed on local and remote machines. When a runspace is
created, it resides in the global scope and it is an environment upon itself, which includes
its own properties, execution polices, and profiles. This environment persists for the life-
time of the runspace, regardless of the volatility of the host machine’s environment.
758
CHAPTER 21
Automating Tasks Using PowerShell Scripting
Being tied to the host program that created it, a runspace ceases to exist when the host
program is closed. When this happens, all aspects of the runspace are gone, and you can
no longer retrieve or use the runspace. However, when created on a remote machine, a
runspace will remain until it is stopped.
To create a runspace on a machine, you can use two cmdlets. The first cmdlet, Enter-
PSSession, is used to create an interactive PowerShell session. This is the cmdlet that was
shown in the previous example. When this cmdlet is used against a remote machine, a
new runspace (PowerShell process) is created and a connection is established from the
local machine to the runspace on the remote computer. If executed against the local
machine, a new runspace (PowerShell process) is created and connection is established
back to the local machine. To close the interactive session, you would use the Exit-
PSSession cmdlet or the exit alias.
Fan-In Remoting
Fan-In remoting is named in reference to the ability for multiple administrators to open
their own runspaces at the same time. In other words, many administrators can “Fan-In”
from many machines into a single machine. When connected, each administrator is then
limited to the scope of their own runspace. This partitioning of access can be achieved
thanks to the new PowerShell 2.0 security model, which allows for the creation of
restricted shells and cmdlets.
ptg
However, the steps needed to fully utilize the new security model require a degree of soft-
ware development using the .NET Framework. The ability of being able to provide secure
partitioned remote management access on a single host to a number of different adminis-
trators is a very powerful feature. Usage could range from a web hosting company
wanting to partition remote management access to each customer for each of their
websites to internal IT departments wanting to consolidate their management consoles on
a single server.
Fan-Out Remoting
Fan-Out remoting is named in reference to the ability to issue commands to a number of
remote machines at once. When using this method of remoting, command(s) are issued
on your machine. These commands then “Fan-Out” and are executed on each of the
remote machines that have been specified. The results from each remote machine are then
returned to your machine in the form of an object, which you can then review or further
work with—in other words, the basic definition for how remoting was defined earlier in
this chapter.
Ironically enough, PowerShell has always supported the concept of Fan-Out remoting. In
PowerShell 1.0, Fan-Out remoting was achieved using WMI. For example, you could always
import a list of machine names and then use WMI to remotely manage those machines:
PS C:\> import-csv machineList.csv | foreach {Get-WmiObject Win32_
➥NetworkAdapterConfiguration -computer $_.MachineName}
Although the ability to perform Fan-Out remoting in PowerShell 1.0 using WMI was a
powerful feature, this form of remoting suffered in usability because it was synchronous in
Using Windows PowerShell
759
nature. In other words, once a command had been issued, it was executed on each remote
machine one at a time. While this happened, further command execution had to wait until
21
the command issued had finished being executed on all the specified remote machines.
Needless to say, attempting to synchronously manage a large number of remote machines
can prove to be a challenging task. To address this challenge in PowerShell 2.0, the
product team tweaked the remoting experience such that Fan-Out remoting could be done
asynchronously. With these changes, you could still perform remote WMI management,
as shown in the previous example. However, you can also asynchronously execute remote
commands using the following methods:
. Executing the command as a background job
. Using the Invoke-Command cmdlet
. Using the Invoke-Command cmdlet with a reusable runspace
The first method, a background job, as its name might suggest, allows commands to be
executed in the background. Although not truly asynchronous, a command that is
executed as a background job enables you to continue executing additional commands
while the job is being completed. For example, to run the previously shown WMI
example as a background job, you can simply add the AsJob parameter for the Get-
ptg
WmiObject cmdlet:
PS C:\> import-csv machineList.csv | foreach {Get-WmiObject Win32_
➥NetworkAdapterConfiguration -computer $_.MachineName -asjob}
With the AsJob parameter (new in PowerShell 2.0) being used, each time the Get-
WmiObject cmdet is called in the foreach loop, a new background job is created to
complete execution of the cmdlet. Although more details about background jobs are
provided later in this chapter, this example shows how background jobs can be used to
achieve asynchronous remote command execution when using WMI.
The second method to asynchronously execute remote commands is by using the new
cmdlet called Invoke-Command. This cmdlet is new in PowerShell 2.0, and it enables you
to execute commands both locally and remotely on machines—unlike WMI, which uses
remote procedure calls (RPC) connections to remotely manage machines. The Invoke-
Command cmdlet utilizes WinRM to push the commands out to each of the specified
“targets” in an asynchronous manner.
To use the cmdlet, two primary parameters need to be defined. The first parameter,
ScriptBlock, is used to specify a scriptblock, which contains the command to be
executed. The second parameter, ComputerName (NetBIOS name or IP address), is used to
specify the machine or machines to execute the command that is defined in the script-
block. For example:
PS C:\> invoke-command -scriptblock {get-process} -computer sc1-infra01,sc1-infra02
760
CHAPTER 21
Automating Tasks Using PowerShell Scripting
Additionally, the Invoke-Command cmdlet also supports a set of parameters that make it
an even more powerful vehicle to conduct remote automation tasks with. These parame-
ters are described in Table 21.4.
TABLE 21.4
Important Invoke-Command Cmdlet Parameters
Parameter
Details
AsJob
Used to execute the command as a background job
Credential
Used to specify alternate credentials that are used to execute the specified
command(s)
ThrottleLimit
Used to specify the maximum number of connections that can be established
by the Invoke-Command cmdlet
Session
Used to execute the command in the specified PSSessions
As discussed previously, the AsJob parameter is used to execute the specified command as
a background job. However, unlike the Get-WmiObject cmdlet, when the AsJob parameter
is used with the Invoke-Command cmdlet, a background job is created on the client
ptg
machine, which then spawns a number of child background job(s) on each of the speci-
fied remote machine(s). Once execution of a child background job is finished, the result(s)
are returned to the parent background job on the client machine.
Needless to say, if there are a large number of remote machines defined using the