Esempio n. 1
0
        /// <summary>
        /// Get a Hashtable object out of a PowerShell data file (.psd1)
        /// </summary>
        /// <param name="parameterName">
        /// Name of the parameter that takes the specified .psd1 file as a value
        /// </param>
        /// <param name="psDataFilePath">
        /// Path to the powershell data file
        /// </param>
        /// <param name="context">
        /// ExecutionContext to use
        /// </param>
        /// <param name="allowedCommands">
        /// Set of command names that are allowed to use in the .psd1 file
        /// </param>
        /// <param name="allowedVariables">
        /// Set of variable names that are allowed to use in the .psd1 file
        /// </param>
        /// <param name="allowEnvironmentVariables">
        /// If true, allow to use environment variables in the .psd1 file
        /// </param>
        /// <param name="skipPathValidation">
        /// If true, caller guarantees the path is valid
        /// </param>
        /// <returns></returns>
        internal static Hashtable EvaluatePowerShellDataFile(
            string parameterName,
            string psDataFilePath,
            ExecutionContext context,
            IEnumerable <string> allowedCommands,
            IEnumerable <string> allowedVariables,
            bool allowEnvironmentVariables,
            bool skipPathValidation)
        {
            if (!skipPathValidation && string.IsNullOrEmpty(parameterName))
            {
                throw PSTraceSource.NewArgumentNullException("parameterName");
            }

            if (string.IsNullOrEmpty(psDataFilePath))
            {
                throw PSTraceSource.NewArgumentNullException("psDataFilePath");
            }

            if (context == null)
            {
                throw PSTraceSource.NewArgumentNullException("context");
            }

            string resolvedPath;

            if (skipPathValidation)
            {
                resolvedPath = psDataFilePath;
            }
            else
            {
                #region "ValidatePowerShellDataFilePath"

                bool isPathValid = true;

                // File extension needs to be .psd1
                string pathExt = Path.GetExtension(psDataFilePath);
                if (string.IsNullOrEmpty(pathExt) ||
                    !StringLiterals.PowerShellDataFileExtension.Equals(pathExt, StringComparison.OrdinalIgnoreCase))
                {
                    isPathValid = false;
                }

                ProviderInfo provider;
                var          resolvedPaths = context.SessionState.Path.GetResolvedProviderPathFromPSPath(psDataFilePath, out provider);

                // ConfigPath should be resolved as FileSystem provider
                if (provider == null || !Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName.Equals(provider.Name, StringComparison.OrdinalIgnoreCase))
                {
                    isPathValid = false;
                }

                // ConfigPath should be resolved to a single path
                if (resolvedPaths.Count != 1)
                {
                    isPathValid = false;
                }

                if (!isPathValid)
                {
                    throw PSTraceSource.NewArgumentException(
                              parameterName,
                              ParserStrings.CannotResolvePowerShellDataFilePath,
                              psDataFilePath);
                }

                resolvedPath = resolvedPaths[0];

                #endregion "ValidatePowerShellDataFilePath"
            }

            #region "LoadAndEvaluatePowerShellDataFile"

            object evaluationResult;
            try
            {
                // Create the scriptInfo for the .psd1 file
                string      dataFileName       = Path.GetFileName(resolvedPath);
                var         dataFileScriptInfo = new ExternalScriptInfo(dataFileName, resolvedPath, context);
                ScriptBlock scriptBlock        = dataFileScriptInfo.ScriptBlock;

                // Validate the scriptblock
                scriptBlock.CheckRestrictedLanguage(allowedCommands, allowedVariables, allowEnvironmentVariables);

                // Evaluate the scriptblock
                object oldPsScriptRoot = context.GetVariableValue(SpecialVariables.PSScriptRootVarPath);
                try
                {
                    // Set the $PSScriptRoot before the evaluation
                    context.SetVariable(SpecialVariables.PSScriptRootVarPath, Path.GetDirectoryName(resolvedPath));
                    evaluationResult = PSObject.Base(scriptBlock.InvokeReturnAsIs());
                }
                finally
                {
                    context.SetVariable(SpecialVariables.PSScriptRootVarPath, oldPsScriptRoot);
                }
            }
            catch (RuntimeException ex)
            {
                throw PSTraceSource.NewInvalidOperationException(
                          ex,
                          ParserStrings.CannotLoadPowerShellDataFile,
                          psDataFilePath,
                          ex.Message);
            }

            var retResult = evaluationResult as Hashtable;
            if (retResult == null)
            {
                throw PSTraceSource.NewInvalidOperationException(
                          ParserStrings.InvalidPowerShellDataFile,
                          psDataFilePath);
            }

            #endregion "LoadAndEvaluatePowerShellDataFile"

            return(retResult);
        }