Description
Description
Need to have an isolated build process so that no assemblies clobber others and no modules are loaded to confuse platyPS.
You can create an isolated runspace from within PowerShell itself using the .NET API. This lets you build your module in a separate session state—essentially an “isolated runtime” inside your current process—without the modules or assemblies imported in your parent session.
However, note that runspace isolation isn’t as complete as a new process (for example, already-loaded assemblies may still be visible), but it does allow you to start with a fresh session state and avoid the auto-loaded modules and functions from your current session.
Below is an example of how you can create an isolated runspace with a clean initial session state, dot-source only your build script, run your build function, and then clean up the runspace:
# Define the build logic as a ScriptBlock
$buildScript = {
# Disable module autoloading
$PSModuleAutoloadingPreference = 'None'
$var = Get-Date -Format "yyyy-MM-dd-HH-mm-ss"
# Blank out PSModulePath to prevent any module auto-loading from default locations
New-Item -Path "C:\Repos\$var" -ItemType Directory
}
# Create a new initial session state (only core commands are loaded)
$iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Create and open a new runspace with this session state
$runspace = [runspacefactory]::CreateRunspace($iss)
$runspace.Open()
# Create a new PowerShell instance and assign it the isolated runspace
$ps = [PowerShell]::Create()
$ps.Runspace = $runspace
# Add the build script from the ScriptBlock by converting it to a string
$ps.AddScript($buildScript.ToString()) | Out-Null
# Invoke the script in the isolated runspace
$results = $ps.Invoke()
$results
# Check for any errors during execution
if ($ps.HadErrors) {
Write-Error 'Errors occurred in the isolated build runspace:'
$ps.Streams.Error | ForEach-Object { Write-Error $_.ToString() }
}
# Clean up the runspace and PowerShell instance
$ps.Dispose()
$runspace.Close()
$runspace.Dispose()
Explanation
-
InitialSessionState: By using
[InitialSessionState]::CreateDefault()
, you start with a clean slate containing only the core commands and providers. Modules or functions imported in your parent session aren’t carried over. -
Restricting PSModulePath: In the script block (or by modifying the session state), you can clear or restrict
$env:PSModulePath
so that only modules you explicitly load (like your build script) are available. -
[PowerShell]::Create(): This creates a new PowerShell instance that runs in the separate runspace. Commands added to this instance run in isolation from the current session.
-
Dot-Sourcing Your Build Script: The script block dot-sources
build-module.ps1
so that only the necessary build functions are loaded. Then,Build-MyModule
is called to build and output your module artifact. -
Cleanup: Disposing of the runspace and PowerShell instance cleans up any resources used during the isolated build process.
This approach keeps your build operations isolated within the same process, allowing you to avoid conflicts with preloaded modules and to build your module without interference. If you need complete isolation (for example, if there’s concern about already loaded assemblies), you might consider spawning a new process using pwsh -NoProfile
as an alternative.