You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, when parsing PowerShell files, there is not way to pass a session context. Instead, PowerShell uses a global context. This means that we do no have a way to only specify modules which are only available to a function app. As a workaround, we can install the modules locally in one of the global paths of $Env:PSModulePath. However, this will not work when working on Azure and it is a blocker for the PowerShell Functions v2 programming model which uses PowerShell 7.4.
For this repro, I would like to use a custom enum defined in my CustomModule PowerShell module.
Custom module definition:
$code=@'using System;using System.Management.Automation;namespace CustomModule{ // Define custom enum public enum FruitType { Apple, Banana, Orange, Grape, Mango } [Cmdlet(VerbsCommon.Get, "Fruit")] public class GetFruitCmdlet : Cmdlet { // Parameter to accept the FruitType enum value from PowerShell [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)] public FruitType Fruit { get; set; } // The ProcessRecord method will be called when the cmdlet is executed protected override void ProcessRecord() { // Output the selected fruit to the PowerShell pipeline WriteObject($"You selected {Fruit.ToString()}."); } }}'@# From this code, I generate the following assembly:Add-Type-TypeDefinition $code-OutputAssembly CustomModule.dll
CustomModule.psd1 module manifest:
@{
# Script module or binary module file associated with this manifest.RootModule='CustomModule.dll'# Version number of this module.ModuleVersion='0.0.1'# ID used to uniquely identify this moduleGUID='a29f3d82-c4e7-4ac2-8e09-7eb5afeae0f9'FunctionsToExport=@()
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.CmdletsToExport=@("Get-Fruit")
# Variables to export from this moduleVariablesToExport='*'# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.AliasesToExport=@()
}
This custom module is placed at the functionAppRoot\Modules directory (this path gets appended to the $env:PSModulePath variable before invoking the function).
PowerShell function definition (functions-parser-repro.psm1):
ScriptBlockAst? fileAst = Parser.ParseFile(powerShellFile.FullName, out _, out ParseError[] errors);
Note: The parsing issue is because the types defined in the custom module are not loaded prior to parsing the file in the runspace.
Follow up question: In order to use the using <ModuleName> statement, does the module need to be available in the global $env:PSModulePath path?
Would it be possible to get this fixed for PowerShell 7.4?
Expected behavior
Parser.ParseFile should take a session context with the modules available to the function app, so that the types are available.
Actual behavior
`Parser.ParseFile` fails because the types are not loaded / available in the runspace.
Error details
[2023-07-27T02:02:11.964Z] ERROR: Unable to find type [CustomModule.FruitType].[2023-07-27T02:02:11.966Z][2023-07-27T02:02:11.967Z] Exception :[2023-07-27T02:02:11.968Z] Type : System.Management.Automation.RuntimeException[2023-07-27T02:02:11.969Z] ErrorRecord :[2023-07-27T02:02:11.970Z] Exception :[2023-07-27T02:02:11.971Z] Type : System.Management.Automation.ParentContainsErrorRecordException[2023-07-27T02:02:11.971Z] Message : Unable to find type [CustomModule.FruitType].[2023-07-27T02:02:11.972Z] HResult : -2146233087[2023-07-27T02:02:11.973Z] TargetObject : CustomModule.FruitType[2023-07-27T02:02:11.974Z] CategoryInfo : InvalidOperation: (CustomModule.FruitType:TypeName) [], ParentContainsErrorRecordException[2023-07-27T02:02:11.975Z] FullyQualifiedErrorId : TypeNotFound[2023-07-27T02:02:11.975Z] InvocationInfo :[2023-07-27T02:02:11.976Z] ScriptLineNumber : 19[2023-07-27T02:02:11.977Z] OffsetInLine : 18[2023-07-27T02:02:11.978Z] HistoryId : 1[2023-07-27T02:02:11.979Z] ScriptName : C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1[2023-07-27T02:02:11.980Z] Line : $fruitName = [CustomModule.FruitType]::Apple[2023-07-27T02:02:11.981Z][2023-07-27T02:02:11.982Z] Statement : [CustomModule.FruitType][2023-07-27T02:02:11.983Z] PositionMessage : At C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1:19 char:18[2023-07-27T02:02:11.984Z] + $fruitName = [CustomModule.FruitType]::Apple[2023-07-27T02:02:11.984Z] + ~~~~~~~~~~~~~~~~~~~~~~~~[2023-07-27T02:02:11.985Z] PSScriptRoot : C:\MyFunctionApps\PSNPMBugBash[2023-07-27T02:02:11.986Z] PSCommandPath : C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1[2023-07-27T02:02:11.987Z] CommandOrigin : Internal[2023-07-27T02:02:11.988Z] ScriptStackTrace : at MyHttpTriggerParseRepro, C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1: line 19[2023-07-27T02:02:11.989Z] TargetSite :[2023-07-27T02:02:11.990Z] Name : ResolveTypeName[2023-07-27T02:02:11.991Z] DeclaringType : System.Management.Automation.TypeOps, System.Management.Automation, Version=7.4.0.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35[2023-07-27T02:02:11.992Z] MemberType : Method[2023-07-27T02:02:11.992Z] Module : System.Management.Automation.dll[2023-07-27T02:02:11.993Z] Message : Unable to find type [CustomModule.FruitType].[2023-07-27T02:02:11.994Z] Data : System.Collections.ListDictionaryInternal[2023-07-27T02:02:11.996Z] Source : System.Management.Automation[2023-07-27T02:02:11.998Z] HResult : -2146233087[2023-07-27T02:02:11.998Z] StackTrace :[2023-07-27T02:02:11.999Z] at System.Management.Automation.TypeOps.ResolveTypeName(ITypeName typeName, IScriptExtent errorPos)[2023-07-27T02:02:12.000Z] at System.Management.Automation.Interpreter.FuncCallInstruction`3.Run(InterpretedFrame frame)[2023-07-27T02:02:12.001Z] at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)[2023-07-27T02:02:12.002Z] TargetObject : CustomModule.FruitType[2023-07-27T02:02:12.002Z] CategoryInfo : InvalidOperation: (CustomModule.FruitType:TypeName) [], RuntimeException[2023-07-27T02:02:12.003Z] FullyQualifiedErrorId : TypeNotFound[2023-07-27T02:02:12.004Z] InvocationInfo :[2023-07-27T02:02:12.005Z] ScriptLineNumber : 19[2023-07-27T02:02:12.006Z] OffsetInLine : 18[2023-07-27T02:02:12.006Z] HistoryId : 1[2023-07-27T02:02:12.007Z] ScriptName : C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1[2023-07-27T02:02:12.008Z] Line : $fruitName = [CustomModule.FruitType]::Apple[2023-07-27T02:02:12.009Z][2023-07-27T02:02:12.011Z] Statement : [CustomModule.FruitType][2023-07-27T02:02:12.012Z] PositionMessage : At C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1:19 char:18[2023-07-27T02:02:12.013Z] + $fruitName = [CustomModule.FruitType]::Apple[2023-07-27T02:02:12.014Z] + ~~~~~~~~~~~~~~~~~~~~~~~~[2023-07-27T02:02:12.015Z] PSScriptRoot : C:\MyFunctionApps\PSNPMBugBash[2023-07-27T02:02:12.016Z] PSCommandPath : C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1[2023-07-27T02:02:12.017Z] CommandOrigin : Internal[2023-07-27T02:02:12.018Z] ScriptStackTrace : at MyHttpTriggerParseRepro, C:\MyFunctionApps\PSNPMBugBash\functions-parser-repro.psm1: line 19[2023-07-27T02:02:12.019Z][2023-07-27T02:02:12.020Z][2023-07-27T02:02:12.020Z] Result: ERROR: Unable to find type [CustomModule.FruitType].
Environment data
Name Value
---------
PSVersion 7.4.0-preview.3
PSEdition Core
GitCommitId 7.4.0-preview.3
OS Microsoft Windows 6.2.9200
Platform Win32NT
PSCompatibleVersions {1.0,2.0,3.0,4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Visuals
No response
The text was updated successfully, but these errors were encountered:
@Francisco-Gamino I cannot reproduce the issue within pwsh by following the repro steps.
Theoretically, the parsing of the psm1 file doesn't require a custom type to be resolved unless the type is used in a PowerShell class definition. Feel free to ping me to take a look at the issue together.
Steps to reproduce
Currently, when parsing PowerShell files, there is not way to pass a session context. Instead, PowerShell uses a global context. This means that we do no have a way to only specify modules which are only available to a function app. As a workaround, we can install the modules locally in one of the global paths of
$Env:PSModulePath
. However, this will not work when working on Azure and it is a blocker for thePowerShell Functions
v2 programming model which usesPowerShell 7.4
.This is the PowerShell API that we use the parse the files: https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.parser.parsefile?view=powershellsdk-7.3.0
For this repro, I would like to use a custom enum defined in my
CustomModule
PowerShell module.Custom module definition:
CustomModule.psd1
module manifest:This custom module is placed at the
functionAppRoot\Modules
directory (this path gets appended to the$env:PSModulePath
variable before invoking the function).PowerShell function definition (functions-parser-repro.psm1):
Note: The parsing issue is because the types defined in the custom module are not loaded prior to parsing the file in the runspace.
Follow up question: In order to use the
using <ModuleName>
statement, does the module need to be available in the global $env:PSModulePath path?Would it be possible to get this fixed for
PowerShell 7.4
?Expected behavior
Parser.ParseFile should take a session context with the modules available to the function app, so that the types are available.
Actual behavior
`Parser.ParseFile` fails because the types are not loaded / available in the runspace.
Error details
Environment data
Visuals
No response
The text was updated successfully, but these errors were encountered: