4

I have a few modules in my powershell profile, and their loading sometimes takes a lot of time (10-15s). I would like to load them in a background thread using something like this:

Start-Job -ScriptBlock { Import-Module -Global DockerCompletion }

The problem is that even though the documentation states that Import-Module uses global scope as a default, when I use Get-Module in the parent shell the module is not listed, so it was not loaded even though the job states completed.

Some of modules I use:

Import-Module “$env:ChocolateyInstall\helpers\chocolateyProfile.psm1” -Force
Import-Module WSLTabCompletion
Import-Module posh-git
Import-Module npm-completion
Import-Module DockerCompletion

EDIT: I am using pwsh 7.1

Luk164
  • 657
  • 8
  • 22
  • Apart from the first one, which looks like it installs somewhere custom, don't the others just auto-load when needed? As long as the modules are in a known location (somewhere in the `$PsModulePath`, which could include your custom path), PowerShell should do this as required: [Implicitly Importing a Module](https://learn.microsoft.com/en-us/powershell/scripting/developer/module/importing-a-powershell-module?view=powershell-7.1#implicitly-importing-a-module-powershell-30) – boxdog Aug 31 '21 at 12:50
  • @boxdog Does not work like that. If the completion module is not loaded it will not trigger. I double checked that right now. – Luk164 Aug 31 '21 at 12:56
  • 3
    `Start-Job` runs the background job in a separate process, so doesn't affect the global scope of the calling session. – Mathias R. Jessen Aug 31 '21 at 13:00
  • There might be a solution here using ThreadJobs but this requires PowerShell Core. Alternatively you might be able to whip something up using `[System.Threading.Thread]::Start`, but I don't have any ready examples or code to provide as an answer here. – codewario Aug 31 '21 at 13:06
  • 1
    Also, what do you mean "if the completion module is not loaded it will not trigger"? I've written a couple of modules and if they are on the module path they automatically load. I've not done anything specific to get command completion working, and they fit the rules of autoloading modules in PowerShell. – codewario Aug 31 '21 at 13:06
  • It looks like the completion modules are using `Register-ArgumentCompleter` to generate and add various tab-completion behaviors rather than functions/cmdlets. I think you cannot do this in the background either since they need to register in the current context. – Cpt.Whale Aug 31 '21 at 14:26
  • I also did some testing with both the `PSThreadJob` (open source module for 5.1 thread jobs) and the official `ThreadJob` module for PS Core, neither seem to be able to import a module where it is usable from the invoking session, at least not by default. – codewario Aug 31 '21 at 14:52
  • @BendertheGreatest So essentially the module is badly written and I cannot load it in the background? I am using pwsh 7.1 BTW if that makes any difference. – Luk164 Aug 31 '21 at 16:12
  • I'm saying I did some testing with threadjob solutions available to both PowerShell Core and Windows PowerShell, and neither showed modules imported in the thread job were available from the main thread (used `Get-Module` to see which modules were loaded in the current session). To be fair, I have not gone the full mile of inspection to see what members are available from the threadjob objects, but at a glance it doesn't seem like a background thread will work for importing modules. – codewario Aug 31 '21 at 16:24
  • In theory objects changed in the background thread should eventually make their way to the main thread, but the ways to force this behavior I'm not sure whether this can be done with ThreadJobs or not. There might be some way to make this work if you use the `System.Threading` namespace directly. – codewario Aug 31 '21 at 16:27
  • You don't need to import any modules if they are already installed in your modules folder as listed in `$env:PSModulePath` – Dennis Aug 31 '21 at 17:38
  • @Dennis The folders are in the modules path, yet they do not start working until the Import*modules command is complete – Luk164 Sep 01 '21 at 10:13
  • Then you need to contact the author. That is not how PowerShell modules are supposed to work in PowerShell 3.0 and later. – Dennis Sep 01 '21 at 11:53
  • https://github.com/dahlbyk/posh-git#step-2-import-posh-git-from-your-powershell-profile I think tab completion does need import-module in profile. – NanoNova Mar 07 '23 at 06:43
  • As long as the modules is stored properly in the module path they will autoload. Check that they are stored in a folder listed in `$env:PSModulePath -split ';'` – Dennis May 31 '23 at 21:27

0 Answers0