internal static PowerShell Convert(ScriptBlockAst body, ReadOnlyCollection <ParameterAst> functionParameters, bool isTrustedInput, ExecutionContext context, Dictionary <string, object> variables, bool filterNonUsingVariables, bool?createLocalScope, object[] args) { ExecutionContext.CheckStackDepth(); if (args == null) { args = Array.Empty <object>(); } // Perform validations on the ScriptBlock. GetSimplePipeline can allow for more than one // pipeline if the first parameter is true, but Invoke-Command doesn't yet support multiple // pipelines in a PowerShell (it just grabs the last command directly.) The rest of this // code properly supports multiple pipelines, so it should just work to change the false to true // if/when Invoke-Command can support multiple pipelines. string errorId; string errorMsg; body.GetSimplePipeline(true, out errorId, out errorMsg); if (errorId != null) { throw new ScriptBlockToPowerShellNotSupportedException(errorId, null, errorMsg); } var checker = new ScriptBlockToPowerShellChecker { ScriptBeingConverted = body }; if (functionParameters != null) { foreach (var parameter in functionParameters) { parameter.InternalVisit(checker); } } body.InternalVisit(checker); // When the context is null (or they haven't supplied any variables), throw, but only if we really need the // context (basically, if we have some variable reference to resolve). if (context == null && (checker.HasUsingExpr || checker.UsesParameter) && (variables == null)) { throw new PSInvalidOperationException(AutomationExceptions.CantConvertScriptBlockWithNoContext); } try { var converter = new ScriptBlockToPowerShellConverter { _context = context, _createLocalScope = createLocalScope }; if (checker.HasUsingExpr) { converter._usingValueMap = GetUsingValues(body, isTrustedInput, context, variables, filterNonUsingVariables).Item1; } if (checker.UsesParameter) { // If any parameters are used, we create a new scope and bind the parameters. var newScope = context.EngineSessionState.NewScope(false); context.EngineSessionState.CurrentScope = newScope; context.EngineSessionState.CurrentScope.ScopeOrigin = CommandOrigin.Internal; var locals = MutableTuple.MakeTuple(Compiler.DottedLocalsTupleType, Compiler.DottedLocalsNameIndexMap); // Get the parameter metadata for the script block. // If 'functionParameters' is not null, then the ScriptBlockAst is actually the body of a FunctionDefinitionAst, and it doesn't have a ParamBlock. // If 'functionParameters' is null, then the ScriptBlockAst may have parameters defined in its ParamBlock. bool usesCmdletBinding = false; var parameters = functionParameters != null ? Compiler.GetParameterMetaData(functionParameters, true, ref usesCmdletBinding) : ((IParameterMetadataProvider)body).GetParameterMetadata(true, ref usesCmdletBinding); object[] remainingArgs = ScriptBlock.BindArgumentsForScriptblockInvoke( (RuntimeDefinedParameter[])parameters.Data, args, context, false, null, locals); locals.SetAutomaticVariable(AutomaticVariable.Args, remainingArgs, context); newScope.LocalsTuple = locals; } foreach (var pipeline in body.EndBlock.Statements.OfType <PipelineAst>()) { converter._powershell.AddStatement(); converter.ConvertPipeline(pipeline, isTrustedInput); } return(converter._powershell); } finally { if (checker.UsesParameter) { context.EngineSessionState.RemoveScope(context.EngineSessionState.CurrentScope); } } }
internal static PowerShell Convert(ScriptBlockAst body, IEnumerable <ParameterAst> functionParameters, ExecutionContext context, Dictionary <string, object> variables, bool filterNonUsingVariables, bool?createLocalScope, object[] args) { string str; string str2; PowerShell shell; ExecutionContext.CheckStackDepth(); if (args == null) { args = ScriptBlock.EmptyArray; } body.GetSimplePipeline(false, out str, out str2); if (str != null) { throw new ScriptBlockToPowerShellNotSupportedException(str, null, str2, new object[0]); } ScriptBlockToPowerShellChecker visitor = new ScriptBlockToPowerShellChecker { ScriptBeingConverted = body }; if (functionParameters != null) { foreach (ParameterAst ast in functionParameters) { ast.InternalVisit(visitor); } } body.InternalVisit(visitor); if (((context == null) && (visitor.HasUsingExpr || visitor.UsesParameter)) && (variables == null)) { throw new PSInvalidOperationException(AutomationExceptions.CantConvertScriptBlockWithNoContext); } try { ScriptBlockToPowerShellConverter converter = new ScriptBlockToPowerShellConverter { _context = context, _createLocalScope = createLocalScope }; if (visitor.HasUsingExpr) { converter._usingValues = GetUsingValues(body, context, variables, filterNonUsingVariables); } if (visitor.UsesParameter) { SessionStateScope scope = context.EngineSessionState.NewScope(false); context.EngineSessionState.CurrentScope = scope; context.EngineSessionState.CurrentScope.ScopeOrigin = CommandOrigin.Internal; MutableTuple locals = MutableTuple.MakeTuple(Compiler.DottedLocalsTupleType, Compiler.DottedLocalsNameIndexMap); bool usesCmdletBinding = false; object[] objArray = ScriptBlock.BindArgumentsForScripblockInvoke((RuntimeDefinedParameter[])((IParameterMetadataProvider)body).GetParameterMetadata(true, ref usesCmdletBinding).Data, args, context, false, null, locals); locals.SetAutomaticVariable(AutomaticVariable.Args, objArray, context); scope.LocalsTuple = locals; } foreach (PipelineAst ast2 in body.EndBlock.Statements.OfType <PipelineAst>()) { converter._powershell.AddStatement(); converter.ConvertPipeline(ast2); } shell = converter._powershell; } finally { if (visitor.UsesParameter) { context.EngineSessionState.RemoveScope(context.EngineSessionState.CurrentScope); } } return(shell); }