powershellfunction

Trying to create a source alias or function to the PowerShell . builtin


I'm trying to create a source alias or function to the PowerShell . builtin.

Creating an alias to . does not work :

PS C:\> Set-Alias source .
PS C:\> source $profile.CurrentUserAllHosts
source : The term '.' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name,
or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ source $profile.CurrentUserAllHosts
+ ~~~~~~
    + CategoryInfo          : ObjectNotFound: (.:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\>

I also tried creating a function instead :

PS C:\> Get-Command source | % Definition
param($script)

        if( $script ) {
                . $script
        }

PS C:\> source $profile.CurrentUserAllHosts

And my newly created lastBoot is not recognized :

PS C:\> source $profile.CurrentUserAllHosts
PS C:\> lastBoot
lastBoot : The term 'lastBoot' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ lastBoot
+ ~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (lastBoot:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\>

But if I use the . character, it works :

PS C:\> . $profile.CurrentUserAllHosts
PS C:\> lastBoot

CSName LastBootUpTime
------ --------------
myPC  15/07/2025 12:02:15


PS C:\>

How can I make my source function work ?


Solution

  • Optimized source Function

    Thanks to Santiago Squarzon for the optimized code!

    This version uses [System.Management.Automation.Language.Parser]::ParseFile for AST parsing, eliminating the need for scriptblock execution (. $scriptBlock):

    function source {
        param($script)
    
        if ($script) {
            $tokens = $null
            $errors = $null
            $ast = [System.Management.Automation.Language.Parser]::ParseFile($script, [ref]$tokens, [ref]$errors)
            if ($errors) {
                Write-Error "Errors parsing script: $($errors -join ', ')"
                return
            }
            $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)
            foreach ($func in $functions) {
                $funcName = $func.Name
                $globalFuncBody = $func.Body.GetScriptBlock()
                Set-Item -Path "Function:\global:$funcName" -Value $globalFuncBody
            }
        }
    }
    

    How It Works

    1. Parse the Script: Uses Parser.ParseFile to analyze the script file and get the AST without running any code. It also captures tokens and errors for basic validation.

    2. Find Functions: Searches the AST for all function definitions (supports multiple root-level functions).

    3. Promote to Global Scope: Extracts each function's body as a scriptblock and defines it globally using Set-Item.

    Example Usage