Windows PowerShell 1.0 shows what having a broadly available command-line tool for Windows management can do for productivity. Version 2, now in beta, goes even further, adding remote management and new cmdlets. Microsoft is putting a lot of work into providing command-line support for all its management and this will continue to show in future versions of PowerShell.
Most editions of this column talk about how to do something using Windows PowerShell. This month, I'd like to talk about some of the reasons why PowerShell is organized the way that it is. Knowing this will help you understand its structure as the extent of its coverage in the Windows operating system increases. I had an interesting chat about this with Jeffrey Snover, partner architect for the Microsoft PowerShell team, and I'd like to share his insights with you.
You may have noticed in past columns that not all cmdlets are structured in the same way. That is, sometimes we use top-level cmdlets that are unique to a particular situation, such as stop-process. That cmdlet stops a process -- always. In contrast, cmdlets such as get-childitem work for a lot of different types of operations, such as enumerating the contents of a folder, listing registry subkeys or showing the current values of variables.
Additionally, some of these cmdlets that work in more than one situation don't always do exactly the same thing. In fact, sometimes they have no purpose at all. One design goal of Windows PowerShell is to make cmdlet syntax consistent. So why do we have some cmdlets that deal with one kind of data and others that deal with a different kind of data?
Windows PowerShell deals with two types of data: one in a flat, single-level structure (e.g., running services) and one in a hierarchical structure (e.g., the registry). Much of the time, it makes sense to organize hierarchical data into structures called providers. People are apt to do much the same kind of thing with hierarchical data (list items, create new ones, delete them), so you don't need to create individual cmdlets for each action. The details of the cmdlets' behavior may change, but the basic syntax stays pretty much the same.
Designing for discoverability
Part of the reason for the dual approach is that Windows PowerShell faces the same dilemma as any management system with a complex UI: helping people easily find the tools they need. (The fact that the PowerShell UI is based in the command line doesn't mean it's not complex, just that it doesn't include graphical elements.) One approach is to create individual cmdlets for each action you could take. On the plus side, this means you can see all the cmdlets at once and pick the one you want. On the minus side, as the list of cmdlets grows it becomes increasingly difficult to browse, even with PowerShell's filtering capabilities and support for wildcards in searches.
This is more than just a problem with a command-line UI. Imagine what Windows would look like if every single command had a button on the desktop. One obvious answer is to group like commands to simplify browsing, and that's what a graphical user interface does. The catch there is (a) how to tell people where to find the right group and (b) how to make it simple for them to take actions that are exposed in different groups. The compromise with PowerShell was to use both approaches to organize cmdlets.
PowerShell 1.0 comes with seven standard providers to access known data stores:
- FileSystem provider
- Registry provider
- Certificate provider
- Function provider
- Environment provider
- Alias provider
To list all the providers on your computer, type get-PsProvider from the PowerShell console. PowerShell calls all of these providers drives, as though they were hard disks. The FileSystem drive is selected by default, so if you invoke get-childitem or the related cmdlets, PowerShell assumes that you mean to work with the file system. To change to a new provider, type set-location and the drive name, as revealed by get-PSProvider. For example, to change locations to the user-specific section of the registry, you'd type set-location HKCU: (with the colon). This puts you into the requested virtual drive. You can move from drive to drive with set-location without having to leave the current drive first.
Not all standard cmdlets will be supported in different drives, and they may not have quite the same behavior (or even the same parameters). Parameters specific to a particular drive are called dynamic parameters.
You can also group top-level cmdlets specific to a particular action to see what's available, although the results won't be the same as they would be in a provider. Windows PowerShell doesn't have any way to sort cmdlets by function, but it can sort them by name and it supports wildcards. Therefore, if you want to find all the cmdlets that might set values, you'd type get-help get-*. If you were pretty sure that the one you wanted had the letter "c" in the beginning of its name, you could type get-help get-c*. (If there's only one hit, then PowerShell will assume you want help on that cmdlet.)
Summary: One size does not fit all
The key thing to take away from this is that Windows PowerShell organizes tasks in one of two ways: by name (at the top level) or by function (within the context of a specific provider). As PowerShell coverage in the operating system expands, you can expect to see more top-level commands and providers, depending on the way the data is structured. You can use get-PSProvider to find the current providers and see what's available, then navigate your options with set-location and get-childitem, or filter search results for top-level cmdlets.
Just remember that there is a reason why Windows PowerShell is split into providers and top-level cmdlets: Neither the provider approach nor the individual cmdlet approach is appropriate for all circumstances.
Miss a column? Check out the Scripting School archive.
A former Terminal Services MVP, Christa Anderson is a program manager on the Terminal Services team at Microsoft and author of the forthcoming Windows Terminal Services Resource Kit from Microsoft Press. She is an internationally known authority on scripting, the author of Windows Terminal Services, The Definitive Guide to MetaFrame XP, and co-author of the book Mastering Windows 2003 Server. If you have a scripting question for Christa, please email her at editor@SearchWincomputing.com. She often uses these emails as fodder for her scripting columns.