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?
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
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.