Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all functions defined in a .ps1 file?

Tags:

powershell

I have some functions defined in a .ps1 file, which I can import them by a dot operator (. .\script.ps1). After that, I can use these functions in my powershell terminal. If it's a module, I could use the gcm -module ... command to get all commands from the module. But here it's a file, not a module. Is there a way for me to list all functions defined in the file? Like gcm -file "script.ps1".

like image 382
Fajela Tajkiya Avatar asked Sep 02 '25 09:09

Fajela Tajkiya


2 Answers

You can achieve this indirectly, by querying the .File property of the .ScriptBlock property of function objects (System.Management.Automation.FunctionInfo):

  • To match by script file name only:

    Get-Command -Type Function | 
      Where-Object { $_.ScriptBlock.File -like '*[\/]script.ps1' } | 
      ForEach-Object Name
    
  • To avoid ambiguity, you should match against the full script path, not just the file name, e.g.:

    Get-Command -Type Function | 
      Where-Object { $_.ScriptBlock.File -eq 'C:\path\to\script.ps1' } | 
      ForEach-Object Name
    
    • Note that .File always reports the path as a file-system-native one, even if you dot-sourced the script via a PowerShell-only drive. When in doubt, use Convert-Path on a path in order to convert it to a file-system-native one.

Santiago Squarzon points to an interesting variation of your task: Get the list of all functions directly from a script file (.ps1), irrespective of whether the script has been dot-sourced or not (i.e., irrespective of whether the functions have (already) been defined in the session):

# Returns the names of all functions defined in specified script
(Get-Command 'C:\path\to\script.ps1').ScriptBlock.Ast.FindAll(
  { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] },
  $false # parameter `searchNestedScriptBlocks`
).Name

See also:

  • System.Management.Automation.Language.Ast, the class that the script's AST (abstract syntax tree), reported in .ScriptBlock.Ast, is an instance of.

  • This answer by Santiago, which shows more advanced techniques for reflecting on a script's functions (examining their parameters).

like image 174
mklement0 Avatar answered Sep 05 '25 01:09

mklement0


A more advanced use case is when you want to find a Command (i.e function with CmdLetBinding) defined in the current script, by name:

# eg. C:\Users\username\scriptName.ps1
$MyScriptPath = $MyInvocation.MyCommand.Definition.ToString()

# Filter the commands available in the current context.
$Cmd = Get-Command -Type Function |
    Where-Object { $_.ScriptBlock.Ast.Body.ParamBlock.Attributes.TypeName.Name -eq 'CmdLetBinding' } |
        Where-Object { $_.ScriptBlock.File -eq $MyScriptPath } |
            Where-Object { $_.Name -eq $CommandName }

This should give you a list of FunctionInfo objects that have all the metadata about the commands, including the ScriptBlock. After finding/validating, you can execute the command simply using & $CommandName

like image 31
forumulator Avatar answered Sep 05 '25 00:09

forumulator