Tải bản đầy đủ (.pdf) (50 trang)

Tài liệu Windows 7 Resource Kit- P11 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.07 MB, 50 trang )

Introduction to Windows PowerShell Scripting CHAPTER 13
453
Including Functions
In Windows PowerShell 1.0 you could include functions from previously written scripts by
dot-sourcing the script, but the use of a module offers greater flexibility because of the ability
to create a module manifest that specifies exactly which functions and programming elements
will be imported into the current session.
diReCt FRoM tHe SoURCe
Scopes and Dot-Sourcing
James O’Neill, Evangelist
Developer and Platform Group
W
indows PowerShell has three logical drives that can be thought of as holding
the variables ENV: (which holds environment variables), VARIABLE: (which
holds Windows PowerShell variables), and FUNCTION: (which holds Windows
PowerShell functions). You can refer to the contents of an environment variable as
$ENV:name. Windows PowerShell also has the concept of scopes, which can be sum-
marized as “what happens in the script, stays in the script.” That is, a variable, alias,
or function that is changed in a script won’t affect the Windows PowerShell environ-
ment after the script terminates. This is usually a good thing. Actions taken at the
command prompt affect a global scope, and scripts and functions only affect their
local scope. A function that must change something in the global scope can explic-
itly work on $Global:name. However, this still presents a problem for scripts that set
variables we want to use later in the session or that load functions because, as soon
the script is completed, the variables and functions are lost. Windows PowerShell
allows a command to be prefixed with a dot (.) character. The dot operator says
“Run this command in the current scope and not in a scope of its own,” a process
that is known as “dot-sourcing.”
Using Dot-Sourcing
This technique of dot-sourcing still works in Windows PowerShell 2.0, and it offers the
advantage of simplicity and familiarity. In the TextFunctions.ps1 script, two functions are


created. The first function is called New-Line. The second function is called Get-TextStatus.
The TextFunctions.ps1 script is seen here.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
454
TextFunctions.ps1
Function New-Line([string]$stringIn)
{
"-" * $stringIn.length
} #end New-Line

Function Get-TextStats([string[]]$textIn)
{
$textIn | Measure-Object -Line -word -char
} #end Get-TextStats
The New-Line function will create a line that is the length of an input text. This is helpful
when you want an underline for text separation purposes that is sized to the text. Traditional
VBScript users copy the function they need to use into a separate file and run the newly pro-
duced script. An example of using the New-Line text function in this manner is seen here.
CallNew-LineTextFunction.ps1
Function New-Line([string]$stringIn)
{
"-" * $stringIn.length
} #end New-Line

Function Get-TextStats([string[]]$textIn)
{
$textIn | Measure-Object -Line -word -char
} #end Get-TextStats


# *** Entry Point to script ***
"This is a string" | ForEach-Object {$_ ; New-Line $_}
When the script runs, it returns the following output.
This is a string

Of course, this is a bit inefficient, and it limits your ability to use the functions. If you have
to copy the entire text of a function into each new script you want to produce or edit a script
each time you want to use a function in a different manner, you dramatically increase your
workload. If the functions were available all the time, you might be inclined to use them more
often. To make the text functions available in your current Windows PowerShell console, you
need to dot-source the script containing the functions into your console. You will need to use
the entire path to the script unless the folder that contains the script is in your search path.
The syntax to dot-source a script is so easy, it actually becomes a stumbling block for some
people who are expecting some complex formula or cmdlet with obscure parameters. It is
none of that—just a period (dot) and the path to the script that contains the function. This is
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
455
why it is called dot-sourcing: you have a dot and the source (path) to the functions you want
to include as seen here.
PS C:\> . C:\fso\TextFunctions.ps1
When you include the functions into your current console, all the functions in the source
script are added to the Function drive. This is seen in Figure 13-36.
FIGURE 13-36 Functions from a dot-sourced script are available via the Function drive.
Using Dot-Sourced Functions
When the functions have been introduced to the current console, you can incorporate them
into your normal commands. This flexibility should also influence the way you write the func-
tion. If you write the functions so they will accept pipelined input and do not change the
system environment (by adding global variables, for example), you will be much more likely
to use the functions, and they will be less likely to conflict with either functions or cmdlets

that are present in the current console.
As an example of using the New-Line function, consider the fact that the Get-WmiObject
cmdlet allows the use of an array of computer names for the –computername parameter. The
problem is that the output is confusing, because you do not know which piece of information
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
456
is associated with which output. In this example, basic input/output system (BIOS) information
is obtained from two separate workstations.
PS C:\> Get-WmiObject -Class Win32_bios -ComputerName berlin, vista

SMBIOSBIOSVersion : 080002
Manufacturer : A. Datum Corporation
Name : BIOS Date: 02/22/06 20:54:49 Ver: 08.00.02
SerialNumber : 2096-1160-0447-0846-3027-2471-99
Version : A D C - 2000622

SMBIOSBIOSVersion : 080002
Manufacturer : A. Datum Corporation
Name : BIOS Date: 02/22/06 20:54:49 Ver: 08.00.02
SerialNumber : 2716-2298-1514-1558-4398-7113-73
Version : A D C - 2000622
You can improve the display of the information returned by Get-WmiObject by pipelin-
ing the output to the New-Line function so that you can underline each computer name
as it comes across the pipeline. You do not need to write a script to produce this kind of
display. You can type the command directly into the Windows PowerShell console. The first
thing you need to do is to dot-source the TextFunctions.ps1 script. This makes the functions
directly available in the current Windows PowerShell console session. You then use the same
Get-WmiObject query that you used earlier to obtain BIOS information via WMI from two
computers. Pipeline the resulting management objects to the ForEach-Object cmdlet. Inside

the script block section, you use the $_ automatic variable to reference the current object
on the pipeline and retrieve the System.Management.ManagementPath object. From the
ManagementPath object, you can obtain the name of the server that is supplying the infor-
mation. You send this information to the New-Line function so the server name is underlined,
and you display the BIOS information that is contained in the $_ variable.
The command to import the New-Line function into the current Windows PowerShell
session and use it to underline the server names is shown here.
PS C:\> . C:\fso\TextFunctions.ps1
PS C:\> Get-WmiObject -Class win32_Bios -ComputerName vista, berlin |
>> ForEach-Object { $_.Path.Server ; New-Line $_.Path.Server ; $_ }
The results of using the New-Line function are seen in Figure 13-37.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
457
FIGURE 13-37 Functions that are written to accept pipelined input will find an immediate
use in your daily work routine.
The Get-TextStats function from the TextFunctions.ps1 script provides statistics based on
an input text file or text string. When the TextFunctions.ps1 script is dot-sourced into the cur-
rent console, the statistics that it returns when the function is called are word count, number
of lines in the file, and number of characters. An example of using this function is seen here.
Get-TextStats "This is a string"
When the Get-TextStats function is used, the following output is produced.
Lines Words Characters Property

1 4 16
In this section, the use of functions was discussed. The reuse of functions could be as
simple as copying the text of the function from one script into another script. It is easier to
dot-source the function. This can be done from within the Windows PowerShell console or
from within a script.
Adding Help for Functions

There is one problem that is introduced when dot-sourcing functions into the current Windows
PowerShell console. Because you are not required to open the file that contains the function
to use it, you may be unaware of everything the file contains within it. In addition to functions,
the file could contain variables, aliases, Windows PowerShell drives, or a wide variety of other
things. Depending on what you are actually trying to accomplish, this may or may not be an
issue. The need arises, however, to have access to help information about the features pro-
vided by the Windows PowerShell script.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
458
Using the here-string Technique for Help
In Windows PowerShell 1.0, you could solve this problem by adding a –help parameter to the
function and storing the help text within a here-string. You can use this approach in Windows
PowerShell 2.0 as well, but as discussed in the next section, there is a better approach to
providing help for functions. The classic here-string approach for help is seen in the
GetWmiClassesFunction.ps1 script. The first step that needs to be done is to define a switched
parameter named $help. The second step involves creating and displaying the results of a
here-string that includes help information. The GetWmiClassesFunction.ps1 script is shown here.
GetWmiClassesFunction.ps1
Function Get-WmiClasses(
$class=($paramMissing=$true),
$ns="root\cimv2",
[switch]$help
)
{
If($help)
{
$helpstring = @"
NAME
Get-WmiClasses

SYNOPSIS
Displays a list of WMI Classes based upon a search criteria
SYNTAX
Get-WmiClasses [[-class] [string]] [[-ns] [string]] [-help]
EXAMPLE
Get-WmiClasses -class disk -ns root\cimv2"
This command finds wmi classes that contain the word disk. The
classes returned are from the root\cimv2 namespace.
"@
$helpString
break #exits the function early
}
If($local:paramMissing)
{
throw "USAGE: getwmi2 -class <class type> -ns <wmi namespace>"
} #$local:paramMissing
"`nClasses in $ns namespace "
Get-WmiObject -namespace $ns -list |
where-object {
$_.name -match $class -and `
$_.name -notlike 'cim*'
}
# end Get-WmiClasses function} #end get-wmiclasses
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
459
The here-string technique works fairly well for providing function help. If you follow the
cmdlet help pattern, it works well, as seen in Figure 13-38.
FIGURE 13-38 Manually created help can mimic the look of core cmdlet help.
The drawback to manually creating help for a function is that it is tedious. As a result, only

the most important functions receive help information when using this methodology. This is
unfortunate, because it then requires the user to memorize the details of the function contract.
One way to work around this is to use the Get-Content cmdlet to retrieve the code that was
used to create the function. This is much easier to do than searching for the script that was used
to create the function and opening it in Notepad. To use the Get-Content cmdlet to display the
contents of a function, you type Get-Content and supply the path to the function. All functions
available to the current Windows PowerShell environment are available via the PowerShell
Function drive. You can therefore use the following syntax to obtain the content of a function.
PowerShell C:\> Get-Content Function:\Get-WmiClasses
The technique of using Get-Content to read the text of the function is seen in Figure 13-39.
FIGURE 13-39 The Get-Content cmdlet can retrieve the contents of a function.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
460
Using –help Function Tags to Produce Help
Much of the intensive work of producing help information for your functions is removed
when you use the stylized –help function tags that are available in Windows PowerShell 2.0.
To use the help function tags, you place the tags inside the block comment tags when you are
writing your script. When you write help for your function and employ the –help tags, the use
of the tags allows for complete integration with the Get-Help cmdlet. This provides a seamless
user experience for those utilizing your functions. In addition, it promotes the custom user-
defined function to the same status within Windows PowerShell as native cmdlets. The experi-
ence of using a custom user-defined function is no different than using a cmdlet, and indeed,
to the user there is no need to distinguish between a custom function that was dot-sourced
or loaded via a module or a native cmdlet. The –help function tags and their associated
meanings are shown in Table 13-3.
TABLE 13-3 Function –help Tags and Meanings
HELP TAG NAME HELP TAG DESCRIPTION
.Synopsis A very brief description of the function. It begins with a verb and
informs the user as to what the function does. It does not include the

function name or how the function works. The function synopsis
appears in the SYNOPSIS field of all help views.
.Description Two or three full sentences that briefly list everything that the function
can do. It begins with “The <function name> function…” If the function
can get multiple objects or take multiple inputs, use plural nouns in the
description. The description appears in the DESCRIPTION field of all help
views.
.Parameter Brief and thorough. Describes what the function does when the para-
meter is used and the legal values for the parameter. The parameter
appears in the PARAMETERS field only in Detailed and Full help views.
.Example Illustrates the use of a function with all its parameters. The first example
is simplest with only the required parameters; the last example is most
complex and should incorporate pipelining if appropriate. The example
appears in the EXAMPLES field only in the Example, Detailed, and Full
help views.
.Inputs Lists the .NET Framework classes of objects that the function will accept
as input. There is no limit to the number of input classes you may list.
The inputs appear in the INPUTS field only in the Full help view.
.Outputs Lists the .NET Framework classes of objects that the function will emit as
output. There is no limit to the number of output classes you may list.
The outputs appear in the OUTPUTS field only in the Full help view.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
461
HELP TAG NAME HELP TAG DESCRIPTION
.Notes Provides a place to list information that does not fit easily into the other
sections. This can be special requirements required by the function, as
well as author, title, version, and other information. The notes appear in
the NOTES field only in the Full help view.
.Link Provides links to other Help topics and Internet sites of interest. Because

these links appear in a command window, they are not direct links.
There is no limit to the number of links you may provide. The links ap-
pear in the RELATED LINKS field in all help views.
You do not need to supply values for all the –help tags. As a best practice, however, you
should consider supplying the .Synopsis and the .Example tags, because these provide the
most critical information required to assist a person in learning how to use the function.
An example of using the –help tags is shown in the GetWmiClassesFunction1.ps1 script.
The help information provided is exactly the same as the information provided by the
GetWmiClassesFunction.ps1 script. The difference happens with the use of the –help tags.
First, you will notice that there is no longer a need for the switched $help parameter. The
reason for not needing the switched $help parameter is the incorporation of the code with
the Get-Help cmdlet. When you do not need to use a switched $help parameter, you also do
not need to test for the existence of the $help variable. By avoiding the testing for the $help
variable, your script can be much simpler. You gain several other bonuses by using the special
–help tags. These bonus features are listed here:
n
The name of the function is displayed automatically and displayed in all help views.
n
The syntax of the function is derived from the parameters automatically and displayed
in all help views.
n
Detailed parameter information is generated automatically when the –full parameter
of the Get-Help cmdlet is used.
n
Common parameters information is displayed automatically when Get-Help is used
with the –detailed and –full parameters.
In the GetWmiClassesFunction.ps1 script, the Get-WmiClasses function begins the help
section with the Windows PowerShell 2.0 multiline comment block. The multiline comment
block special characters begin with the left angle bracket followed with a pound sign (<#)
and end with the pound sign followed by the right angle bracket (#>). Everything between

the multiline comment characters is considered to be commented out. Two special –help tags
are included: the .Synopsis and the .Example tags. The other –help tags that are listed in Table
13-3 are not used for this function.
<#
.SYNOPSIS
Displays a list of WMI Classes based upon a search criteria
.EXAMPLE
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
462
Get-WmiClasses -class disk -ns root\cimv2"
This command finds wmi classes that contain the word disk. The
classes returned are from the root\cimv2 namespace.
#>
When the GetWmiClassesFunction.ps1 script is dot-sourced into the Windows PowerShell
console, you can use the Get-Help cmdlet to obtain help information from the Get-WmiClasses
function. When the Get-Help cmdlet is run with the –full parameter, the help display seen in
Figure 13-40 appears.
FIGURE 13-40 Full help obtained from the function Get-WmiClasses
The complete GetWmiClassesFunction.ps1 script is seen here.
GetWmiClassesFunction1.ps1
Function Get-WmiClasses(
$class=($paramMissing=$true),
$ns="root\cimv2"
)
{
<#
.SYNOPSIS
Displays a list of WMI Classes based upon a search criteria
.EXAMPLE

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
463
Get-WmiClasses -class disk -ns root\cimv2"
This command finds wmi classes that contain the word disk. The
classes returned are from the root\cimv2 namespace.
#>
If($local:paramMissing)
{
throw "USAGE: getwmi2 -class <class type> -ns <wmi namespace>"
} #$local:paramMissing
"`nClasses in $ns namespace "
Get-WmiObject -namespace $ns -list |
where-object {
$_.name -match $class -and `
$_.name -notlike 'cim*'
}
#
} #end get-wmiclasses
If you intend to use the dot-source method for including functions into your working
Windows PowerShell environment, it makes sense to add the directory that contains your
scripts to the path. You can add your function Storage directory as a permanent change by
using the Windows GUI tools, or you can simply make the addition to your path each time
you start Windows PowerShell by making the change via your PowerShell profile. If you decide
to add your Function directory by using Windows PowerShell commands, you can use the
PowerShell Environmental drive to access the system path variable and make the change. The
code seen here first examines the path, and then it appends the C:\Fso folder to the end of
the path. Each directory that is added to the search path is separated by a semicolon. When
you append a directory to the path, you must include that semicolon as the first item that is
added. You can use the += operator to append a directory to the end of the path. The last

command checks the path once again to ensure the change took place as intended.
PS C:\> $env:path
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32
\Windows System Resource Manager\bin;C:\Windows\idmu\common;C:\Windows\system32
\WindowsPowerShell\v1.0\
PS C:\> $env:path += ";C:\fso"
PS C:\> $env:path
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32
\Windows System Resource Manager\bin;C:\Windows\idmu\common;C:\Windows\system32
\WindowsPowerShell\v1.0\;C:\fso
A change made to the path via the Windows PowerShell Environmental drive is temporary; it
only lasts for the length of the current PowerShell console session. It will take effect immediate-
ly, and therefore it is a convenient method to alter your current Windows PowerShell environ-
ment quickly without making permanent changes to your system environmental settings.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
464
A very powerful feature of modifying the path via the Windows PowerShell Environmental
drive is that the changes are applied immediately and are at once available to the current
PowerShell session. This means you can add a directory to the path, dot-source a script that
contains functions, and use the Get-Help cmdlet to display help information without the re-
quirement to close and to open Windows PowerShell. After a directory has been appended to
the search path, you can dot-source scripts from that directory without the need to type the
entire path to that directory. The technique of modifying the path, dot-sourcing a directory,
and using Get-Help is illustrated here.
PS C:\> $env:Path += ";C:\fso"
PS C:\> . GetWmiClassesFunction1.ps1
PS C:\> Get-Help Get-WmiClasses
Figure 13-41 displays the results of using the technique of adding a directory to the path,
dot-sourcing a script that resides in the newly appended folder, and then calling the Get-Help

cmdlet to retrieve information from the newly added functions.
FIGURE 13-41 By appending to the path, functions can be dot-sourced easily into the
current Windows PowerShell environment.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
465
diReCt FRoM tHe SoURCe
Folders and Locations
James O’Neill, Evangelist
Developer and Platform Group
I
f you type DIR Variable: you will see the locations Windows PowerShell uses to
get its configuration information. $PSHome holds the folder where Windows
PowerShell is installed, and this contains .PS1XML files, which control the default for-
matting and type extensions. It also contains language folders that hold the Windows
PowerShell online help and a Modules folder. $Profile contains the path to the user’s
profile, which is a script that is run when Windows PowerShell starts. In fact, Windows
PowerShell supports four profiles—two that are host specific, and two for all hosts.
One of each kind is for the current user, and the other of each kind applies to all
users. You can see these as properties of $Profile named .AllUsersAllHosts,
AllUsersCurrentHost, CurrentUserAllHosts, and CurrentUserCurrentHost. Windows
PowerShell uses a Windows environment variable, $env:psModulePath, to determine
where modules should be located. The default is the $PSHome folder and the folder
containing the users profile.
Locate and Load Modules
There are two default locations for Windows PowerShell modules. The first location is found
in the user’s Home directory, and the second is in the Windows PowerShell Home directory.
The Modules directory in the Windows PowerShell Home directory always exists. However,
the Modules directory in the user’s Home directory is not present by default. The Modules
directory will exist only in the user’s Home directory if it has been created. The creation of

the Modules directory in the user’s Home directory does not normally happen until someone
decides to create and to store modules there. A nice feature of the Modules directory is that
when it exists, it is the first place that Windows PowerShell uses when it searches for a mod-
ule. If the user’s Modules directory does not exist, the Modules directory within the Windows
PowerShell Home directory is used.
Listing Available Modules
Windows PowerShell modules exist in two states: loaded and unloaded. To display a list of all
loaded modules, use the Get-Module cmdlet without any parameters, as shown here.
PS C:\> Get-Module

ModuleType Name ExportedCommands

Script helloworld {Hello-World, Hello-User}
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
466
If multiple modules are loaded when the Get-Module cmdlet is run, each module will ap-
pear along with its accompanying exported commands on their own individual lines, as seen
here.
PS C:\> Get-Module

ModuleType Name ExportedCommands

Script GetFreeDiskSpace Get-FreeDiskSpace
Script HelloWorld {Hello-World, Hello-User}
Script TextFunctions {New-Line, Get-TextStats}
Manifest BitsTransfer {Start-BitsTransfer, Remove-BitsTransfe
Script PSDiagnostics {Enable-PSTrace, Enable-WSManTrace, Sta



PS C:\>
If no modules are loaded, nothing will be displayed to the Windows PowerShell console.
No errors are displayed, nor is there any confirmation that the command has actually run, as
shown here.
PS C:\> Get-Module
PS C:\>
To obtain a listing of all modules that are available on the system but are not loaded, you
use the Get-Module cmdlet with the –ListAvailable parameter. The Get-Module cmdlet with
the –ListAvailable parameter lists all modules that are available whether or not the modules
are loaded into the Windows PowerShell console, as seen here.
PS C:\> Get-Module -ListAvailable

ModuleType Name ExportedCommands

Manifest GetFreeDiskSpace Get-FreeDiskSpace
Script HelloWorld {}
Script TextFunctions {}
Manifest BitsTransfer {}
Manifest PSDiagnostics {Enable-PSTrace, Enable-WSManTrace, Sta
Loading Modules
After you identify a module you want to load, you use the Import-Module cmdlet to load the
module into the current Windows PowerShell session, as shown here.
PS C:\> Import-Module -Name GetFreeDiskSpace
PS C:\>
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
467
If the module exists, the Import-Module cmdlet completes without displaying any infor-
mation. If the module is already loaded, no error message is displayed. This is seen in the
code here, where you use the up arrow to retrieve the previous command and press Enter to

execute the command. The Import-Module command is run three times.
PS C:\> Import-Module -Name GetFreeDiskSpace
PS C:\> Import-Module -Name GetFreeDiskSpace
PS C:\> Import-Module -Name GetFreeDiskSpace
PS C:\>
After you import the module, you may want to use the Get-Module cmdlet to quickly see
what functions are exposed by the module, as seen here.
PS C:\> Get-Module -Name GetFreeDiskSpace

ModuleType Name ExportedCommands

Script GetFreeDiskSpace Get-FreeDiskSpace


PS C:\>
The GetFreeDiskSpace module exports a single command: the Get-FreeDiskSpace function.
The one problem with using the Get-Module cmdlet is that it does not include other informa-
tion that could be exported by the module. It lists only commands.
When working with modules that have long names, you are not limited to typing the en-
tire module name. You are allowed to use wildcards. When using wildcards, it is a best prac-
tice to type a significant portion of the module name so that you match only a single module
from the list of modules that are available to you, as seen here.
PS C:\> Import-Module -Name GetFree*
PS C:\>
iMpoRtAnt If you use a wildcard pattern that matches more than one module name,
the first matched module is loaded, and the remaining matches are discarded. This can
lead to inconsistent and unpredictable results. No error message is displayed when more
than one module matches a wildcard pattern.
If you want to load all the modules that are available on your system, you can use the
Get-Module cmdlet with the –ListAvailable parameter and pipeline the resulting

PSModuleInfo objects to the Import-Module cmdlet as seen here.
PS C:\> Get-Module -ListAvailable | Import-Module
PS C:\>
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
468
If you have a module that uses a verb that is not on the allowed verb list, a warning mes-
sage displays when you import the module. The functions in the module still work, and the
module will work, but the warning is displayed to remind you to check the authorized verb
list, as seen here.
PS C:\> Get-Module -ListAvailable | Import-Module
WARNING: Some imported command names include unapproved verbs which might make
them less discoverable. Use the Verbose parameter for more detail or type
Get-Verb to see the list of approved verbs.
PS C:\>
To obtain more information about which unapproved verbs are being used, you use the
–verbose parameter of Import-Module. This command is seen here.
PS C:\> Get-Module -ListAvailable | Import-Module –Verbose
The results of the Import-Module –verbose command are seen in Figure 13-42.
FIGURE 13-42 The –verbose parameter of Import-Module displays information about each
function, as well as illegal verb names.
Install Modules
One of the features of modules is that they can be installed without elevated rights. Because
each user has a Modules folder in the %UserProfile% directory that he or she has the right to
use, the installation of a module does not require administrator rights. An additional fea-
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
469
ture of modules is that they do not require a specialized installer. The files associated with a
module can be copied by using the XCopy utility, or they can be copied by using Windows

PowerShell cmdlets.
Creating a Modules Folder
The user’s Modules folder does not exist by default. To avoid confusion, you may decide to
create the Modules directory in the user’s profile prior to deploying modules, or you may
simply create a module installer script that checks for the existence of the user’s Modules
folder, creates the folder if it does not exist, and then copies the modules. One thing to re-
member when directly accessing the user’s Modules directory is that it is in a different
location depending on the version of the operating system. On Windows XP and Windows
Server 2003, the user’s Modules folder is in the My Documents folder, whereas on Windows
Vista and later versions, the user’s Modules folder is in the Documents folder. In the Copy-
Modules.ps1 script, you solve the problem of different Modules folder locations by using a
function, Get-OperatingSystemVersion, that retrieves the major version number of the operat-
ing system. The Get-OperatingSystemVersion function is seen here.
Function Get-OperatingSystemVersion
{
(Get-WmiObject -Class Win32_OperatingSystem).Version
} #end Get-OperatingSystemVersion
The major version number of the operating system is used in the Test-ModulePath func-
tion. If the major version number of the operating system is greater than or equal to 6, it
means the operating system is at least Windows Vista and will therefore use the Documents
folder in the path to the modules. If the major version number of the operating system is
less than 6, the script will use the My Documents folder for the module location. After you
have determined the version of the operating system and have ascertained the path to the
module location, it is time to determine whether the Modules folder exists. The best tool to
use for checking the existence of folders is the Test-Path cmdlet. The Test-Path cmdlet returns
a Boolean value. As you are only interested in the absence of the folder, you can use the –not
operator, as shown here in the completed Test-ModulePath function.
Function Test-ModulePath
{
$VistaPath = "$env:userProfile\documents\WindowsPowerShell\Modules"

$XPPath = "$env:Userprofile\my documents\WindowsPowerShell\Modules"
if ([int](Get-OperatingSystemVersion).substring(0,1) -ge 6)
{
if(-not(Test-Path -path $VistaPath))
{
New-Item -Path $VistaPath -itemtype directory | Out-Null
} #end if
} #end if
Else
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
470
{
if(-not(Test-Path -path $XPPath))
{
New-Item -path $XPPath -itemtype directory | Out-Null
} #end if
} #end else
} #end Test-ModulePath
After the user’s Modules folder has been created, it is time to create a child folder to hold
the new module. A module is always installed into a folder that has the same name as the
module itself. The name of the module is the file name that contains the module without the
.psm1 extension. This location is shown in Figure 13-43.
FIGURE 13-43 Modules are placed in the user’s Modules directory.
In the Copy-Module function from the Copy-Modules.ps1 script, the first action that is
taken is to retrieve the value of the PSModulePath environment variable. Because there are
two locations that modules can be stored, the PSModulePath environment variable contains
the path to both locations. PSModulePath is not stored as an array; it is stored as a string. The
value contained in PSModulePath is seen here.
PS C:\> $env:psmodulePath

C:\Users\administrator.NWTRADERS.000\Documents\WindowsPowerShell\Modules;C:\Windows
\System32\WindowsPowerShell\V1.0\Modules\
If you attempt to index into the data stored in the PSModulePath environment variable,
you will retrieve one letter at a time, as seen here.
PS C:\> $env:psmodulePath[0]
C
PS C:\> $env:psmodulePath[1]
:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
471
PS C:\> $env:psmodulePath[2]
\
PS C:\> $env:psmodulePath[3]
U
Attempting to retrieve the path to the user’s Modules folder one letter at a time would
be difficult at best and error-prone at worst. Because the data is a string, you can use string
methods to manipulate the two paths. To break a string into an array that can be utilized
easily, you use the split method from the System.String class. You need only to pass a single
value to the split method—the character to split upon. Because the value stored in the
PSModulePath variable is a string, you can access the split method directly, as shown here.
PS C:\> $env:psmodulePath.split(";")
C:\Users\administrator.NWTRADERS.000\Documents\WindowsPowerShell\Modules
C:\Windows\System32\WindowsPowerShell\V1.0\Modules\
You can see from this output that the first string displayed is the path to the user’s Mod-
ules folder, and the second path is the path to the system Modules folder. Because the split
method turns a string into an array, it means you can now index into the array and retrieve
the path to the user’s Modules folder by using the [0] syntax. You do not need to use an
intermediate variable to store the returned array of paths if you do not want to do so. You can
index into the returned array directly. If you were to use the intermediate variable to hold the

returned array and then index into the array, the code would resemble the following.
PS C:\> $aryPaths = $env:psmodulePath.split(";")
PS C:\> $aryPaths[0]
C:\Users\administrator.NWTRADERS.000\Documents\WindowsPowerShell\Modules
Because the array is immediately available after the split method has been called, you
directly retrieve the user’s Modules folder, as seen here.
PS C:\> $env:psmodulePath.split(";")[0]
C:\Users\administrator.NWTRADERS.000\Documents\WindowsPowerShell\Modules
Working with the $modulePath Variable
The path that will be used to store the module is stored in the $modulePath variable. This
path includes the path to the user’s Modules folder and a child folder that is the same name
as the module itself. To create the new path, it is a best practice to use the Join-Path cmdlet
instead of doing string concatenation and attempting to build the path to the new folder
manually. The Join-Path cmdlet will put together a parent path and a child path to create a
new path, as seen here.
$ModulePath = Join-Path -path $userPath `
-childpath (Get-Item -path $name).basename
In Windows PowerShell 2.0, the PowerShell team added a script property called basename
to the System.Io.FileInfo class. This makes it easy to retrieve the name of a file without the file
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
472
extension. Prior to Windows PowerShell 2.0, it was common to use the split method or some
other string manipulation technique to remote the extension from the file name. Use of the
basename property is shown here.
PS C:\> (Get-Item -Path C:\fso\HelloWorld.psm1).basename
HelloWorld
The last step that needs to be accomplished is to create the subdirectory that will hold
the module and to copy the module files into the directory. To avoid cluttering the display
with the returned information from the New-Item and the Copy-Item cmdlets, the results are

pipelined to the Out-Null cmdlet, as seen here.
New-Item -path $modulePath -itemtype directory | Out-Null
Copy-item -path $name -destination $ModulePath | Out-Null
The entry point to the Copy-Modules.ps1 script calls the Test-ModulePath function to
determine whether the user’s Modules folder exists. It then uses the Get-ChildItem cmdlet to
retrieve a listing of all the module files in a particular folder. The –Recurse parameter is used
to retrieve all the module files in the path. The resulting FileInfo objects are pipelined to the
ForEach-Object cmdlet. The fullname property of each FileInfo object is passed to the
Copy-Module function, as shown here.
Test-ModulePath
Get-ChildItem -Path C:\fso -Include *.psm1,*.psd1 -Recurse |
Foreach-Object { Copy-Module -name $_.fullName }
The complete Copy-Modules.ps1 script is seen here.
Copy-Modules.ps1
Function Get-OperatingSystemVersion
{
(Get-WmiObject -Class Win32_OperatingSystem).Version
} #end Get-OperatingSystemVersion

Function Test-ModulePath
{
$VistaPath = "$env:userProfile\documents\WindowsPowerShell\Modules"
$XPPath = "$env:Userprofile\my documents\WindowsPowerShell\Modules"
if ([int](Get-OperatingSystemVersion).substring(0,1) -ge 6)
{
if(-not(Test-Path -path $VistaPath))
{
New-Item -Path $VistaPath -itemtype directory | Out-Null
} #end if
} #end if

Else
{
if(-not(Test-Path -path $XPPath))
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Introduction to Windows PowerShell Scripting CHAPTER 13
473
{
New-Item -path $XPPath -itemtype directory | Out-Null
} #end if
} #end else
} #end Test-ModulePath

Function Copy-Module([string]$name)
{
$UserPath = $env:PSModulePath.split(";")[0]
$ModulePath = Join-Path -path $userPath `
-childpath (Get-Item -path $name).basename
New-Item -path $modulePath -itemtype directory | Out-Null
Copy-item -path $name -destination $ModulePath | Out-Null
}

# *** Entry Point to Script ***
Test-ModulePath
Get-ChildItem -Path C:\fso -Include *.psm1,*.psd1 -Recurse |
Foreach-Object { Copy-Module -name $_.fullName }
note Scripting support does not need to be enabled in Windows PowerShell to use
modules unless the module contains functions, such as the diagnostic modules. However,
to run the Copy-Modules.ps1 script to install modules to the user’s profile, you need
script support. To enable scripting support in Windows PowerShell, you use the
Set-ExecutionPolicy cmdlet. You could also use Xcopy to copy modules to the user’s

Modules folder.
Creating a Module Drive
An easy way to work with modules is to create a couple of Windows PowerShell drives using
the FileSystem provider. Because the modules are in a location to which it is not easy to navi-
gate from the command line and because the $PSModulePath returns a string that contains
the path to both the user’s and the system Modules folders, it makes sense to provide an
easier way to work with the modules’ location. To create a Windows PowerShell drive for
the user’s Modules folder location, you use the New-PSDrive cmdlet, specify a name such as
mymods, use the FileSystem provider, and obtain the root location from the $PSModulePath
environment variable by using the split method from the .NET Framework string class. For the
user’s Modules folder, you use the first element from the returned array, as shown here.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
474
PS C:\> New-PSDrive -Name mymods -PSProvider filesystem -Root `
(($env:PSModulePath).Split(";")[0])

WARNING: column "CurrentLocation" does not fit into the display and was removed
.

Name Used (GB) Free (GB) Provider Root

mymods 47.62 FileSystem C:\Users\administrator
The command to create a Windows PowerShell drive for the system module location is
exactly the same as the one used to create a Windows PowerShell drive for the user’s Mod-
ules folder location, with the exception of specifying a different name, such as sysmods, and
choosing the second element from the array you obtain by using the split method on the
$PSModulePath variable. This command is seen here.
PS C:\> New-PSDrive -Name sysmods -PSProvider filesystem -Root `
(($env:PSModulePath).Split(";")[1])


WARNING: column "CurrentLocation" does not fit into the display and was removed
.

Name Used (GB) Free (GB) Provider Root

sysmods 47.62 FileSystem C:\Windows\System32\Win
You can also write a script that creates Windows PowerShell drives for each of the two
module locations. To do this, you first create an array of names for the Windows PowerShell
drives. You then use a for statement to walk through the array of Windows PowerShell drive
names and call the New-PSDrive cmdlet. Because you are running the commands inside a
script, it means the new Windows PowerShell drives would live within the script scope by
default. When the script ends, the script scope goes away. This means the Windows PowerShell
drives would not be available when the script ended, which would defeat your purposes
in creating them in the first place. To solve this scoping problem, you need to create the
Windows PowerShell drives within the global scope, which means they will be available in
the Windows PowerShell console once the script has completed running. To avoid displaying
confirmation messages when creating the Windows PowerShell drives, you pipe the results to
the Out-Null cmdlet.
In the New-ModulesDrive.ps1 script, another function is created. This function displays
global FileSystem provider Windows PowerShell drives. When the script is run, the
New-ModuleDrives function is called. It is followed by calling the Get-FileSystemDrives
function. The complete New-ModulesDrive.ps1 script is shown here.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Summary CHAPTER 13
475
New-ModulesDrive.ps1
Function New-ModuleDrives
{
<#

.SYNOPSIS
Creates two PSDrives: myMods and sysMods
.EXAMPLE
New-ModuleDrives
Creates two PSDrives: myMods and sysMods. These correspond
to the users' modules folder and the system modules folder respectively.
#>
$driveNames = "myMods","sysMods"

For($i = 0 ; $i -le 1 ; $i++)
{
New-PsDrive -name $driveNames[$i] -PSProvider filesystem `
-Root ($env:PSModulePath.split(";")[$i]) -scope Global |
Out-Null
} #end For
} #end New-ModuleDrives

Function Get-FileSystemDrives
{
<#
.SYNOPSIS
Displays global PS Drives that use the Filesystem provider
.EXAMPLE
Get-FileSystemDrives
Displays global PS Drives that use the Filesystem provider
#>
Get-PSDrive -PSProvider FileSystem -scope Global
} #end Get-FileSystemDrives

# *** EntryPoint to Script ***

New-ModuleDrives
Get-FileSystemDrives
Summary
This chapter has provided an overview of tools that you can use for managing a Windows 7
desktop infrastructure. The tools covered included in-box tools, free tools available from the
Microsoft Download Center, the Windows Sysinternals Suite of system troubleshooting tools,
the six products included in the Microsoft Desktop Optimization Pack for Software Assurance,
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 13 Overview of Management Tools
476
and the Microsoft System Center family of products. The chapter also includes an extensive
tutorial on Windows PowerShell for administrators, including demonstrations of some of the
new features in Windows PowerShell 2.0.
Additional Resources
These resources contain additional information and tools related to this chapter.
Related Information
The information below is organized according to topic to make it easier to use.
Related Information on In-box Tools
n
For information on how to use WMI to manage Windows 7 computers, see the
various resources available on the Script Center on Microsoft TechNet at
/>n
For a collection of sample administration scripts, see the Script Center Script Repository
at />n
For more information about Windows PowerShell, see the “Scripting with Windows
PowerShell” section of the Script Center at
/scriptcenter/hubs/msh.mspx.
n
For information about what’s new in Windows PowerShell 2.0, see
/>n

For the latest news about Windows PowerShell and tips on using it, see the Windows
PowerShell blog at />n
For information about WinRM and WinRS, see “Windows Remote Management” on
MSDN at />n
For a list of Windows commands and their detailed syntax, see the “Command
Reference” section of “Commands, References, and Tools for Windows Server 2008 R2”
at />Related Information on Downloadable Tools
n
Search the Microsoft Download Center at for
free system tools you can use to manage different aspects of Windows 7 in your
environment.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Additional Resources CHAPTER 13
477
Related Information on Windows Sysinternals Tools
n
For information concerning each of the tools in the Windows Sysinternals Suite, click
on the link for the tool on the Sysinternals Utility Index at
/en-us/sysinternals/bb545027.aspx.
n
You can download the entire Sysinternals Suite as a compressed archive file from
/>Related Information on MDOP for Software Assurance
n
For information about the Microsoft Software Assurance for Volume Licensing
program, see />n
For information about Windows 7 Enterprise Edition, see
/windows/enterprise/products/windows-7-enterprise.aspx.
n
For information about MDOP, see
/technologies/mdop.aspx.

n
For the latest news about MDOP products and tips on how to use them, see the
Official MDOP blog at />n
Software Assurance customers can download MDOP 2009 from the MVLS site at
/>n
For information about App-V 4.5, see
/products/app-virtualization.aspx.
n
For information about AGPM, see
/products/advanced-group-policy-management.aspx.
n
For information about AIS 1.5, see
/products/ais.aspx.
n
For information about DaRT, see
/products/dart.aspx.
n
For information about MED-V 1.0, see
/products/med-v.aspx.
n
For information about DEM, see
/products/dem.aspx.
Related Information on Microsoft System Center
n
For information about System Center Configuration Manager 2007 R2, see
/>n
For the latest news about System Center Configuration Manager and tips on using
the platform, see the System Center Configuration Manager Team blog at
/>Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

×