Powershell,  Tools

Get any Function’s source code from the Function PSDrive

You may be already familiar with the concept of PSDrive or Powershell Providers:

PowerShell providers are Microsoft .NET Framework-based programs that make the data in a specialized data store available in PowerShell so that you can view and manage it.
The data that a provider exposes appears in a drive, and you access the data in a path like you would on a hard disk drive. You can use any of the built-in cmdlets that the provider supports to manage the data in the provider drive. And, you can use custom cmdlets that are designed especially for the data.
The providers can also add dynamic parameters to the built-in cmdlets. These are parameters that are available only when you use the cmdlet with the provider data.

You are likely using some Providers (especially the File System Provider) without even realizing it, while some come in handy if you need to perform actions on specific types of objects. For example you can list the certificates under your profile running Get-ChildItem -Path Cert:\CurrentUser\My. Notice the use of “Cert:” (Certificate) Provider (or PSDrive).

The Function: drive allows to list all functions available in the current powershell session:

PS /> Get-ChildItem Function:

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        cd..                                                          
Function        cd\                                                           
Function        Clear-Host                                                    
Function        Convert-CertBase64DataToFile                       2.7.2      LSEFunctions
Function        Convert-CertificateToBase64String                  2.7.2      LSEFunctions
Function        ConvertFrom-Base64                                 2.7.2      LSEFunctions
Function        ConvertTo-Base64                                   2.7.2      LSEFunctions
Function        ConvertTo-CamelCase                                2.7.2      LSEFunctions
Function        ConvertTo-PascalCase                               2.7.2      LSEFunctions
Function        Format-Xml                                         2.7.2      LSEFunctions
Function        Get-ADUserPasswordExpirationDate                   2.7.2      LSEFunctions
Function        Get-ArrayItemIndex                                 2.7.2      LSEFunctions
Function        Get-EncryptedCredentialFromFile                    2.7.2      LSEFunctions
Function        Get-LoggedOnUser                                   2.7.2      LSEFunctions
Function        Get-SystemUptime                                   2.7.2      LSEFunctions
Function        help                                                          
Function        New-Password                                       2.7.2      LSEFunctions
Function        oss                                                           
Function        Pause                                                         
Function        prompt                                                        
Function        PSConsoleHostReadLine                              2.0.0      PSReadLine
Function        Set-EncryptedCredentialsToFile                     2.7.2      LSEFunctions
Function        Set-PSModulePath                                   2.7.2      LSEFunctions
Function        Set-WindowTitle                                    2.7.2      LSEFunctions
Function        TabExpansion2                                                 
Function        Test-Guid                                          2.7.2      LSEFunctions
Function        Test-IsAdmin                                       2.7.2      LSEFunctions
Function        Unprotect-SecureString                             2.7.2      LSEFunctions
Function        Update-DomainPassword                              2.7.2      LSEFunctions
Function        Update-ModuleVersion                               2.7.2      LSEFunctions
Function        Update-StringInFile                                2.7.2      LSEFunctions
Function        Write-RawCertData                                  2.7.2      LSEFunctions

As you can see some functions come with Powershell (e.g. oss, pause, prompt, PSConsoleHostReadLine, Clear-Host) while others are imported from a one of my custom modules I have imported in the current console.

Note: the Function drive only shows Functions (as you can guess ?), not binary cmdlets.

Functions expose some interesting properties, use Get-Member to list them:

PS /> Get-ChildItem Function:Unprotect-SecureString | Get-Member                    


   TypeName: System.Management.Automation.FunctionInfo
Name                MemberType     Definition
----                ----------     ----------
Equals              Method         bool Equals(System.Object obj)
GetHashCode         Method         int GetHashCode()
GetType             Method         type GetType()
ResolveParameter    Method         System.Management.Automation.ParameterMetadata ResolveParameter(string name)
ToString            Method         string ToString()
PSDrive             NoteProperty   PSDriveInfo PSDrive=Function
PSIsContainer       NoteProperty   bool PSIsContainer=False
PSPath              NoteProperty   string PSPath=Microsoft.PowerShell.Core\Function::Unprotect-SecureString
PSProvider          NoteProperty   ProviderInfo PSProvider=Microsoft.PowerShell.Core\Function
CmdletBinding       Property       bool CmdletBinding {get;}
CommandType         Property       System.Management.Automation.CommandTypes CommandType {get;}
DefaultParameterSet Property       string DefaultParameterSet {get;}
Definition          Property       string Definition {get;}
Description         Property       string Description {get;set;}
HelpFile            Property       string HelpFile {get;}
Module              Property       psmoduleinfo Module {get;}
ModuleName          Property       string ModuleName {get;}
Name                Property       string Name {get;}
Noun                Property       string Noun {get;}
Options             Property       System.Management.Automation.ScopedItemOptions Options {get;set;}
OutputType          Property       System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Automation.PSTypeName] OutputType {get;}
Parameters          Property       System.Collections.Generic.Dictionary[string,System.Management.Automation.ParameterMetadata] Parameters {get;}
ParameterSets       Property       System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Automation.CommandParameterSetInfo] ParameterSe…
RemotingCapability  Property       System.Management.Automation.RemotingCapability RemotingCapability {get;}
ScriptBlock         Property       scriptblock ScriptBlock {get;}
Source              Property       string Source {get;}
Verb                Property       string Verb {get;}
Version             Property       version Version {get;}
Visibility          Property       System.Management.Automation.SessionStateEntryVisibility Visibility {get;set;}
HelpUri             ScriptProperty System.Object HelpUri {get=$oldProgressPreference = $ProgressPreference…

For example, Module shows the module that exposes the current function, OutputType (if the function specifies one) is the type returned, Visibility is the Scope the function has access to.

I found particularly useful the possibility to read the function’s source code from the ScriptBlock or Definition properties (I used it a few times to debug exceptions thrown by some function I was using interactively at the console):

PS /> Get-Item Function:Unprotect-SecureString | Select-Object -ExpandProperty Definition

[CmdletBinding()]

param(
    [parameter(Mandatory=$true, Position=1)]
    [SecureString]$SecureString
)

[String]$stringValue = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString))

return $stringValue

Or, the abbreviated form I prefer:

PS /> ${Function:Unprotect-SecureString}

[CmdletBinding()]

param(
    [parameter(Mandatory=$true, Position=1)]
    [SecureString]$SecureString
)

[String]$stringValue = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString))

return $stringValue

The secret of creativity is knowing how to hide your sources. – Albert Einstein

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.