Chapter 4 Other Key PowerShell Concepts

IN THIS CHAPTER

Although previous chapters in this book have emphasized PowerShell’s ease of use for scripters familiar with other scripting languages such as Bash and VBScript, the PowerShell language introduces a number of key new concepts that enable scripters to take their automation tasks to a new level of capability, organization, and clarity. The goal of this chapter is to explore these new concepts, provide specific examples to demonstrate each concept, and to illustrate the underlying principle behind each concept to help take your understanding of the inner workings of PowerShell to the next level.

Formatting Output

As you are getting started with PowerShell, you will probably make use of PowerShell’s formatting cmdlets almost from the beginning. The formatting cmdlets are a key part of PowerShell’s functionality, as they enable you to organize the output of other cmdlets in a useful manner. This section provides an overview of the native PowerShell formatting cmdlets and their capabilities, explores how the formatting cmdlets actually perform their work, and discusses how to customize the output of the formatting cmdlets to meet your own requirements.

The Formatting Cmdlets

There are four native PowerShell cmdlets that deal specifically with formatting the output of commands:

Format-ListThe Format-List cmdlet formats the output of a command as a list of properties in which each property is displayed on a separate line. You can use Format-List to format and display all or selected properties of an object as a list (Format-List *).

Format-TableThe Format-Table cmdlet formats the output of a command as a table with a selected properties of the object in each column. The object type determines the default layout and properties that are displayed in each column, but you can use the Property parameter to select the properties that you want to see.

Format-WideThe Format-Wide cmdlet formats objects as a wide table that displays only one property of each object. You can use the Property parameter to determine which property is displayed.

Format-CustomThe Format-Custom cmdlet formats the output of a command as defined in an alternate view. Format-Custom is designed to display views that are not just tables or just lists. You can use the views defined in the *format.PS1XML files in the Windows PowerShell directory or you can create your own views in new PS1XML files and use the Update-FormatData cmdlet to add them to Windows PowerShell.

PowerShell’s Formatting under the Hood

As you are first getting used to working with PowerShell, it is easy to type a command such as get-process | format-list and appreciate the ease of getting results from PowerShell without needing to have a detailed understanding of exactly how PowerShell is displaying these results. This section takes a look at the mechanics of the formatting cmdlets and describes how to customize the output of PowerShell’s formatting cmdlets to meet your own requirements.

As we discussed in Chapter 3, “Advanced PowerShell Concepts,” the Extended Type System (ETS) enables existing .NET objects to be assigned new behaviors by PowerShell. PowerShell uses ETS to include detailed formatting information for the objects that it uses. This formatting information is stored in a series of files with a .ps1xml extension that reside in the PowerShell home directory. In PowerShell 2.0 CTP2, the PowerShell home directory is C:WINDOWSsystem32WindowsPowerShellv1.0; this value is also stored in the PowerShell variable $PSHOME. The command that follows shows a list of the .ps1xml files that are part of the current release of PowerShell 2.0 CTP2.

image

PS C:> dir $PSHOME/*format* | ft name

Name
----

Certificate.Format.ps1xml
DotNetTypes.Format.ps1xml
FileSystem.Format.ps1xml
Help.Format.ps1xml
PowerShellCore.format.ps1xml
PowerShellTrace.format.ps1xml
Registry.format.ps1xml


PS C:>

image

The function of each of these seven formatting files is described in the following:

Certificate.Format.ps1xmlProvides formatting guidelines for objects such as X.509 certificates and certificate stores.

DotNetTypes.Format.ps1xmlFormats .NET types not covered by the other formatting files, such as CultureInfo, FileVersionInfo, and EventLogEntry objects.

FileSystem.Format.ps1xmlContains formatting information for file system objects such as files and directories.

Help.Format.ps1xmlDescribes the views that PowerShell uses to display help file content, such as detailed and full views, parameters, and examples.

PowerShellCore.format.ps1xmlFormats objects that are created by the PowerShell core cmdlets, such as Get-Member and Get-ExecutionPolicy.

PowerShellTrace.format.ps1xmlControls the appearance of trace objects, such as those generated by the Trace-Command cmdlet.

Registry.format.ps1xmlInstructs PowerShell on the formatting and appearance of registry objects, such as keys and entries.

CAUTION

Although you are welcome to take a look at any of the formatting files listed previously, these files should not be edited directly, or PowerShell’s basic functionality may be impacted. Each of these files is digitally signed to prevent modification.

Customizing Output Formats

As you continue to use PowerShell for your scripting automation tasks, you will likely run into situations where it would be really helpful to be able to add an additional property to a PSObject. For example, you might want to create a new alias property to make it easier to reference a property in an existing PSObject. There are two different ways to approach this kind of task. If you just need to add a property temporarily, you can use the Add-Member cmdlet to add an additional property to an existing PSObject. The sequence of commands that follows shows how to add a NoteProperty System.String property called Status with a value of done to the type name System.IO.DirectoryInfo:

image

Image

image

The limitation of adding properties to PSObjects interactively is that the properties persist only for the duration of your PowerShell session. After you close PowerShell, any custom properties that you have added are destroyed and need to be manually recreated in subsequent sessions if you want to use the properties again. If you find that you are making regular use of custom properties and would like to have these properties automatically loaded every time PowerShell is launched, the best solution is to create a custom .ps1xml file that can be loaded as part of your PowerShell profile. The steps that follow describe how to create your own custom .ps1xml file and add it to your Windows PowerShell console.

To create a new .ps1xml file, you can begin with a blank template similar to the one shown in the following. You should save this file in your PowerShell user profile directory with the name Types.Custom.ps1xml. To obtain the path for your PowerShell user profile, you can enter the command $profile at any PowerShell prompt. The value that is returned is similar to C:Documents and Settings<username>My DocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1. Thus, this file should be saved as C:Documents and Settings<username>My DocumentsWindowsPowerShellTypes.Custom.ps1xml.

image

image

The previous example is a valid .ps1xml file, but it contains no data. To configure PowerShell to load this Types.Custom.ps1xml file when PowerShell starts, you can add the following lines to your PowerShell profile:

image

image

At this point, you have configured PowerShell to load a custom .ps1xml file named Types.Custom.ps1xml for your user profile when PowerShell is launched. The next step is to add some customizations to Types.Custom.ps1xml. The example that follows demonstrates adding an AliasProperty named BytesFree to the System.IO.DriveInfo PSObject, which references the existing property AvailableFreeSpace:

image

image

After you have saved the Types.Custom.ps1xml file in your PowerShell user profile directory as described previously, exit PowerShell and restart it to allow the new custom types file to be included. The example that follows shows the output of [System.IO.DriveInfo]::getdrives() pipelined to Format-List (aliased here as fl) with the properties Name, DriveType, VolumeLabel, and BytesFree. Note that PowerShell now accepts BytesFree as a valid property for System.IO.DriveInfo and returns the value for AvailableFreeSpace, even though the BytesFree label is displayed by Format-List.

image

PS C:> $a = [System.IO.DriveInfo]::getdrives()
PS C:> $a | fl Name, DriveType, VolumeLabel, BytesFree


Name        : C:
DriveType   : Fixed
VolumeLabel : IBM_PRELOAD
BytesFree   : 51519315968

Name        : D:
DriveType   : Fixed
VolumeLabel : 60 GB
BytesFree   : 19784757248

Name        : E:
DriveType   : Fixed
VolumeLabel : Data
BytesFree   : 36199202816

Name        : F:
DriveType   : CDRom
VolumeLabel :
BytesFree   :

PS C:>

image

Although the example shown is a relatively straightforward demonstration of adding an alias for an existing PSObject property, it is possible to perform much more detailed customizations in a .ps1xml file, such as including script blocks to assign a scripted action to a PSObject property. The following abbreviated example comes from PowerShell’s default types.ps1xml file and illustrates how the DateTime property of the System. DateTime type is populated using a series of scripted commands to parse the input and return a value:

image

image

NOTE

If you plan to make extensive customizations to your own .ps1xml file, and especially if you plan to distribute your customizations to other users, it is a best practice to digitally sign your .ps1xml file. Please review Chapter 5, “Understanding PowerShell Security,” for more information on digitally signing PowerShell files.

Providers

Most computer systems are used to store data, often in a structure such as a file system. Because of the amount of data stored in these structures, processing and finding information can be unwieldy. Most shells have interfaces, or providers, for interacting with data stores in a predictable, set manner. PowerShell also has a set of providers for presenting the contents of data stores through a core set of cmdlets. You can then use these cmdlets to browse, navigate, and manipulate data from stores through a common interface. To get a list of the core cmdlets, use the following command:

image

PS C:> help about_core_commands
...
    ChildItem CMDLETS
    Get-ChildItem

    CONTENT CMDLETS
    Add-Content
    Clear-Content
    Get-Content
    Set-Content

    DRIVE CMDLETS
    Get-PSDrive
    New-PSDrive
    Remove-PSDrive

    ITEM CMDLETS
    Clear-Item
    Copy-Item
    Get-Item
    Invoke-Item
    Move-Item
    New-Item
    Remove-Item
    Rename-Item
    Set-Item

    LOCATION CMDLETS
    Get-Location
    Pop-Location
    Push-Location
    Set-Location

    PATH CMDLETS
    Join-Path
    Convert-Path
    Split-Path
    Resolve-Path
    Test-Path

    PROPERTY CMDLETS
    Clear-ItemProperty
    Copy-ItemProperty
    Get-ItemProperty

    Move-ItemProperty
    New-ItemProperty
    Remove-ItemProperty
    Rename-ItemProperty
    Set-ItemProperty

    PROVIDER CMDLETS
    Get-PSProvider



PS C:>

image

To view built-in PowerShell providers, use the following command:

image

Image

image

The preceding list displays not only built-in providers, but also the drives each provider currently supports. A drive is an entity that a provider uses to represent a data store through which data is made available to the PowerShell session. For example, the Registry provider creates a PowerShell drive for the HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER Registry hives.

To see a list of all current PowerShell drives, use the following command:

image

Image

image

Accessing Drives and Data

One way to access PowerShell drives and their data is with the Set-Location cmdlet. This cmdlet, shown in the following example, changes the working location to another specified location that can be a directory, subdirectory, location stack, or Registry location:

image

PS C:> set-location hklm:
PS HKLM:> set-location softwaremicrosoftwindows
PS HKLM:softwaremicrosoftwindows>

image

Next, use the Get-ChildItem cmdlet to list the subkeys under the Windows key:

image

Image

image

Note that with a Registry drive, the Get-ChildItem cmdlet lists only the subkeys under a key, not the actual Registry values. This is because Registry values are treated as properties for a key rather than a valid item. To retrieve these values from the Registry, you use the Get-ItemProperty cmdlet, as shown in this example:

image

Image

image

As with the Get-Process command, the data returned is a collection of objects. You can modify these objects further to produce the output you want, as this example shows:

image

PS HKLM:softwaremicrosoftwindows> get-itemproperty currentversion |
select ProductId

ProductId
---------
76487-OEM-XXXXXXX-XXXXX


PS HKLM:softwaremicrosoftwindows>

image

Accessing data from a FileSystem drive is just as simple. The same type of command logic is used to change the location and display the structure:

image

Image

image

What’s different is that data is stored in an item instead of being a property of that item. To retrieve data from an item, use the Get-Content cmdlet, as shown in this example:

image

PS C:WINDOWSsystem32windowspowershellv1.0> get-content
about_Alias.help.txt
TOPIC
    Aliases


SHORT DESCRIPTION
    Using pseudonyms to refer to cmdlet names in the Windows
PowerShell

LONG DESCRIPTION
    An alias is a pseudonym, or "nickname," that you can assign to a
    cmdlet so that you can use the alias in place of the cmdlet name.
    The Windows PowerShell interprets the alias as though you had
    entered the actual cmdlet name. For example, suppose that you want
    to retrieve today's date for the year 1905. Without an alias, you
    would use the following command:

        Get-Date -year 1905
...


PS C:WINDOWSsystem32windowspowershellv1.0>

image

NOTE

Not all drives are based on a hierarchical data store. For example, the Environment, Function, and Variable PowerShell providers aren’t hierarchical. Data accessed through these providers is in the root location on the associated drive.

Mounting a Drive

PowerShell drives can be created and removed, which is handy when you’re working with a location or set of locations frequently. Instead of having to change the location or use an absolute path, you can create new drives (also referred to as “mounting a drive” in PowerShell) as shortcuts to those locations. To do this, use the New-PSDrive cmdlet, shown in the following example:

image

Image

image

To remove a drive, use the Remove-PSDrive cmdlet, as shown here:

image

Image

image

Profiles

A PowerShell profile is a saved collection of settings for customizing the PowerShell environment. There are four types of profiles, loaded in a specific order each time PowerShell starts. The following sections explain these profile types, where they should be located, and the order in which they are loaded.

The All Users Profile

The All Users profile is located in %windir%system32windowspowershellv1.0profile.ps1. Settings in the All Users profile are applied to all PowerShell users on the current machine. If you plan to configure PowerShell settings across the board for users on a machine, then this is the profile to use.

The All Users Host-Specific Profile

This profile is located in %windir%system32windowspowershellv1.0ShellID_profile.ps1. Settings in the All Users host-specific profile are applied to all users of the current shell (by default, the PowerShell Console). PowerShell supports the concept of multiple shells or hosts. For example, the PowerShell Console is a host and the one most users use exclusively.

NOTE

While the word host is colloquially used to refer to a physical computer system that provides services to users, in the context of the PowerShell language, the word host signifies an instance of the PowerShell console host program, which provides PowerShell services to users of PowerShell. Many of the native PowerShell cmdlets reflect this frame of reference, such as Read-Host and Write-Host, which both provide text processing functionality within an existing PowerShell session.

However, other applications can call an instance of the PowerShell runtime to access and run PowerShell commands and scripts. An application that does this is called a hosting application and uses a host-specific profile to control the PowerShell configuration. The host-specific profile name is reflected by the host’s ShellID. In the PowerShell Console, the ShellID is the following:

image

PS C: $ShellId
Microsoft.PowerShell
PS C:

image

Putting this together, the PowerShell Console’s All Users host-specific profile is named Microsoft.PowerShell_profile.ps1. For other hosts, the ShellID and All Users host-specific profile names are different. For example, the PowerShell Analyzer (www.powershellanalyzer.com) is a PowerShell host that acts as a rich graphical interface for the PowerShell environment. Its ShellID is PowerShellAnalyzer.PSA, and its All Users host-specific profile name is PowerShellAnalyzer.PSA_profile.ps1.

The Current User’s Profile

This profile is located in %userprofile%My DocumentsWindowsPowerShellprofile.ps1. Users who want to control their own profile settings can use the current user’s profile. Settings in this profile are applied only to the user’s current PowerShell session and don’t affect any other users.

The Current User’s Host-Specific Profile

This profile is located in %userprofile%My DocumentsWindowsPowerShellShellID_profile.ps1. Like the All Users host-specific profile, this profile type loads settings for the current shell. However, the settings are user-specific.

NOTE

When you start the shell for the first time, you might see a message indicating that scripts are disabled and no profiles are loaded. You can modify this behavior by changing the PowerShell execution policy, discussed in Chapter 5.

Scopes

A scope is a logical boundary in PowerShell that isolates the use of functions and variables. Scopes can be defined as global, local, script, and private. They function in a hierarchy in which scope information is inherited downward. For example, the local scope can read the global scope, but the global scope can’t read information from the local scope. Scopes and their use are described in the following sections.

The Global Scope

As the name indicates, a global scope applies to an entire PowerShell instance. Global scope data is inherited by all child scopes, so any commands, functions, or scripts that run make use of variables defined in the global scope. However, global scopes are not shared between different instances of PowerShell.

The following example shows the $Processes variable being defined as a global variable in the ListProcesses function. Because the $Processes variable is being defined globally, checking $Processes.Count after ListProcesses completes returns a count of the number of active processes at the time ListProcesses was executed.

image

PS C:> function ListProcesses {$Global:Processes = get-process}
PS C:> ListProcesses
PS C:> $Processes.Count
37

image

NOTE

In PowerShell, you can use an explicit scope indicator to determine the scope a variable resides in. For instance, if you want a variable to reside in the global scope, you define it as $Global:variablename. If an explicit scope indicator isn’t used, a variable resides in the current scope for which it’s defined.

The Local Scope

A local scope is created dynamically each time a function, filter, or script runs. After a local scope has finished running, information in it is discarded. A local scope can read information from the global scope but can’t make changes to it.

The following example shows the locally scoped variable $Processes being defined in the ListProcesses function. After ListProcesses finishes running, the $Processes variable no longer contains any data because it was defined only in the ListProcesses function. As you can see, checking $Processes.Count after the ListProcesses function is finished produces no results.

image

PS C:> function ListProcesses {$Processes = get-process}
PS C:> ListProcesses
PS C:> $Processes.Count
PS C:>

image

The Script Scope

A script scope is created whenever a script runs and is discarded when the script finishes running. To see an example of how a script scope works, create the following script and save it as ListProcesses.ps1:

image

image

After you have created the script file, run it from a PowerShell session. Your output should look similar to this example:

image

PS C:> .ListProcesses.ps1
Here is the first process:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------        ------                -----           -----    -----        ------          -- -----------
    105       5               1992             4128    32                            916 alg


PS C:> $Processes[0]
Cannot index into a null array.
At line:1 char:12
+ $Processes[0 <<<< ]
PS C:>

image

Notice that when the ListProcesses.ps1 script runs, information about the first process object in the $Processes variable is written to the console. However, when you try to access information in the $Processes variable from the console, an error is returned because the $Processes variable is valid only in the script scope. When the script finishes running, that scope and all its contents are discarded.

The Private Scope

A private scope is similar to a local scope, with one key difference: Definitions in the private scope aren’t inherited by any child scopes.

The following example shows the privately scoped variable $Processes defined in the ListProcesses function. Notice that during execution of the ListProcesses function, the $Processes variable isn’t available to the child scope represented by the script block enclosed by { and } in lines 6–9.

image

PS C:> function ListProcesses {$Private:Processes = get-process
>>     write-host "Here is the first process:" -Foregroundcolor Yellow
>>     $Processes[0]
>>     write-host
>>
>>     &{
>>         write-host "Here it is again:" -Foregroundcolor Yellow
>>         $Processes[0]
>>     }
>> }
>>
PS C:> ListProcesses

Here is the first process:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------         ------           -----            -----       -----          ------          -- -----------
    105         5             1992           4128    32                           916 alg

Here it is again:
Cannot index into a null array.
At line:7 char:20
+         $Processes[0 <<<< ]


PS C:>

image

This example works because it uses the ‘&' call operator. With this call operator, you can execute fragments of script code in an isolated local scope. This technique is helpful for isolating a script block and its variables from a parent scope or, as in this example, isolating a privately scoped variable from a script block.

Dot Sourcing

What if you want to use a script in a pipeline or access it as a library file for common functions? Normally, this isn’t possible because PowerShell discards a script scope whenever a script finishes running. Luckily, PowerShell supports the dot sourcing technique, a term that originally came from UNIX. Dot sourcing a script file tells PowerShell to load a script scope into the calling parent’s scope, rather than creating a new local scope for the execution of the script.

To dot source a script file, simply prefix the script name with a period (dot) when running the script, as shown here:

image

PS C:> . c:scriptsmyscript.ps1

image

Library Files

In PowerShell, library files are groups of cmdlets that are used to perform related functions. In most cases, library files that are used in PowerShell are implemented in a dynamic link library (DLL), which is then registered with PowerShell to provide access to the cmdlet functionality implemented in the DLL. This section walks through the process of registering a new PowerShell library file, adding the snapin to the console, and confirming that the new library file is providing the expected functionality.

By default, a number of PSSnapins are included with PowerShell. These PSSnapins contain the built-in cmdlets used by PowerShell. You can display a list of these cmdlets by entering the command Get-PSSnapin at the PowerShell command prompt as shown in the following:

image

PS C:> get-pssnapin


Name        : Microsoft.PowerShell.Core
PSVersion   : 2.0
Description : This Windows PowerShell snap-in contains Windows
              PowerShell management 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.

Name        : Microsoft.PowerShell.Management
PSVersion   : 2.0
Description : This Windows PowerShell snap-in contains management
              cmdlets used to manage Windows components.

Name        : Microsoft.PowerShell.Security
PSVersion   : 2.0
Description : This Windows PowerShell snap-in contains cmdlets to
              manage Windows PowerShell security.

Name        : Microsoft.PowerShell.Utility
PSVersion   : 2.0
Description : This Windows PowerShell snap-in contains utility Cmdlets
              used to manipulate data.


PS C:>

image

You can also use the Get-PSSnapin command to return a list of all the registered PSSnapins outside of the default PowerShell snapins listed in the previous example. Entering the command Get-PSSnapin- Registered on a newly installed PowerShell system will return nothing, as shown in the following:

image

PS C:> get-pssnapin -registered
PS C:>

image

To register a third-party library, the .NET utility InstallUtil.exe is used. In the example below, InstallUtil.exe is used to install a third-party library file called nivot.powershell.eventing.dll. This DLL is part of the third-party PowerShell Eventing library, which can be freely downloaded from http://www.codeplex.com/PSEventing:

image

PS C:pseventing> &
"$env:windirMicrosoft.NETFrameworkv2.0.50727InstallUtil.exe "
nivot.powershell.eventing.dll
Microsoft (R) .NET Framework Installation utility Version
2.0.50727.1433
Copyright (c) Microsoft Corporation.  All rights reserved.


Running a transacted installation.

Beginning the Install phase of the installation.
See the contents of the log file for the
C:pseventing ivot.powershell.eventing.dll assembly's progress.
The file is located at
C:pseventing ivot.powershell.eventing.InstallLog.
Installing assembly
'C:pseventing ivot.powershell.eventing.dll'.
Affected parameters are:
   logtoconsole =
   assemblypath = C:pseventing ivot.powershell.eventing.dll
   logfile = C:pseventing ivot.powershell.eventing.InstallLog

The Install phase completed successfully, and the Commit phase is
beginning.
See the contents of the log file for the
C:pseventing ivot.powershell.eventing.dll assembly's progress.
The file is located at
C:pseventing ivot.powershell.eventing.InstallLog.
Committing assembly
'C:pseventing ivot.powershell.eventing.dll'.
Affected parameters are:
   logtoconsole =
   assemblypath = C:pseventing ivot.powershell.eventing.dll
   logfile = C:pseventing ivot.powershell.eventing.InstallLog

The Commit phase completed successfully.

The transacted install has completed.
PS C:pseventing>

image

NOTE

The version of the InstallUtil program that you must use varies depending on whether you are installing on a 32-bit or 64-bit platform.

To install 32-bit registry information, use: %systemroot%Microsoft.NETFrameworkv2.0.50727installutil.exe.

To install 64-bit registry information, use: %systemroot%Microsoft.NETFramework64v2.0.50727installutil.exe.

After the DLL library file has been registered with PowerShell, the next step is to register the DLL’s snapin with PowerShell, so that the cmdlets contained in the DLL are made available to PowerShell. In the case of the PowerShell Eventing library, the snapin is registered by using the command Add-PSSnapin pseventing as shown in the following:

image

PS C:> add-pssnapin pseventing
PS C:>

image

Now that the pseventing snapin has been registered, you can enter the command Get-Help pseventing as shown in the following to review the usage information for the PSEventing cmdlets:

image

PS C:pseventing> get-help pseventing
TOPIC
    PowerShell Eventing Library (version 1.0)


SHORT DESCRIPTION
    Describes the Windows PowerShell Eventing (PSEventing) snapin and
    how to use the contained cmdlets and scripts that ship with
    PSEventing.


LONG DESCRIPTION
    PowerShell Eventing is a PowerShell Snapin that opens a new door
    for scripters into the powerful world of .NET events. Previously
    thought shut tight given the nature of the command-line driven
    prompt, this library provides the tools to automatically capture
    events in real-time, but lets you deal with them in your time.




CMDLETS
    The current PSEventing cmdlets are listed below:


    Get-Event
        Retrieve one or more PSEvent objects representing tracked .NET
        events that have been raised since the last invocation of this
        command.

    New-Event
        Create a custom PSEvent with an optional associated object
        payload. This can be used for inter-runspace communication, or
        simple notification inside a loop.

    Get-EventBinding
        Shows information about currently bound and/or
        unbound events on one or more .NET objects, accessible through
        PowerShell variables.

    Connect-EventListener
        Allows PowerShell to sink events for a given .NET object.

    Disconnect-EventListener
        Disconnects one or more event sinks for a given .NET object.

    Start-KeyHandler
        Allows PowerShell to transparently intercept keypresses and
        breaks (ctrl+c) converting them into PSEvent objects to be
        added to the queue.

    Stop-KeyHandler
        Stop all keypress handling activity.

image

Now that the registration of the PSEventing library DLL is complete and the associated snapin has been added to the console, you can enter the command Get-PSSnapin–registered again and see that the PSEventing snapin has been added to the console.

image

PS C:> get-pssnapin -registered


Name        : PSEventing
PSVersion   : 2.0
Description : PowerShell Eventing Library 1.0



PS C:>

image

NOTE

The PSEventing library actually uses an installation script to complete the DLL registration and snapin tasks described previously. These tasks are listed out here simply to illustrate the process.

Now that you have registered the third-party library file and added its snapin to the console, you may find that the library does not meet your needs, and you want to remove it. The removal process is basically a reversal of the installation steps listed previously. First, you remove the snapin from the console using the command Remove-PSSnapin pseventing, as shown in the following:

image

PS C:> Remove-PSSnapin pseventing
PS C:>

image

After the third-party snapin has been unregistered, you will once again use InstallUtil.exe with a /U switch to unregister the DLL, as shown in the following:

image

PS C:pseventing> & "$env:windirMicrosoft.NETFrameworkv2.0.50727
InstallUtil.exe " /U nivot.powershell.eventing.dll
Microsoft (R) .NET Framework Installation utility Version
2.0.50727.1433
Copyright (c) Microsoft Corporation. All rights reserved.

The uninstall is beginning.
See the contents of the log file for the
C:pseventing ivot.powershell.eventing.dll assembly's progress.
The file is located at
C:pseventing ivot.powershell.eventing.InstallLog.
Uninstalling assembly 'C:pseventing ivot.powershell.eventing.dll'.

Affected parameters are:
   logtoconsole =
   assemblypath = C:pseventing ivot.powershell.eventing.dll
   logfile = C:pseventing ivot.powershell.eventing.InstallLog

The uninstall has completed.
PS C:pseventing>

image

After 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 third-party libraries are listed.

image

PS C:> get-pssnapin -registered
PS C:>

image

As you can see from the examples above, PowerShell’s implementation of library files provides a straightforward method for extending PowerShell’s functionality, and is currently used by many third-party vendors to register their cmdlets. Although developing your own library files is beyond the scope of this chapter, there are many resources available online to assist you with this type of project. A good starting point for PowerShell development work is the Windows PowerShell Programmer’s Guide at http://msdn.microsoft.com/en-us/library/cc136167(VS.85).aspx.

Summary

This chapter covered a number of key PowerShell concepts that are useful as your knowledge of PowerShell increases. We discussed PowerShell’s formatting cmdlets and went into detail about how these cmdlets do their work, including a walkthrough of the Add-Member cmdlet and creating a customized .ps1xml file to load customized alias properties when PowerShell starts up. This chapter also covered PowerShell’s implementation of providers, which enable access to the contents of data stores through a core set of cmdlets. The provider cmdlets enable users to browse, navigate, and manipulate data from stores such as file systems, the Windows registry, certificate stores, and PowerShell variables. We reviewed PowerShell’s hierarchy of profiles and provided details on the functionality provided by each of the four profile types. The behavior of PowerShell scopes was documented with particular attention to the limits imposed by global, local, script, and private scopes. The dot sourcing technique was reviewed as a way to run a script in the current scope instead of creating a local scope. Finally, PowerShell’s use of library files was discussed, including a walkthrough of the process of registering a new third-party DLL with PowerShell and adding the associated snapin to the console, then removing the snapin and unregistering the DLL to return the system to its original state.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset