Skip to content

Instantly share code, notes, and snippets.

@TylerLeonhardt
Last active August 21, 2020 13:15
Show Gist options
  • Save TylerLeonhardt/bca6e0991fd12889fce0ebc420e64667 to your computer and use it in GitHub Desktop.
Save TylerLeonhardt/bca6e0991fd12889fce0ebc420e64667 to your computer and use it in GitHub Desktop.
Helper module that helps emulate the Azure Functions environment in a PowerShell session.
<#
Helper module that helps emulate the Azure Functions environment in a PowerShell session. It do so by:
1. Modifying the PSModulePath
2. Loading Azure Functions DLLs so custom types are available
3. Setting up TypeForwards for the Http*Context types since the Azure Functions runtime does this
Usage:
# To do all of that ^
Enable-AzFuncEnvironment
# To change the PSModulePath back
Disable-AzFuncEnvironment
#>
$script:OldPSModulePath = $env:PSModulePath
$script:PathSeparator = [System.IO.Path]::PathSeparator
# TODO: figure out where chocolatey installs it and make cross-plat
$script:PowerShellWorkerPath = "C:\Users\tyleonha\AppData\Roaming\npm\node_modules\azure-functions-core-tools\bin\workers\powershell"
function Enable-AzFuncEnvironment {
[CmdletBinding()]
param (
$Path = '.',
[switch]
$NoDllLoad
)
# Move to the Path
$Path = Push-Location $Path -PassThru -ErrorAction Stop
if (!(Join-Path $Path host.json | Test-Path)) {
Pop-Location
throw "Path doesn't seem to contain an Azure Function App: $($Path.Path)"
}
# Build the PSModulePath
$newPSModulePath = Join-Path $Path.Path ([System.IO.Path]::DirectorySeparatorChar) "Modules" $script:PathSeparator
$hostJson = Get-Content .\host.json -Raw | ConvertFrom-Json
if($hostJson.managedDependency.enabled) {
$functionAppName = [System.IO.Path]::GetFileName($Path.Path)
# TODO: make cross-plat
$newPSModulePath += "C:\Users\tyleonha\AppData\Local\AzureFunctions\$functionAppName\ManagedDependencies$script:PathSeparator"
}
$newPSModulePath += "$script:PowerShellWorkerPath\Modules$script:PathSeparator"
# We still need to keep the VSCode built-in modules in the PSModulePath so things like Script Analysis still works.
if ($host.Name -eq "Visual Studio Code Host") {
$newPSModulePath += $env:PSModulePath -split $script:PathSeparator | Select-Object -Last 1
}
$script:OldPSModulePath = $env:PSModulePath
$env:PSModulePath = $newPSModulePath
# Load the PowerShell Worker DLL and add accelerators
if(!$NoDllLoad) {
Add-Type -Path "$script:PowerShellWorkerPath/Microsoft.Azure.Functions.PowerShellWorker.dll"
$addMethod = [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators").GetMethod("Add", [type[]]@([string], [type]))
$addMethod.Invoke($null, @("HttpResponseContext", [Microsoft.Azure.Functions.PowerShellWorker.HttpResponseContext]))
$addMethod.Invoke($null, @("HttpRequestContext", [Microsoft.Azure.Functions.PowerShellWorker.HttpRequestContext]))
}
}
function Disable-AzFuncEnvironment {
[CmdletBinding()]
param ()
Write-Warning 'Assembly unloading is not possible in .NET Core so the state can''t be cleaned up completely. If you need a full cleanup, restart your PowerShell instance.'
Pop-Location
$env:PSModulePath = $script:OldPSModulePath
}
Export-ModuleMember -Function Enable-AzFuncEnvironment,Disable-AzFuncEnvironment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment