Giter Site home page Giter Site logo

aliceqin12 / cloud-services-dotnet-execute-powershell-file-in-storage-file-mounted-disk Goto Github PK

View Code? Open in Web Editor NEW

This project forked from azure-samples/cloud-services-dotnet-execute-powershell-file-in-storage-file-mounted-disk

0.0 1.0 0.0 91 KB

This sample demonstrates how to let cloud service worker role execute PowerShell script file in a mounted Azure File Storage disk

License: MIT License

C# 94.04% Batchfile 5.96%

cloud-services-dotnet-execute-powershell-file-in-storage-file-mounted-disk's Introduction

services platforms author
cloud-services
dotnet
msonecode

How to Execute PowerShell from Mounted Azure Storage File Disk in Azure Cloud Service Worker Role

Introduction

When we are using Azure Cloud Service and Azure Storage, we always keep some common files in Azure Storage and make Azure Cloud Service read those files directly from storage service.

In this example, you will learn how to mount an Azure Storage Shared File service as a remote to cloud service instance in a startup task.

You will also learn how to execute a PowerShell script in startup tasks and avoid the warning for PowerShell policy conflicts.

Prerequisites

1. Create Azure File storage

Please follow the below document to create an Azure File storage.

https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-files/

Instead of running all the steps in this document, you just need to create an Azure File folder in Azure portal.

Please record the storage account name and access key because they will be used in further steps.

2. Upload test to execute PowerShell script

After Azure File storage folder is ready, please use Azure portal to upload test PowerShell script file.

In this example, the script file name is “test.ps1”. Below is the content of this file.

Get-Date -Format "yyyy-MM-dd HH:mm:ss" | Out-File $env:TEMP\PSLog.txt

3. Create test cloud service

Please follow below document to create an Azure Cloud Service.

https://azure.microsoft.com/en-us/documentation/articles/cloud-services-how-to-create-deploy-portal/

Building the Sample

1. Create Solution in Visual Studio 2015

Now you can use Visual Studio 2015 to build a cloud service solution. This solution contains one cloud service project and a worker role project.

2. Configure Service Definition File

Open ServiceDefinition.csdef and change content as below.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureCloudService1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
  <WorkerRole name="WorkerRole1" vmsize="Small">
    <Runtime executionContext="elevated" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
    </ConfigurationSettings>
    <LocalResources>
    </LocalResources>
    <Imports>
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WorkerRole>
</ServiceDefinition>

This configuration

<Runtime executionContext="elevated" />

makes worker role service running under administrator mode, since we need to use the administrator authority to run mount disk commands.

3. Write Startup.cmd Content

Create a Startup.cmd file to Worker Role project root path.

Startup.cmd will set PowerShell global execution policy to prevent meeting policy-not-enough warning. It will also mount the storage file folder as remote disk.

Please refer to the codes in our example solution and replace the storage account and access key to yours.

4. Write Worker Role Code to execute cmd and PowerShell script

Please modify WorkerRole.RunAsync method as below codes.

These codes run under administrator role at first to execute startup.cmd to mount disk.

Then it will execute PowerShell test.ps1

        private async Task RunAsync(CancellationToken cancellationToken)
        {
            try
            {
                string appRoot = Environment.GetEnvironmentVariable("RoleRoot");
                string fullPath = Path.Combine(appRoot + @"\", @"AppRoot\startup.cmd");
                ProcessStartInfo startInfo = new ProcessStartInfo(fullPath)
                {
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    Verb = "runas"
                };

                Process p = System.Diagnostics.Process.Start(startInfo);
                using (StreamReader reader = p.StandardOutput)
                {
                    string processResult = reader.ReadToEnd();
                    File.AppendAllText(Path.Combine(Path.GetTempPath(), "startProcess.log"), processResult + "\r\n\r\n");
                }
                p.WaitForExit();
            }
            catch (Exception ex)
            {
                File.WriteAllText(Path.Combine(Path.GetTempPath(), "startProcess.log"),
                    ex.ToString() + "\r\n\r\n");
            }

            var hasRunPs = false;
            // TODO: Replace the following with your own logic.
            while (!cancellationToken.IsCancellationRequested)
            {
                Trace.TraceInformation("Working");
                if (!hasRunPs)
                {
                    try
                    {
                        File.AppendAllText(Path.Combine(Path.GetTempPath(), "PS.log"), "start PS\r\n\r\n");
                        ProcessStartInfo startInfo = new ProcessStartInfo("powershell.exe")
                        {
                            UseShellExecute = false,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            Verb = "runas"
                        };

                        startInfo.Arguments = @"P:\test.ps1";
                        Process p = System.Diagnostics.Process.Start(startInfo);

                        using (StreamReader reader = p.StandardOutput)
                        {
                            string result = reader.ReadToEnd();
                            File.AppendAllText(Path.Combine(Path.GetTempPath(), "PS.log"), result + "\r\n\r\n");
                        }

                        using (StreamReader reader = p.StandardError)
                        {
                            string result = reader.ReadToEnd();
                            File.AppendAllText(Path.Combine(Path.GetTempPath(), "PS.log"), result + "\r\n\r\n");
                        }
                    }
                    catch (Exception ex)
                    {
                        File.WriteAllText(Path.Combine(Path.GetTempPath(), "startProcess.log"),
                            ex.ToString() + "\r\n\r\n");
                    }
                    hasRunPs = true;
                }
                await Task.Delay(1000);
            }
        }

Running the Sample

Right click cloud service project and choose “Publish…” command.

1

Before we publish this cloud service, please enable RDP and set a RDP account. You can click "Enable Remote Desktop for all roles" under Cloud section.

2

You can use this RDP account to do below things.

• RDP to instance to troubleshoot if the startup task failed or FTP configuration failed.

• Use this account to login FTP

Using the Code

You can RDP to instance and check the following folder to verity that PowerShell script has been successfully executed.

C:\Resources\temp\[deployment_id].WebRole1\RoleTemp

There should be a “PSLog.txt” file under this folder. The file content should be a date time.

Here are some key points to understand.

Why can’t we run startup.cmd in startup task?

It is because cloud service startup task and the main logic of worker role is running under different system accounts.

Windows remote disk is protected by its security setting. Worker role account cannot access the remote disk which was mounted by startup task execution account.

Why can’t I see the remote disk P when I RDP to the instance?

The reason is the same as the above question.

It is the remote desktop account with which you logged into the instance, but not the account that mounted the disk.

cloud-services-dotnet-execute-powershell-file-in-storage-file-mounted-disk's People

Contributors

acomsmpbot avatar ericlgf819 avatar vaanpan avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.