5

My PowerShell profile is getting a bit cumbersome and I find that I don't always use everything in it. I want to reduce the size of my profile and speed up the startup time that's been getting slower and slower, but I still want to be able to access those functions relatively quickly when I need them.

Is there a way to "dot source" a set of PowerShell functions and aliases from within a separate function such that the sourced functions will be available outside of that function call?

sourcing

2 Answers 2

14

After a great deal of effort (and to make sure I won't lose it later), here's what I've found works.

I've placed the following function in my profile:

function extras {. C:\...\WindowsPowerShell\extrafunctions.ps1}

And then I "dot source" the function within the PowerShell window.

. extras

And all my extra functions are available to the session without slowing down the startup time.

Sign up to request clarification or add additional context in comments.

3 Comments

That approach will work, but have you considered grouping related functions together in modules?
The module approach works very similar to what @aepksbuck is asking for. A library of functions that are available but will not be imported into the session until they are used. Excellent suggestion.
In bash you can do alias ..='. ~/.bash_profile' and when you change something you can run .., but it seems that's impossible with powershell so I'm doing function .. { . $env:profile } and running . .. instead which is less tidy than .. but less effort than typing $env:profile every time.
7

As others have already pointed out, the proper way to go about this would be to put those extra functions into a module. In its simplest form a module is a subfolder in one of the folders listed in $env:PSModulePath with a PowerShell script of the same name (but with the extension .psm1 instead of .ps1):

$env:USERPROFILE
`-Documents
  `-WindowsPowerShell
    `-Modules
      `-ExtraFunctions
        `-ExtraFunctions.psm1

ExtraFunctions.psm1 contains all your functions and ends with an Export-ModuleMember statement exporting the functions/aliases/… you want to publish:

function Get-Foo {
  ...
}

function New-Bar {
  ...
}

...

New-Alias -Name gf -Value Get-Foo
...

Export-ModuleMember -Function Get-Foo, New-Bar, ... -Alias gf, ...

That way you can import specific members:

PS C:\> Import-Module ExtraFunctions -Function Get-Foo

or everything at once:

PS C:\> Import-Module ExtraFunctions

A module can be unloaded via the Remove-Module cmdlet:

PS C:\> Remove-Module ExtraFunctions

With PowerShell v3 and newer you don't even need to import your module manually, because modules are loaded automatically when one of their exported functions/cmdlets is called.

If you want to put in some extra work you can add a module manifest:

@{
  # Script module or binary module file associated with this manifest
  ModuleToProcess = 'ExtraFunctions.psm1'

  # Version number of this module.
  ModuleVersion = '1.0'

  # ID used to uniquely identify this module
  GUID = 'dbf5a7ca-683a-4f18-a090-0700ecccf6ff'

  # Author of this module
  Author = 'Ansgar Wiechers'

  # Company or vendor of this module
  CompanyName = ''

  # Copyright statement for this module
  Copyright = ''

  # Description of the functionality provided by this module
  Description = 'Extra functions.'

  # Minimum version of the Windows PowerShell engine required by this module
  PowerShellVersion = ''

  # Name of the Windows PowerShell host required by this module
  PowerShellHostName = ''

  # Minimum version of the Windows PowerShell host required by this module
  PowerShellHostVersion = ''

  # Minimum version of the .NET Framework required by this module
  DotNetFrameworkVersion = ''

  # Minimum version of the common language runtime (CLR) required by this
  # module
  CLRVersion = ''

  # Processor architecture (None, X86, Amd64, IA64) required by this module
  ProcessorArchitecture = ''

  # Modules that must be imported into the global environment prior to
  # importing this module
  RequiredModules = @()

  # Assemblies that must be loaded prior to importing this module
  RequiredAssemblies = @()

  # Script files (.ps1) that are run in the caller's environment prior to
  # importing this module
  ScriptsToProcess = @()

  # Type files (.ps1xml) to be loaded when importing this module
  TypesToProcess = @()

  # Format files (.ps1xml) to be loaded when importing this module
  FormatsToProcess = @()

  # Modules to import as nested modules of the module specified in
  # ModuleToProcess
  NestedModules = @()

  # Functions to export from this module
  FunctionsToExport = 'Get-Foo', 'New-Bar'

  # Cmdlets to export from this module
  CmdletsToExport = ''

  # Variables to export from this module
  VariablesToExport = ''

  # Aliases to export from this module
  AliasesToExport = 'gf'

  # List of all modules packaged with this module
  ModuleList = @()

  # List of all files packaged with this module
  FileList = 'ExtraFunctions.psm1'

  # Private data to pass to the module specified in ModuleToProcess
  PrivateData = ''
}

Manifests allow you for instance to define dependencies, or to split your module implementation into multiple files. They can be created manually or via the New-ModuleManifest cmdlet. Put the manifest into the root folder of the module:

$env:USERPROFILE
`-Documents
  `-WindowsPowerShell
    `-Modules
      `-ExtraFunctions
        +-ExtraFunctions.psd1
        `-ExtraFunctions.psm1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.