Everyone needs to get good with Advanced Functions – this is the easiest path to the best semantics for everyone. In previous posts we’ve shown how you can add a few simple attributes and get a TON of stuff for free. There is a LOT more to advanced functions. You can go VERY VERY far with advanced functions. I can’t think of anything you can do in C# Cmdlet that you can’t do with a PowerShell cmdlet. Many of these functions are made available to you via the $PsCmdlet variable.
For example, if you write a Cmdlet which takes multiple ParameterSets, you need to know which ParameterSet the user selected. The way you get at that is:
$PsCmdlet.ParameterSetName
Now there is a TON of good stuff in $PSCmdlet and it is not yet well documented so the question is – how do you use it. You ALREADY know the answer of course –
Use PowerShell to explore and figure it out yourself (and then blog it so others can learn)
I was doing a bunch of scripting today and couldn’t remember how to use $PsCmdlet to do something so I decided to write myself a function that allowed me to Test PsCmdlet. I’m sharing it with you here so you can use/enjoy it (remember – explore, learn, blog/share).
function Test-PsCmdlet { <# .Synopsis Test/Explore the $PsCmdlet variable .Description This command creates a nested prompt with $PsCmdlet set so that you explore the capabilities of the parameter. When you write an advanced function, you use $PsCmdlet to give you access to the PowerShell engine and a rich set of functions. Use this function to explore what is available to you. This command copies $PsCmdlet to $p so you can use it and reduce typing. This is implemented by using $host.EnterNestedPrompt() which means that you have to type EXIT to get out of this mode.
.Example Test-PsCmdlet .ReturnValue None .Link about_functions_advanced about_functions_advanced_methods about_functions_advanced_parameters .Notes NAME: Test-PsCmdlet AUTHOR: RugratsVista\jsnover LASTEDIT: 01/10/2009 16:25:42 #> [CmdletBinding()] param() Write-Host -ForegroundColor RED "Interactively explore `$PsCmdlet . Copied `$PsCmdlet to `$p " Write-Host -ForegroundColor RED 'Type "Exit" to return' $p = $pscmdlet function Prompt {"Test-PsCmdlet> "} $host.EnterNestedPrompt() }
Let’s use it and explore:
PS> Test-PScmdlet Interactively explore $PsCmdlet . Copied $PsCmdlet to $p Type "Exit" to return Test-PsCmdlet> $p |gm
TypeName: System.Management.Automation.PSScriptCmdlet
Name MemberType Definition ---- ---------- ---------- CurrentProviderLocation Method System.Management.Automat... Dispose Method System.Void Dispose() Equals Method System.Boolean Equals(Obj... GetDynamicParameters Method System.Object GetDynamicP... GetHashCode Method System.Int32 GetHashCode() GetResolvedProviderPathFromPSPath Method System.Collections.Object... GetResourceString Method System.String GetResource... GetType Method System.Type GetType() GetUnresolvedProviderPathFromPSPath Method System.String GetUnresolv... GetVariableValue Method System.Object GetVariable... Invoke Method Invoke(), System.Collect... ShouldContinue Method System.Boolean ShouldCont... ShouldProcess Method System.Boolean ShouldProc... ThrowTerminatingError Method System.Void ThrowTerminat... ToString Method System.String ToString() TransactionAvailable Method System.Boolean Transactio... WriteCommandDetail Method System.Void WriteCommandD... WriteDebug Method System.Void WriteDebug(St... WriteError Method System.Void WriteError(Er... WriteObject Method System.Void WriteObject(O... WriteProgress Method System.Void WriteProgress... WriteVerbose Method System.Void WriteVerbose(... WriteWarning Method System.Void WriteWarning(... CommandOrigin Property System.Management.Automat... CommandRuntime Property System.Management.Automat... CurrentPSTransaction Property System.Management.Automat... Events Property System.Management.Automat... Host Property System.Management.Automat... InvokeCommand Property System.Management.Automat... InvokeProvider Property System.Management.Automat... JobRepository Property System.Management.Automat... MyInvocation Property System.Management.Automat... ParameterSetName Property System.String ParameterSe... SessionState Property System.Management.Automat... Stopping Property System.Boolean Stopping {...
Test-PsCmdlet> $p.CurrentProviderLocation
MemberType : Method OverloadDefinitions : {System.Management.Automation.PathInfo CurrentProvide rLocation(String providerId)} TypeNameOfValue : System.Management.Automation.PSMethod Value : System.Management.Automation.PathInfo CurrentProvider Location(String providerId) Name : CurrentProviderLocation IsInstance : True
Test-PsCmdlet> $p.CurrentProviderLocation("FileSystem")
Path ---- C:\temp
Test-PsCmdlet> $p.CurrentProviderLocation("registry")
Path ---- HKLM:\
Test-PsCmdlet> exit PS>
BTW – when you write a script and you want to write a file into the current directory – you should NOT use the current directory because in PowerShell, that might be the registry, the certificate store, the WSMAN configuration store, etc. What you REALLY want to do is to write a file into the Current FILESYSTEM directory. This is the way you find out. $psCmdlet.CurrentProviderLocation() is a method that returns the current location for a particular provider (which you pass in as a string). Thus to get the current filesystem directory you type:
$psCmdlet.CurrentProviderLocation("FileSystem")
Remember – this only works when you have $psCmdlet set which is to say when you are in an Advanced Function. Did I mention that everyone should be using Advanced Functions for everything? Get with the program today.
Enjoy!
Jeffrey Snover [MSFT] Windows Management Partner Architect Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx