简体   繁体   English

使用powershell挂载Azure文件服务映射驱动器

[英]Mount Azure File Service mapped drive with powershell

I'm using Azure File Service to persist some files that a program, installed on a role instance, will access. 我正在使用Azure文件服务来保存安装在角色实例上的程序将访问的某些文件。

I have managed to map a drive, to the file service share, through remote desktop, using a PowerShell script. 我已设法使用PowerShell脚本通过远程桌面将驱动器映射到文件服务共享。 However, when I try to execute that same script, in the OnStart() of the worker role, it doesn't work. 但是,当我尝试执行相同的脚本时,在辅助角色的OnStart()中,它不起作用。 I can't figure out what's wrong. 我无法弄清楚出了什么问题。

So, this is what I do: 所以,这就是我做的:

public override bool OnStart()
{
    ServicePointManager.DefaultConnectionLimit = 12;

    _slsPath = RoleEnvironment.GetLocalResource("StartupLocalStorage").RootPath;

    var settingstring = CloudConfigurationManager.GetSetting("StorageConnectionString");
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(settingstring);

    var blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference("zipfiles");
    ICloudBlob blob = container.GetBlobReferenceFromServer("Program.zip");
     //copy blob from cloud to local gallery
     blob.DownloadToFile(_slsPath + "Program.zip", FileMode.Create);

    // get powershell script for mounting drive
     blob = container.GetBlobReferenceFromServer("mountdrive.ps1");
    blob.DownloadToFile(_slsPath + "mountdrive.ps1", FileMode.Create);

    // small exe for executing powershell script for mounting drive
    blob = container.GetBlobReferenceFromServer("Programinstaller.exe");
    blob.DownloadToFile(_slsPath + "Programinstaller.exe", FileMode.Create);

    ZipFile.ExtractToDirectory(_slsPath + @"\Program.zip", _slsPath);

    var share = storageAccount
    .CreateCloudFileClient()
    .GetShareReference("someshare");
    share.CreateIfNotExists();

    var filesPath = @"Z:\Folder";
    // Mounting drive
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardOutput = true;
    startInfo.FileName = _slsPath + @"Programinstaller.exe";
    startInfo.WindowStyle = ProcessWindowStyle.Normal;
    startInfo.Arguments = _slsPath + @"\ " + filesPath;

    // Start the process with the info we specified.
    // Call WaitForExit and then the using statement will close.
    using (Process exeProcess = Process.Start(startInfo))
    {
            int count = 0;
            var res = exeProcess.StandardOutput.ReadLine();
            System.IO.File.WriteAllText(_slsPath + @"ResultOfDriveMount.txt", res + Environment.NewLine);
            while (count < 30)
            {
                    Thread.Sleep(1000);
                    res = exeProcess.StandardOutput.ReadLine();
                    System.IO.File.AppendAllText(_slsPath + @"ResultOfDriveMount.txt", res + Environment.NewLine);
                    count++;
            }
    }
}

Allright, so, the Programinstaller.exe is just this: 好吧,所以,Programinstaller.exe就是这样的:

    static void Main(string[] args)
    {
        Console.WriteLine(args[0]);
        Thread t = new Thread(() =>
        {
            ExecutePowerShell(args[0] + "mountdrive.ps1", args[0]);
        });
        t.Start();
        Thread.Sleep(20000);
        InstallProgram(args[0], args[1]);
    }

    private static void ExecutePowerShell(string scriptfile, string SlsPath)
    {
        RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
        runspace.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);

        Pipeline pipeline = runspace.CreatePipeline();

        //Here's how you add a new script with arguments
        Command myCommand = new Command(scriptfile);
        //CommandParameter testParam = new CommandParameter("key", "value");
        //myCommand.Parameters.Add(testParam);

        pipeline.Commands.Add(myCommand);

        // Execute PowerShell script
        var results = pipeline.Invoke();
        foreach (var res in results)
            System.IO.File.WriteAllText(SlsPath + @"ResultOfPowerShell.txt", res.ToString());
    }

    /// <summary>
    /// Launch the legacy application with some options set.
    /// </summary>
    static void InstallProgram(string folderPath, string pathTwo)
    {
        // Use ProcessStartInfo class
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.CreateNoWindow = false;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.FileName = folderPath + @"ProgramAuthor.ProgramName.exe";
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        startInfo.Arguments = folderPath + [someargument] + pathTwo;

        try
        {
            // Start the process with the info we specified.
            // Read output lines, store to txt
            using (Process exeProcess = Process.Start(startInfo))
            {
                int count = 0;
                var result = exeProcess.StandardOutput.ReadLine(); 

                System.IO.File.WriteAllText(folderPath + @"ResultOfProgramInstall.txt", result + Environment.NewLine);
                while (count < 300)
                {
                    Thread.Sleep(1000);
                    result = exeProcess.StandardOutput.ReadLine();
                    System.IO.File.AppendAllText(folderPath + @"ResultOfProgramInstall.txt", result + Environment.NewLine);
                    count++;
                }
            }
        }
        catch (Exception ex)
        {
            System.IO.File.WriteAllText(folderPath + @"Error2.txt", ex.Message + " ... " + ex.StackTrace);
        }
    }

And the Ps1-file goes like this: 而Ps1文件是这样的:

Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted
cmdkey /add:[account].file.core.windows.net /user:[account] /pass:[key]
net use z: \\[account].file.core.windows.net\someshare

Strange thing is that running the Programinstaller.exe file, that was downloaded from the blob, from command prompt - with same parameters - in remote desktop in the worker role, will mount the mapped drive and install the program. 奇怪的是,运行Programinstaller.exe文件,从blob下载,从命令提示符 - 使用相同的参数 - 在worker角色的远程桌面中运行,将挂载映射的驱动器并安装程序。 But calling that same file from code after deploying (ie from OnStart()) doesn't mount the drive. 但是在部署之后从代码调用相同的文件(即从OnStart())不会挂载驱动器。 The ProgramAuthor.ProgramFile.exe is executed, and tries to install in the mapped drive, but it was never mapped so it fails. 执行ProgramAuthor.ProgramFile.exe,并尝试在映射的驱动器中安装,但它从未映射,因此失败。

What's up with this? 怎么了?

Ok, so I went down this way instead, as recommended in this answer . 好吧,所以我按照这个答案推荐的方式改变了 Only problem being that the drive doesn't show up in the file explorer when logged in to the VM. 唯一的问题是登录到VM时驱动器未显示在文件资源管理器中。 Not a big deal. 没有大碍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM