private Dictionary <string, string> GetRequiredModules(String configurationPath) { ConfigurationParseResult parseResult = null; try { parseResult = ConfigurationParsingHelper.ParseConfiguration(configurationPath); } catch (GetDscResourceException e) { ThrowTerminatingError( new ErrorRecord(e, "CannotAccessDscResource", ErrorCategory.PermissionDenied, null)); } if (parseResult.Errors.Any()) { ThrowTerminatingError( new ErrorRecord( new ParseException( String.Format( CultureInfo.CurrentUICulture, Microsoft.Azure.Commands.Compute.Properties.Resources.PublishVMDscExtensionStorageParserErrors, configurationPath, String.Join("\n", parseResult.Errors.Select(error => error.ToString())))), "DscConfigurationParseError", ErrorCategory.ParserError, null)); } var requiredModules = parseResult.RequiredModules; //Since LCM always uses the latest module there is no need to copy PSDesiredStateConfiguration if (requiredModules.ContainsKey("PSDesiredStateConfiguration")) { requiredModules.Remove("PSDesiredStateConfiguration"); } WriteVerbose(String.Format( CultureInfo.CurrentUICulture, Microsoft.Azure.Commands.Compute.Properties.Resources.PublishVMDscExtensionRequiredModulesVerbose, String.Join(", ", requiredModules))); return(requiredModules); }
public string CreateConfigurationArchive( String configurationPath, String configurationArchivePath, Boolean force, String parameterSetName) { WriteVerbose(String.Format(CultureInfo.CurrentUICulture, Properties.Resources.AzureVMDscParsingConfiguration, configurationPath)); ConfigurationParseResult parseResult = null; try { parseResult = ConfigurationParsingHelper.ParseConfiguration(configurationPath); } catch (GetDscResourceException e) { ThrowTerminatingError(new ErrorRecord(e, "CannotAccessDscResource", ErrorCategory.PermissionDenied, null)); } if (parseResult.Errors.Any()) { ThrowTerminatingError( new ErrorRecord( new ParseException( String.Format( CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionStorageParserErrors, configurationPath, String.Join("\n", parseResult.Errors.Select(error => error.ToString())))), "DscConfigurationParseError", ErrorCategory.ParserError, null)); } var requiredModules = parseResult.RequiredModules; //Since LCM always uses the latest module there is no need to copy PSDesiredStateConfiguration if (requiredModules.ContainsKey("PSDesiredStateConfiguration")) { requiredModules.Remove("PSDesiredStateConfiguration"); } WriteVerbose(String.Format(CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionRequiredModulesVerbose, String.Join(", ", requiredModules))); // Create a temporary directory for uploaded zip file var tempZipFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); WriteVerbose(String.Format(CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionTempFolderVerbose, tempZipFolder)); Directory.CreateDirectory(tempZipFolder); _temporaryDirectoriesToDelete.Add(tempZipFolder); // CopyConfiguration var configurationName = Path.GetFileName(configurationPath); var configurationDestination = Path.Combine(tempZipFolder, configurationName); WriteVerbose(String.Format( CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionCopyFileVerbose, configurationPath, configurationDestination)); File.Copy(configurationPath, configurationDestination); // CopyRequiredModules foreach (var module in requiredModules) { using (System.Management.Automation.PowerShell powershell = System.Management.Automation.PowerShell.Create()) { // Wrapping script in a function to prevent script injection via $module variable. powershell.AddScript( @"function Copy-Module([string]$moduleName, [string]$moduleVersion, [string]$tempZipFolder) { if([String]::IsNullOrEmpty($moduleVersion)) { $module = Get-Module -List -Name $moduleName } else { $module = (Get-Module -List -Name $moduleName) | Where-Object{$_.Version -eq $moduleVersion} } $moduleFolder = Split-Path $module.Path Copy-Item -Recurse -Path $moduleFolder -Destination ""$tempZipFolder\$($module.Name)"" }" ); powershell.Invoke(); powershell.Commands.Clear(); powershell.AddCommand("Copy-Module") .AddParameter("moduleName", module.Key) .AddParameter("moduleVersion", module.Value) .AddParameter("tempZipFolder", tempZipFolder); WriteVerbose(String.Format( CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionCopyModuleVerbose, module, tempZipFolder)); powershell.Invoke(); } } // // Zip the directory // string archive; if (parameterSetName == CreateArchiveParameterSetName) { archive = configurationArchivePath; if (!force && File.Exists(archive)) { ThrowTerminatingError( new ErrorRecord( new UnauthorizedAccessException(string.Format(CultureInfo.CurrentUICulture, Properties.Resources.AzureVMDscArchiveAlreadyExists, archive)), "FileAlreadyExists", ErrorCategory.PermissionDenied, null)); } } else { string tempArchiveFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); WriteVerbose(String.Format(CultureInfo.CurrentUICulture, Properties.Resources.PublishVMDscExtensionTempFolderVerbose, tempArchiveFolder)); Directory.CreateDirectory(tempArchiveFolder); _temporaryDirectoriesToDelete.Add(tempArchiveFolder); archive = Path.Combine(tempArchiveFolder, configurationName + DscExtensionCmdletConstants.ZipFileExtension); _temporaryFilesToDelete.Add(archive); } if (File.Exists(archive)) { File.Delete(archive); } ZipFile.CreateFromDirectory(tempZipFolder, archive); return(archive); }