Home > Back-end >  How to determine if a given PSProvider uses variable syntax, e.g. $env:
How to determine if a given PSProvider uses variable syntax, e.g. $env:

Time:08-24

In a nutshell, is there a way from the shell to determine if a PSProvider's path has an accompanying variable and if so, what that variable is named? The built-in PowerShell providers that support this notation are listed here but I'm referring to any provider in general - built-in/3rd party/custom etc. Is it automatically the case that a provider's drive name (which can be exposed with Get-PSProvider) is always the same as its variable notation name?


For instance:

  • The Environment provider uses the Env: drive which can also be accessed using its variable $env:

  • The Certificate provider uses the Cert: drive which can also be accessed using its variable $cert: but does not implement the IContentCmdletProvider interface -- as indicated by the following error message that's triggered in the shell when referencing a $Cert:xyz path (yet I can use CTRL Space and tab to autocomplete $cert: paths)

    The provider 'Certificate' cannot be used to get or set data using the variable syntax. Cannot use interface. The IContentCmdletProvider interface is not implemented by this provider.


Does this (quoted below) mean that every provider's drive(s) automatically use the variable notation (and will always have a corresponding variable), but not all provider drives are capable of exposing/manipulating their contents/items through the provider's variable syntax?

"You can prefix a provider path with the dollar ($) sign, and access the content of any provider that implements the IContentCmdletProvider interface."


Lastly, would the following be an accurate statement?
Asking "Is there a way from the shell to determine if a PSProvider implements the IContentCmdletProvider interface?" probably isn't sufficient enough to determine if a provider's drive contents can be accessed/manipulated using its variable notation.

CodePudding user response:

PowerShell's namespace variable notation works meaningfully with:

To list the drives in a given session that support this notation - based on the underlying provider's capabilities - use the following:

Get-PSDrive |
  Where-Object { 
    $_.Provider.Implementingtype.GetInterfaces() -contains [System.Management.Automation.Provider.IContentCmdletProvider] 
  }

To list the providers that support this notation, each of which may underly any number of drives - including none - in the current session (the .Drives property of each output object contains the list of current drives backed by that provider):

Get-PSProvider |
  Where-Object { 
    $_.Implementingtype.GetInterfaces() -contains [System.Management.Automation.Provider.IContentCmdletProvider] 
  }

As for your questions:

Does this (quoted below) mean that every provider's drive(s) automatically use the variable notation (and will always have a corresponding variable), but not all provider drives are capable of exposing/manipulating their contents/items through the provider's variable syntax?

Indeed: While each drive's items can be addressed with namespace variable notation, it only works with those drives whose backing providers implements IContentCmdletProvider, because the notation's sole purpose is to access the content of provider items.

Asking "Is there a way from the shell to determine if a PSProvider implements the IContentCmdletProvider interface?" probably isn't sufficient enough to determine if a provider's drive contents can be accessed/manipulated using its variable notation.

It is sufficient to test if a given provider implements IContentCmdletProvider (as shown above), assuming that said provider underlies one or more actual drives in the current session to access items by (as reflected in the output from Get-PSDrive).

PowerShell comes with predefined drives; you can define additional ones with New-PSDrive

  • Related