• No results found

Add Custom Methods and Properties to Types |

Discussion

3.12 Add Custom Methods and Properties to Types |

Getting started

If you haven’t already, the first step in creating a types extension file is to create an empty one. The best location for this is probably in the same directory as your cus- tom profile, with the nameTypes.Custom.ps1xml, as shown in Example 3-5.

Next, add a few lines to your PowerShell profile so that PowerShell loads your type extensions during startup:

$typeFile = (Join-Path (Split-Path $profile) "Types.Custom.ps1xml") Update-TypeData -PrependPath $typeFile

By default, PowerShell loads several type extensions from theTypes.ps1xmlfile in Pow- erShell’s installation directory. The Update-TypeData cmdlet tells PowerShell to also look in your Types.Custom.ps1xml file for extensions. The -PrependPath para-meter makes PowerShell favor your extensions over the built-in ones in case of conflict. Once you have a custom types file to work with, adding functionality becomes rela- tively straightforward. As a theme, these examples do exactly what we alluded to ear- lier: add functionality to PowerShell’sPsDrive type.

To support this, you need to extend your custom types file so that it defines addi- tions to the System.Management.Automation.PSDriveInfo type, as shown in Example 3-6. The System.Management.Automation.PSDriveInfo type is the type that theGet-PsDrive cmdlet generates.

Add a ScriptProperty

A ScriptPropertylets you to add properties (that get and set information) to types, using PowerShell script as the extension language. It consists of three child ele- ments: the Nameof the property, theGetterof the property (via the GetScriptBlock

child), and theSetter of the property (via theSetScriptBlock child). Example 3-5. Sample Types.Custom.ps1xml file

<?xml version="1.0" encoding="utf-8" ?> <Types>

</Types>

Example 3-6. A template for changes to a custom types file

<?xml version="1.0" encoding="utf-8" ?> <Types>

<Type>

<Name>System.Management.Automation.PSDriveInfo</Name> <Members>

add members such as <ScriptProperty> here </Members>

</Type> </Types>

In both the GetScriptBlock and SetScriptBlock sections, the $thisvariable refers to the current object being extended. In theSetScriptBlock section, the $args[0]

variable represents the value that the user supplied as the right-hand side of the assignment.

Example 3-7 adds anAvailableFreeSpaceScriptProperty toPSDriveInfo, and should be placed within the members section of the template given in Example 3-6. When you access the property, it returns the amount of free space remaining on the drive. When you set the property, it outputs what changes you must make to obtain that amount of free space.

Example 3-7. A ScriptProperty for the PSDriveInfo type

<ScriptProperty>

<Name>AvailableFreeSpace</Name> <GetScriptBlock>

## Ensure that this is a FileSystem drive if($this.Provider.ImplementingType -eq

[Microsoft.PowerShell.Commands.FileSystemProvider]) {

## Also ensure that it is a local drive $driveRoot = $this.Root

$fileZone = [System.Security.Policy.Zone]::CreateFromUrl(` $driveRoot).SecurityZone

if($fileZone -eq "MyComputer") {

$drive = New-Object System.IO.DriveInfo $driveRoot $drive.AvailableFreeSpace

} }

</GetScriptBlock> <SetScriptBlock>

## Get the available free space

$availableFreeSpace = $this.AvailableFreeSpace

## Find out the difference between what is available, and what they ## asked for.

$spaceDifference = (([long] $args[0]) - $availableFreeSpace) / 1MB ## If they want more free space than they have, give that message if($spaceDifference -gt 0)

{

$message = "To obtain $args bytes of free space, " + " free $spaceDifference megabytes."

Write-Host $message }

## If they want less free space than they have, give that message else

{

$spaceDifference = $spaceDifference * -1

3.12 Add Custom Methods and Properties to Types | 85

Add an AliasProperty

An AliasProperty gives an alternative name (alias) for a property. The referenced property does not need to exist when PowerShell processes your type extension file, since you (or another script) might later add the property through mechanisms such as theAdd-Member cmdlet.

Example 3-8 adds a Free AliasProperty to PSDriveInfo, and should also be placed within the members section of the template given in Example 3-6. When you access the property, it returns the value of theAvailableFreeSpaceproperty. When you set the property, it sets the value of theAvailableFreeSpace property.

Add a ScriptMethod

AScriptMethodallows you to define an action on an object, using PowerShell script as the extension language. It consists of two child elements: theNameof the property and theScript.

In the script element, the$thisvariable refers to the current object you are extend- ing. Like a standalone script, the $args variable represents the arguments to the method. Unlike standalone scripts, ScriptMethods do not support the param state- ment for parameters.

Example 3-9 adds a Remove ScriptMethod to PSDriveInfo. Like the other additions, place these customizations within the members section of the template given in Example 3-6. When you call this method with no arguments, the method simulates removing the drive (through the-WhatIfoption toRemove-PsDrive). If you call this method with $true as the first argument, it actually removes the drive from the PowerShell session.

" use up $spaceDifference more megabytes." Write-Host $message

}

</SetScriptBlock> </ScriptProperty>

Example 3-8. An AliasProperty for the PSDriveInfo type

<AliasProperty> <Name>Free</Name>

<ReferencedMemberName>AvailableFreeSpace</ReferencedMemberName> </AliasProperty>

Example 3-9. A ScriptMethod for the PSDriveInfo type

<ScriptMethod> <Name>Remove</Name> <Script>

$force = [bool] $args[0]

Add other extension points

PowerShell supports several additional features in the types extension file, including

CodeProperty,NoteProperty,CodeMethod, andMemberSet. Although not generally use- ful to end users, developers of PowerShell providers and cmdlets will find these fea- tures helpful. For more information about these additional features, see the Windows PowerShell SDK, or MSDN documentation.

## Remove the drive if they use $true as the first parameter if($force)

{

$this | Remove-PSDrive }

## Otherwise, simulate the drive removal else

{

$this | Remove-PSDrive -WhatIf }

</Script> </ScriptMethod>

87

Chapter 4

CHAPTER 4

Looping and Flow Control

5

4.0

Introduction

As you begin to write scripts or commands that interact with unknown data, the concepts of looping and flow control become increasingly important.

PowerShell’s looping statements and commands let you perform an operation (or set of operations) without having to repeat the commands themselves. This includes, for example, doing something a specified number of times, processing each item in a col- lection, or working until a certain condition comes to pass.

PowerShell’s flow control and comparison statements let you to adapt your script or command to unknown data. They let you execute commands based on the value of that data, skip commands based on the value of that data, and more.

Together, looping and flow control statements add significant versatility to your PowerShell toolbox.

4.1

Make Decisions with Comparison and Logical

Related documents