views:

64

answers:

1

I'm writing a NavigationCmdletProvider for PowerShell. Through the GetItem and GetChildItems overrides, there are various types of objects that are written to the pipeline.

The docs for IPropertyCmdletProvider interface tell us the following:

Developers should implement this interface under the following conditions:

  • When users must use cmdlets such as the Get-Property and Set-Property cmdlets.
  • For a providers that derive from the ItemCmdletProvider, ContainerCmdletProvider, or NavigationCmdletProvider classes.

Confusion:

Not a lot of useful information in my opinion because how would a user know if they must use the Get-Property and Set-Property cmdlet's? I would imagine that's up to the Cmdlet author. The big confusion (for me at least) is if the Cmdlet writes the objects to the pipeline; and those objects have properties exposed that are callable (i.e. get/set); what benefits does calling Get-Property/Set-Property have over manipulating the object(s) directly?

Question:

Under what circumstances should the IPropertyCmdletProvider interface be implemented?

I know I'm missing something here! Any insight would be greatly appreciated.

+3  A: 

Wow those docs are a bit old. There are no Get/Set-Property cmdlets. This must be referring to the Get/Set-ItemProperty cmdlets. In the case of the RegistryProvider, these cmdlets are essential because it is the only way to access registry values. That is, the Get-Item/ChildItem cmdlets only return RegistryKey objects and never a registry value object (they don't exist in .NET). You have to use Get/Set-ItemProperty to get/set specific regvals under a regkey.

OTOH the FileSystem provider allows you to directly access containers (dirs) and leafs (files). You can get the content of a file directly. Still, you can use Get-ItemProperty if you want to get the LastWriteTime of a file:

PS> Get-ItemProperty -Path .\DotNetTypes.format.ps1xml -Name LastWriteTime


PSPath        : Microsoft.PowerShell.Core\FileSystem::C:\Win
                dows\System32\WindowsPowerShell\v1.0\DotNetT
                ypes.format.ps1xml
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::C:\Win
                dows\System32\WindowsPowerShell\v1.0
PSChildName   : DotNetTypes.format.ps1xml
PSDrive       : C
PSProvider    : Microsoft.PowerShell.Core\FileSystem
LastWriteTime : 4/24/2009 11:21:46 AM

However, I wouldn't normally access this property in this fashion. I find the output is way to verbose. I would do this:

PS> (Get-Item .\DotNetTypes.format.ps1xml).LastWriteTime

Friday, April 24, 2009 11:21:46 AM

As for guidance, I would say that you really need to implement this interface if you take the RegistryProvider approach but it is less important if you go the route the FileSystem provider went because you can easly access the properties directly of the objects returned by Get-Item/ChildItem.

Keith Hill
You're right! Those docs do seem old as I look at them closer. I like your explanation and I think I see where you're coming from. Is it safe to say that if there is not a .NET object being written to the pipeline, (i.e. Registry Keys), then the IPropertyCmdletProvider would still allow for the manipulation of these items? Otherwise, using the objects directly (in their native .NET form) is the "best" way to go? I hope that makes sense. :)
Scott Saad
Certainly if the provider is outputting rich objects whose properties can be set directly then the ItemProperty cmdlets aren't so important IMO. However, in the case of RegistryKey, which is the only object output by the RegistryProvider, the values aren't represented as properties in .NET. You can only get to them via the Get/SetValue() overloads. In this case, Get/Set-ItemProperty provides a "property" view on something that is implemented in .NET as methods. Personally, I wish they would have created a RegistryValue object in PowerShell and exposed it as a leaf item.
Keith Hill