Professional
Windows PowerShell
Programming
Snap-ins, Cmdlets, Hosts, and Providers
Arul Kumaravel
Jon White
Michael Naixin Li
Scott Happell
Guohui Xie
Krishna C. Vutukuri
Wiley Publishing, Inc.
Professional
Windows PowerShell
Programming
Preface xvii
Introduction xix
Chapter 1: Introduction to PowerShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 2: Extending Windows PowerShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Chapter 3: Understanding the Extended Type System . . . . . . . . . . . . . . . . . . . . . . 29
Chapter 4: Developing Cmdlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Chapter 5: Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Chapter 6: Hosting the PowerShell Engine in Applications . . . . . . . . . . . . . . . . . 165
Chapter 7: Hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Chapter 8: Formatting&Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Appendix A: Cmdlet Verb Naming Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Appendix B: Cmdlet Parameter Naming Guidelines . . . . . . . . . . . . . . . . . . . . . . . . 263
Appendix C: Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Appendix D: Provider Base Classes and Overrides/Interfaces. . . . . . . . . . . . . . 283
Appendix E: Core Cmdlets for Provider Interaction . . . . . . . . . . . . . . . . . . . . . . . . . 303
Index 307
Professional
Windows PowerShell
Programming
Snap-ins, Cmdlets, Hosts, and Providers
Arul Kumaravel
Jon White
Michael Naixin Li
Scott Happell
Guohui Xie
Krishna C. Vutukuri
Wiley Publishing, Inc.
Windows PowerShell Programming:
Snap-ins, Cmdlets, Hosts, and Providers
Published by
Wiley Publishing, Inc.
10475 Crosspoint Boulevard
Indianapolis, IN 46256
www.wiley.com
Copyright 2008 by Wiley Publishing, Inc., Indianapolis, Indiana
Published simultaneously in Canada
ISBN: 978-0-470-17393-0
Manufactured in the United States of America
10 9 8 7 6 5 4 3 2 1
Library of Congress Cataloging-in-Publication Data
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any
means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections
107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or
authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood
Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be
addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317)
572-3447, fax (317) 572-4355, or online at http://www.wiley.com/go/permissions.
Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties
with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties,
including without limitation warranties of fitness for a particular purpose. No warranty may be created or extended
by sales or promotional materials. The advice and strategies contained herein may not be suitable for every
situation. This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting,
or other professional services. If professional assistance is required, the services of a competent professional person
should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an
organization or Website is referred to in this work as a citation and/or a potential source of further information
does not mean that the author or the publisher endorses the information the organization or Website may provide
or recommendations it may make. Further, readers should be aware that Internet Websites listed in this work may
have changed or disappeared between when this work was written and when it is read.
For general information on our other products and services please contact our Customer Care Department within the
United States at (800) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002.
Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Wrox Programmer to Programmer, and related trade dress
are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and
other countries, and may not be used without written permission. Windows PowerShell is a trademark of Microsoft
Corporation in the United States and/or other countries. All other trademarks are the property of their respective
owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book.
Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be
available in electronic books.
About the Author
Arul Kumaravel is currently the Development Manager of the Windows PowerShell team. He has
worked with this team since its early days and led the team in shipping of version 1 of the product,
and is presently leading the development of next version of PowerShell. Fascinated by computers from
an early age, when he first learned programming using BASIC, he went on to get his Master of Science
degree in Computer Science from both the College of Engineering, Madras, India, and the University
of Iowa. As a Microsoft intern, he wrote the first JavaScript/VBScript debugger for Internet Explorer 3,
and was impressed by the potential to make a difference in millions of people’s lives by working for
Microsoft. He has been working at Microsoft for the past 11 years in various groups, shipping multiple
versions of products, including Internet Explorer, the Windows operating system, and Content Manage-
ment Server, and has even dabbled with Software as a Service with small business online services. More
recently, attracted by the business side of technology, Arul has taken on the arduous task of pursuing his
M.B.A. at the Wharton Business School. He can be reached at
[email protected].
Jon White is a software engineer who lives and works in the idyllic surroundings of Seattle’s eastern
suburbs. An original member of the PowerShell team at Microsoft, his professional career started in
the Administrative Tools group in Windows Server. As a hobbyist, Jon learned programming in his
early teens after his father bought an 8088-based PC clone at a second-hand shop. The PC came with
MS-DOS 2.0, which featured debug.exe with a 16-bit disassembler, but no assembler. As a result, Jon’s
first dive into programming was disassembling long tables of bytes to create a reverse-lookup dictionary
for manually converting assembly programs into executable binary code. Coincidentally, later in life he
filed the bug which removed debug.exe from 64-bit Windows. As a member of the PowerShell team,
he wrote the language’s first production script, when he converted the team’s test harness from Perl to
PowerShell script in 2004. When he’s not working (or writing about work) he’s either sailing or playing
with fire in the backyard. You can contact him at
[email protected].
Michael Naixin Li is the Senior Test Lead working on the Windows PowerShell team and currently
oversees the testing of Windows PowerShell 2.0. Before Windows PowerShell, Michael worked on vari-
ous major projects at Microsoft, including the development of MSN 1.x and 2.x, quality management for
the COM Services component in Windows 2000, NetDocs Web Client Access, Web Services in Hailstorm,
and Software Licensing Service in Windows Vista. Before joining Microsoft, Michael was an assistant
professor at Shanghai University of Science and Technology (now called Shanghai University). He holds
a Ph.D. in Computer Science from Colorado State University.
Scott Happell has been working as a software engineer and tester for 10 years. Three of those years have
been on the Windows PowerShell team, which was what brought him to Microsoft from New Jersey,
where he worked at an Internet startup that went belly-up. Scott recently left Microsoft to become a
recording engineer/rock star and is trying to find cool ways to use PowerShell to help him create music.
George Xie was a Senior Developer in the Windows PowerShell team for three years, mainly focusing
in the area of snap-in model and scripting language. Recently George joined Windows Mobile organi-
zation for the Mobile Device Management product. Before joining Microsoft, George worked for Siebel
Systems Inc. for several years.
Krishna Chythanya Vutukuri is a Software Developer working on the Windows PowerShell team. Before
Windows PowerShell, Krishna worked on various projects at Microsoft, which included the development
of Windows Presentation Foundation. Before joining Microsoft, Krishna held various product develop-
ment positions at Hewlett-Packard India Software Operations and Wipro Technologies. He holds a M.Sc
(Tech.) in Information Systems from Birla Institute of Technology and Science, Pilani, India.
Credits
Executive Editor Editorial Manager
Chris Webb Mary Beth Wakefield
Development Editor Production Manager
Howard Jones Tim Tate
Technical Editor Vice President and Executive Group Publisher
Marco Shaw Richard Swadley
Production Editor Vice President and Executive Publisher
Rachel McConlogue Joseph B. Wikert
Copy Editor Project Coordinator, Cover
Luann Rouff Lynsey Osborn
Contents
Preface xvii
Introduction xix
Chapter 1: Introduction to PowerShell 1
Windows PowerShell Design Principles 1
Preserve the Customer’s Existing Investment 2
Provide a Powerful, Object-Oriented Shell 2
Extensibility, Extensibility, Extensibility 2
Tear Down the Barriers to Development 2
A Quick Tour of Windows PowerShell 3
Cmdlets 3
High-Level Architecture of Windows PowerShell 9
Host Application 9
Windows PowerShell Engine 10
Windows PowerShell Snap-ins 10
Summary 11
Chapter 2: Extending Windows PowerShell 13
Types of PowerShell Snap-ins 13
Creating a Standard PowerShell Snap-in 14
Writing a PowerShell Snap-in 14
Registering Your PowerShell Snap-in 17
Listing Available PowerShell Snap-ins 19
Loading a PowerShell Snap-in to a Running Shell 19
Removing a PowerShell Snap-in from a Running Shell 20
Unregistering a PowerShell Snap-in 20
Registering a PowerShell Snap-in without Implementing a Snap-in Clas 21
Saving Snap-in Configuration 22
Starting PowerShell with a Saved Snap-in Configuration 22
Using a Profile to Save a Snap-in Configuration 23
Creating a Custom PowerShell Snap-in 23
Writing a Custom PowerShell Snap-in 23
Using a Custom PowerShell Snap-in 25
Summary 27
Contents
Chapter 3: Understanding the Extended Type System 29
PSObject 29
Constructing a PSObject 30
PSObject(Object) 31
PSObject() 31
PSObject.AsPSObject(someObject) 32
ImmediateBaseObject and BaseObject 33
Members 34
PSMemberInfoCollection 35
ReadOnlyPSMemberInfoCollection 36
Base, Adapted, and Extended Members 37
Types of Members 37
Properties 38
Methods 46
Sets 51
TypeNames 53
Lookup Algorithm 54
Distance Algorithm 54
PSObject Intrinsic Members and MemberSets 55
Errors and Exceptions 55
Runtime Errors 55
Initialization Errors 56
Type Conversion 57
Standard PS Language Conversion 57
Custom Converters 58
ToString Mechanism 60
Type Configuration (TypeData) 60
Well-Known Members 62
Script Access 62
Summary 62
Chapter 4: Developing Cmdlets 63
Getting Started 63
Command-Line Parsing 65
Command Discovery 65
Parameter Binding 66
Command Invocation 67
Using Parameters 67
Mandatory Parameters 67
Positional Parameters 68
x
Contents
Parameter Sets 71
Parameter Validation 78
Parameter Transformation 80
Processing Pipeline Input 84
Pipeline Parameter Binding 87
Generating Pipeline Output 91
Reporting Errors 92
ErrorRecord 93
ErrorDetails 95
Non-terminating Errors and Terminating Errors 97
Supporting ShouldProcess 98
Confirming Impact Level 100
ShouldContinue() 101
Working with the PowerShell Path 101
Documenting Cmdlet Help 106
Best Practices for Cmdlet Development 114
Naming Conventions 114
Interactions with the Host 115
Summary 116
Chapter 5: Providers 117
Why Implement a Provider? 118
Providers versus Cmdlets 118
Essential Concepts 119
Paths 119
Drives 121
Error Handling 121
Capabilities 122
Hello World Provider 123
Built-in Providers 125
Alias Provider 125
Environment Provider 126
FileSystem Provider 126
Function Provider 126
Registry Provider 127
Variable Provider 128
Certificate Provider 128
Base Provider Types 128
CmdletProvider 129
DriveCmdletProvider 129
ItemCmdletProvider 129
xi
Contents
ContainerCmdletProvider 131
NavigationCmdletProvider 132
Optional Provider Interfaces 132
IContentCmdletProvider 132
IPropertyCmdletProvider 133
IDynamicPropertyCmdletProvider 134
ISecurityDescriptorCmdletProvider 134
CmdletProvider 134
Methods and Properties on CmdletProvider 136
DriveCmdletProvider 139
ItemCmdletProvider 141
ContainerCmdletProvider 147
NavigationCmdletProvider 153
Design Guidelines and Tips 162
Summary 163
Chapter 6: Hosting the PowerShell Engine in Applications 165
Runspaces and Pipelines 165
Getting Started 166
Executing a Command Line 166
Using RunspaceInvoke 166
Using Runspace and Pipeline 168
Using the Output of a Pipeline 170
The Return Value of Invoke() 170
Using PSObject Objects Returned from a Pipeline 170
Handling Terminating Errors 171
Input, Output, and Errors for Synchronous Pipelines 172
Passing Input to Your Pipeline 172
The Output Pipe in Synchronous Execution 173
Retrieving Non-Terminating Errors from the Error Pipe 173
The ErrorRecord Type 174
Other Pipeline Tricks 174
Nested Pipelines 174
Reusing Pipelines 175
Copying a Pipeline Between Runspaces 175
Configuring Your Runspace 176
Creating a Runspace with a Custom Configuration 176
Adding and Removing Snap-Ins 177
Creating RunspaceConfiguration from a Console File 177
Creating RunspaceConfiguration from an Assembly 177
Using SessionStateProxy to Set and Retrieve Variables 178
Fine-Tuning RunspaceConfiguration 179
xii
Contents
Running a Pipeline Asynchronously 181
Calling InvokeAsync() 181
Closing the Input Pipe 182
Reading Output and Error from an Asynchronous Pipeline 182
Monitoring a Pipeline’s StateChanged Event 185
Reading Terminating Errors via PipelineStateInfo.Reason 186
Stopping a Running Pipeline 187
Asynchronous Runspace Operations 187
The OpenAsync() Method 187
Handling the Runspace’s StateChanged Event 188
Constructing Pipelines Programmatically 189
Creating an Empty Pipeline 189
Creating a Command 189
Merging Command Results 190
Adding Command Parameters 191
Adding Commands to the Pipeline 192
Cmdlets as an API Layer for GUI Applications 193
High-Level Architecture 193
Keys to Successful GUI Integration 194
Providing a Custom Host 194
Summary 195
Chapter 7: Hosts 197
Host-Windows PowerShell Engine Interaction 197
Built-In Cmdlets That Interact with the Host 199
Write-Debug 199
Write-Verbose 200
Write-Warning 202
Write-Progress 203
Write-Host and Out-Host 203
Read-Host 204
Cmdlet and Host Interaction 204
PSHost Class 207
InstanceId 208
Name 209
Version 210
CurrentCulture 210
CurrentUICulture 210
PrivateData 211
EnterNestedPrompt 211
ExitNestedPrompt 212
xiii
Contents
Application Notification Methods 214
SetShouldExit 214
PSHostUserInterface Class 221
WriteDebugLine 222
WriteVerboseLine 223
WriteWarningLine 223
WriteProgress 223
WriteErrorLine 224
Write Methods 224
Prompt Method 224
PromptForCredential 226
Read Methods 227
PSHostRawUserInterface Class 227
Summary 231
Chapter 8: Formatting & Output 233
The Four View Types 233
Table: format-table 234
List: format-list 234
Custom: format-custom 235
Wide: format-wide 235
Formatting without#.format.ps1xml 236
Format Configuration File Example 237
Loading Your Format File(s) 238
Update-formatdata 239
Snap-ins 240
RunspaceConfiguration API 240
Anatomy of a Format Configuration File 240
View 241
Name 241
ViewSelectedBy 241
GroupBy 242
TableControl 243
TableHeaders 243
TableRowEntries 244
ListControl 244
ListEntries 245
Wide Control 246
WideEntries 246
Custom Control 246
CustomEntries 248
xiv
Contents
Miscellaneous Configuration Entries 248
Wrap 248
AutoSize 248
Scenarios 249
Format Strings 249
Formatting Deserialized Objects 250
Class Inheritance 250
Selection Sets 253
Colors 253
Summary 255
Appendix A: Cmdlet Verb Naming Guidelines 257
Common Verbs 257
Data Verbs 259
Communication Verbs 260
Diagnostic Verbs 260
Lifecycle Verbs 261
Security Verbs 261
Appendix B: Cmdlet Parameter Naming Guidelines 263
Ubiquitous Parameters 263
Activity Parameters 264
Date/Time Parameters 266
Format Parameters 266
Property Parameters 267
Quantity Parameters 268
Resource Parameters 268
Security Parameters 269
Appendix C: Metadata 271
CmdletAttribute 271
Cmdlet Attribute Example 272
ParameterAttribute 272
ParameterAttribute Example 273
AliasAttribute 273
AliasAttribute Example 273
Argument Validation Attributes 273
ValidateSetAttribute 274
ValidatePatternAttribute 274
ValidateLengthAttribute 274
xv
Contents
ValidateCountAttribute 275
ValidateRangeAttribute 275
Allow and Disallow Attributes 276
AllowNullAttribute 276
AllowEmptyStringAttribute 276
AllowEmptyCollectionAttribute 277
ValidateNotNullAttribute 277
ValidateNotNullOrEmptyAttribute 277
CredentialAttribute 277
Extending Parameter Metadata Attributes 278
ValidateArgumentsAttribute 278
ValidateEnumeratedArgumentsAttribute 279
ArgumentTransformationAttribute 279
Adding Attributes to Dynamic Parameters at Runtime 280
ValidateScriptAttribute 281
Appendix D: Provider Base Classes and Overrides/Interfaces 283
CmdletProvider 283
DriveCmdletProvider 287
ItemCmdletProvider 288
ContainerCmdletProvider 290
NavigationCmdletProvider 294
IContentCmdletProvider 295
IContentReader 296
IContentWriter 297
IPropertyCmdletProvider 297
IDynamicPropertyCmdletProvider 298
Appendix E: Core Cmdlets for Provider Interaction 303
Drive-Specific Cmdlets 303
Item-Specific Cmdlets 303
Container-Specific Cmdlets 304
Property-Specific Cmdlets 304
Dynamic Property Manipulation Cmdlets 305
Content-Related Cmdlets 305
Security Descriptor–Related Cmdlets 305
Index 307
xvi
Preface
Welcome to Professional Windows PowerShell Programming.
Way back in 2003, I attended a talk at a conference center at Microsoft by some engineers from the
Microsoft Management Console team who were giving a demonstration of a prototype enhancement
to MMC. The prototype was one of the early murmurs of Microsoft’s response to the deluge of customer
feedback they’d received about the Windows administrative user experience after the delivery of their
first truly Internet-focused server operating system, Windows 2000 Server. The feedback wasn’t all good.
Windows 2000 Server started its long evolution as a text-based file manager for DOS. During the bulk
of its development, there was simply no idea that anyone would use it for anything other than checking
their mail and organizing a 20-megabyte hard disk. As a result, the management story for Windows 2000
Server was provided in The Windows Way, which was a rich interactive experience, a full set of native
and COM APIs, and no bridge between the two. In Linux, you could write a shell script to configure your
mail and DNS servers; in Windows, you had to either do it manually or learn C++ and COM.
The incorporation of Visual Basic Script and JavaScript into Windows served this niche to a certain
extent, but never really brought parity between the GUI experience and the command-line experience.
Since these scripting languages interact with the operating system through a subset of COM, and a GUI
application can use all of COM, call the Win32 API, and (in the case of certain programs such as Task
Manager) call directly into the native kernel API, the capabilities of Windows scripts were always
eclipsed by what was provided in the GUI.
But back to the demo: People filed into the room, a pair of engineers behind the podium broke the ice
by joking about the PA system, the lights dimmed, and they started the show. The new MMC prototype,
they revealed, was a GUI that used a command-line engine as its API layer. Every node expansion became
a query, every ‘‘OK’’ click became a command, and every action taken by the GUI operator was displayed
as script at the bottom of the screen with 100% fidelity. Old engineers shifted nervously in their seats,
senior managers sat entranced with dollar signs in their eyes, and the caterer, noticing the direction of
everyone’s eyes, palmed an hors d’oeuvre and went outside to smoke a cigarette.
This demo ushered in what, in the following three years, would become Windows PowerShell.
Version 1, available for download on the web and as an optional component on Windows Server 2008,
provides a rich programming environment for users of every stripe, and for the first time gives Windows
users a consistent glide path from the command-line experience all the way to COM and beyond.
This book is intended for the PowerShell snap-in and host developer audience, and introduces the reader
to PowerShell programming from the API level. Written by members of the PowerShell v1.0 team, it
covers development of cmdlets, providers, snap-ins, hosting applications, and custom host implementa-
tions in greater depth than the SDK documentation.
Enjoy.