使用 C# 创建和管理 Azure 中的 Windows VMCreate and manage Windows VMs in Azure using C#

Azure 虚拟机 (VM) 需要多个支持性 Azure 资源。An Azure Virtual Machine (VM) needs several supporting Azure resources. 本文介绍如何使用 C# 创建、管理和删除 VM 资源。This article covers creating, managing, and deleting VM resources using C#. 你将学习如何执行以下操作:You learn how to:

  • 创建 Visual Studio 项目Create a Visual Studio project
  • 安装包Install the package
  • 创建凭据Create credentials
  • 创建资源Create resources
  • 执行管理任务Perform management tasks
  • 删除资源Delete resources
  • 运行应用程序Run the application

完成这些步骤大约需要 20 分钟。It takes about 20 minutes to do these steps.

创建 Visual Studio 项目Create a Visual Studio project

  1. 如果尚未安装,请安装 Visual StudioIf you haven't already, install Visual Studio. 在“工作负荷”页上选择“.NET 桌面开发”,然后单击“安装”。 Select .NET desktop development on the Workloads page, and then click Install. 在摘要中,可以看到系统自动选择了“.NET Framework 4 - 4.6 开发工具”。 In the summary, you can see that .NET Framework 4 - 4.6 development tools is automatically selected for you. 如果已安装 Visual Studio,则可以使用 Visual Studio 启动器添加 .NET 工作负荷。If you have already installed Visual Studio, you can add the .NET workload using the Visual Studio Launcher.
  2. 在 Visual Studio 中,单击“文件” > “新建” > “项目” 。In Visual Studio, click File > New > Project.
  3. 在“模板” > “Visual C#”中,选择“控制台应用(.NET Framework)”,输入 myDotnetProject 作为项目名称,选择项目的位置,然后单击“确定”。 In Templates > Visual C#, select Console App (.NET Framework), enter myDotnetProject for the name of the project, select the location of the project, and then click OK.

安装包Install the package

使用 NuGet 包可以最轻松地安装完成这些步骤所需的库。NuGet packages are the easiest way to install the libraries that you need to finish these steps. 若要在 Visual Studio 中获取所需的库,请执行以下步骤:To get the libraries that you need in Visual Studio, do these steps:

  1. 单击“工具” > “Nuget 包管理器”,然后单击“包管理器控制台” 。Click Tools > Nuget Package Manager, and then click Package Manager Console.

  2. 在控制台中键入此命令:Type this command in the console:

    Install-Package Microsoft.Azure.Management.Fluent
    

创建凭据Create credentials

在开始此步骤之前,请确保能够访问 Active Directory 服务主体Before you start this step, make sure that you have access to an Active Directory service principal. 此外,应记下应用程序 ID、身份验证密钥和租户 ID,以便在后面的步骤中使用。You should also record the application ID, the authentication key, and the tenant ID that you need in a later step.

创建授权文件Create the authorization file

  1. 在解决方案资源管理器中,右键单击myDotnetProject > ,单击 > 添加新建项,然后在Visual C# 项中选择文本文件In Solution Explorer, right-click myDotnetProject > Add > New Item, and then select Text File in Visual C# Items. 将文件命名为 azureauth.properties,然后单击“添加” 。Name the file azureauth.properties, and then click Add.

  2. 添加这些授权属性:Add these authorization properties:

    subscription=<subscription-id>
    client=<application-id>
    key=<authentication-key>
    tenant=<tenant-id>
    managementURI=https://management.core.chinacloudapi.cn/
    baseURL=https://management.chinacloudapi.cn/
    authURL=https://login.chinacloudapi.cn/
    graphURL=https://graph.chinacloudapi.cn/
    

    将 <subscription-id> 替换为订阅标识符,将 <application-id> 替换为 Active Directory 应用程序标识符,将 <authentication-key> 替换为应用程序密钥,将 <tenant-id> 替换为租户标识符 。Replace <subscription-id> with your subscription identifier, <application-id> with the Active Directory application identifier, <authentication-key> with the application key, and <tenant-id> with the tenant identifier.

  3. 保存 azureauth.properties 文件。Save the azureauth.properties file.

  4. 在 Windows 中设置名为 AZURE_AUTH_LOCATION 的环境变量,其中包含创建的授权文件的完整路径。Set an environment variable in Windows named AZURE_AUTH_LOCATION with the full path to authorization file that you created. 例如,可以使用以下 PowerShell 命令:For example, the following PowerShell command can be used:

    [Environment]::SetEnvironmentVariable("AZURE_AUTH_LOCATION", "C:\Visual Studio 2019\Projects\myDotnetProject\myDotnetProject\azureauth.properties", "User")
    

创建管理客户端Create the management client

  1. 打开创建的项目的 Program.cs 文件。Open the Program.cs file for the project that you created. 然后,将以下 using 语句添加到文件顶部的现有语句中:Then, add these using statements to the existing statements at top of the file:

    using Microsoft.Azure.Management.Compute.Fluent;
    using Microsoft.Azure.Management.Compute.Fluent.Models;
    using Microsoft.Azure.Management.Fluent;
    using Microsoft.Azure.Management.ResourceManager.Fluent;
    using Microsoft.Azure.Management.ResourceManager.Fluent.Core;
    
  2. 若要创建管理客户端,请将以下代码添加到 Main 方法:To create the management client, add this code to the Main method:

    var credentials = SdkContext.AzureCredentialsFactory
        .FromFile(Environment.GetEnvironmentVariable("AZURE_AUTH_LOCATION"));
    
    var azure = Azure
        .Configure()
        .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
        .Authenticate(credentials)
        .WithDefaultSubscription();
    

创建资源Create resources

创建资源组Create the resource group

必须在资源组中包含所有资源。All resources must be contained in a Resource group.

若要指定应用程序的值并创建资源组,请将以下代码添加到 Main 方法:To specify values for the application and create the resource group, add this code to the Main method:

var groupName = "myResourceGroup";
var vmName = "myVM";
var location = Region.ChinaNorth;

Console.WriteLine("Creating resource group...");
var resourceGroup = azure.ResourceGroups.Define(groupName)
    .WithRegion(location)
    .Create();

创建可用性集Create the availability set

使用可用性集可以更方便地维护应用程序所用的虚拟机。Availability sets make it easier for you to maintain the virtual machines used by your application.

若要创建可用性集,请将以下代码添加到 Main 方法:To create the availability set, add this code to the Main method:

Console.WriteLine("Creating availability set...");
var availabilitySet = azure.AvailabilitySets.Define("myAVSet")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithSku(AvailabilitySetSkuTypes.Managed)
    .Create();

创建公共 IP 地址Create the public IP address

与虚拟机通信需要公共 IP 地址A Public IP address is needed to communicate with the virtual machine.

若要创建虚拟机的公共 IP 地址,请将以下代码添加到 Main 方法:To create the public IP address for the virtual machine, add this code to the Main method:

Console.WriteLine("Creating public IP address...");
var publicIPAddress = azure.PublicIPAddresses.Define("myPublicIP")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithDynamicIP()
    .Create();

创建虚拟网络Create the virtual network

虚拟机必须在虚拟网络的子网中。A virtual machine must be in a subnet of a Virtual network.

若要创建子网和虚拟网络,请将以下代码添加到 Main 方法:To create a subnet and a virtual network, add this code to the Main method:

Console.WriteLine("Creating virtual network...");
var network = azure.Networks.Define("myVNet")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithAddressSpace("10.0.0.0/16")
    .WithSubnet("mySubnet", "10.0.0.0/24")
    .Create();

创建网络接口Create the network interface

虚拟机需要使用网络接口在虚拟网络上通信。A virtual machine needs a network interface to communicate on the virtual network.

若要创建网络接口,请将以下代码添加到 Main 方法:To create a network interface, add this code to the Main method:

Console.WriteLine("Creating network interface...");
var networkInterface = azure.NetworkInterfaces.Define("myNIC")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithExistingPrimaryNetwork(network)
    .WithSubnet("mySubnet")
    .WithPrimaryPrivateIPAddressDynamic()
    .WithExistingPrimaryPublicIPAddress(publicIPAddress)
    .Create();

创建虚拟机Create the virtual machine

创建所有支持资源后,即可创建虚拟机。Now that you created all the supporting resources, you can create a virtual machine.

若要创建虚拟机,请将以下代码添加到 Main 方法:To create the virtual machine, add this code to the Main method:

Console.WriteLine("Creating virtual machine...");
azure.VirtualMachines.Define(vmName)
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithExistingPrimaryNetworkInterface(networkInterface)
    .WithLatestWindowsImage("MicrosoftWindowsServer", "WindowsServer", "2012-R2-Datacenter")
    .WithAdminUsername("azureuser")
    .WithAdminPassword("Azure12345678")
    .WithComputerName(vmName)
    .WithExistingAvailabilitySet(availabilitySet)
    .WithSize(VirtualMachineSizeTypes.StandardDS1)
    .Create();

Note

本教程创建运行 Windows Server 操作系统版本的虚拟机。This tutorial creates a virtual machine running a version of the Windows Server operating system. 若要详细了解如何选择其他映像,请参阅使用 Windows PowerShell 和 Azure CLI 来导航和选择 Azure 虚拟机映像To learn more about selecting other images, see Navigate and select Azure virtual machine images with Windows PowerShell and the Azure CLI.

如果要使用现有磁盘而不是市场映像,请使用以下代码:If you want to use an existing disk instead of a marketplace image, use this code:

var managedDisk = azure.Disks.Define("myosdisk")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithWindowsFromVhd("https://mystorage.blob.core.chinacloudapi.cn/vhds/myosdisk.vhd")
    .WithSizeInGB(128)
    .WithSku(DiskSkuTypes.PremiumLRS)
    .Create();

azure.VirtualMachines.Define("myVM")
    .WithRegion(location)
    .WithExistingResourceGroup(groupName)
    .WithExistingPrimaryNetworkInterface(networkInterface)
    .WithSpecializedOSDisk(managedDisk, OperatingSystemTypes.Windows)
    .WithExistingAvailabilitySet(availabilitySet)
    .WithSize(VirtualMachineSizeTypes.StandardDS1)
    .Create();

执行管理任务Perform management tasks

在虚拟机生命周期中,可能需要运行管理任务,例如启动、停止或删除虚拟机。During the lifecycle of a virtual machine, you may want to run management tasks such as starting, stopping, or deleting a virtual machine. 此外,建议创建代码来自动执行重复或复杂的任务。Additionally, you may want to create code to automate repetitive or complex tasks.

如需对 VM 执行任何操作,需获取其实例:When you need to do anything with the VM, you need to get an instance of it:

var vm = azure.VirtualMachines.GetByResourceGroup(groupName, vmName);

获取有关 VM 的信息Get information about the VM

若要获取有关虚拟机的信息,请将以下代码添加到 Main 方法:To get information about the virtual machine, add this code to the Main method:

Console.WriteLine("Getting information about the virtual machine...");
Console.WriteLine("hardwareProfile");
Console.WriteLine("   vmSize: " + vm.Size);
Console.WriteLine("storageProfile");
Console.WriteLine("  imageReference");
Console.WriteLine("    publisher: " + vm.StorageProfile.ImageReference.Publisher);
Console.WriteLine("    offer: " + vm.StorageProfile.ImageReference.Offer);
Console.WriteLine("    sku: " + vm.StorageProfile.ImageReference.Sku);
Console.WriteLine("    version: " + vm.StorageProfile.ImageReference.Version);
Console.WriteLine("  osDisk");
Console.WriteLine("    osType: " + vm.StorageProfile.OsDisk.OsType);
Console.WriteLine("    name: " + vm.StorageProfile.OsDisk.Name);
Console.WriteLine("    createOption: " + vm.StorageProfile.OsDisk.CreateOption);
Console.WriteLine("    caching: " + vm.StorageProfile.OsDisk.Caching);
Console.WriteLine("osProfile");
Console.WriteLine("  computerName: " + vm.OSProfile.ComputerName);
Console.WriteLine("  adminUsername: " + vm.OSProfile.AdminUsername);
Console.WriteLine("  provisionVMAgent: " + vm.OSProfile.WindowsConfiguration.ProvisionVMAgent.Value);
Console.WriteLine("  enableAutomaticUpdates: " + vm.OSProfile.WindowsConfiguration.EnableAutomaticUpdates.Value);
Console.WriteLine("networkProfile");
foreach (string nicId in vm.NetworkInterfaceIds)
{
    Console.WriteLine("  networkInterface id: " + nicId);
}
Console.WriteLine("vmAgent");
Console.WriteLine("  vmAgentVersion" + vm.InstanceView.VmAgent.VmAgentVersion);
Console.WriteLine("    statuses");
foreach (InstanceViewStatus stat in vm.InstanceView.VmAgent.Statuses)
{
    Console.WriteLine("    code: " + stat.Code);
    Console.WriteLine("    level: " + stat.Level);
    Console.WriteLine("    displayStatus: " + stat.DisplayStatus);
    Console.WriteLine("    message: " + stat.Message);
    Console.WriteLine("    time: " + stat.Time);
}
Console.WriteLine("disks");
foreach (DiskInstanceView disk in vm.InstanceView.Disks)
{
    Console.WriteLine("  name: " + disk.Name);
    Console.WriteLine("  statuses");
    foreach (InstanceViewStatus stat in disk.Statuses)
    {
        Console.WriteLine("    code: " + stat.Code);
        Console.WriteLine("    level: " + stat.Level);
        Console.WriteLine("    displayStatus: " + stat.DisplayStatus);
        Console.WriteLine("    time: " + stat.Time);
    }
}
Console.WriteLine("VM general status");
Console.WriteLine("  provisioningStatus: " + vm.ProvisioningState);
Console.WriteLine("  id: " + vm.Id);
Console.WriteLine("  name: " + vm.Name);
Console.WriteLine("  type: " + vm.Type);
Console.WriteLine("  location: " + vm.Region);
Console.WriteLine("VM instance status");
foreach (InstanceViewStatus stat in vm.InstanceView.Statuses)
{
    Console.WriteLine("  code: " + stat.Code);
    Console.WriteLine("  level: " + stat.Level);
    Console.WriteLine("  displayStatus: " + stat.DisplayStatus);
}
Console.WriteLine("Press enter to continue...");
Console.ReadLine();

停止 VMStop the VM

可停止虚拟机并保留其所有设置,但需继续付费;还可停止虚拟机并解除分配。You can stop a virtual machine and keep all its settings, but continue to be charged for it, or you can stop a virtual machine and deallocate it. 解除分配虚拟机时,也会解除分配与其关联的所有资源并将停止计费。When a virtual machine is deallocated, all resources associated with it are also deallocated and billing ends for it.

若要停止虚拟机而不解除分配虚拟机,请将以下代码添加到 Main 方法:To stop the virtual machine without deallocating it, add this code to the Main method:

Console.WriteLine("Stopping vm...");
vm.PowerOff();
Console.WriteLine("Press enter to continue...");
Console.ReadLine();

要解除分配虚拟机,请将 PowerOff 调用更改为以下代码:If you want to deallocate the virtual machine, change the PowerOff call to this code:

vm.Deallocate();

启动 VMStart the VM

若要启动虚拟机,请将以下代码添加到 Main 方法:To start the virtual machine, add this code to the Main method:

Console.WriteLine("Starting vm...");
vm.Start();
Console.WriteLine("Press enter to continue...");
Console.ReadLine();

重设 VM 大小Resize the VM

决定虚拟机大小时应考虑部署的诸多方面。Many aspects of deployment should be considered when deciding on a size for your virtual machine. 有关详细信息,请参见 VM 大小For more information, see VM sizes.

若要更改虚拟机大小,请将以下代码添加到 Main 方法:To change size of the virtual machine, add this code to the Main method:

Console.WriteLine("Resizing vm...");
vm.Update()
    .WithSize(VirtualMachineSizeTypes.StandardDS2) 
    .Apply();
Console.WriteLine("Press enter to continue...");
Console.ReadLine();

将数据磁盘添加到 VMAdd a data disk to the VM

若要将数据磁盘添加到虚拟机,请将此代码添加到 Main 方法。To add a data disk to the virtual machine, add this code to the Main method. 此示例添加了一个大小为 2 GB、LUN 为 0、缓存类型为 ReadWrite 的数据磁盘:This example adds a data disk that is 2 GB in size, han a LUN of 0 and a caching type of ReadWrite:

Console.WriteLine("Adding data disk to vm...");
vm.Update()
    .WithNewDataDisk(2, 0, CachingTypes.ReadWrite) 
    .Apply();
Console.WriteLine("Press enter to delete resources...");
Console.ReadLine();

删除资源Delete resources

由于需要为 Azure 中使用的资源付费,因此,删除不再需要的资源总是一种良好的做法。Because you are charged for resources used in Azure, it is always good practice to delete resources that are no longer needed. 如果要删除虚拟机和所有支持资源,只需删除资源组。If you want to delete the virtual machines and all the supporting resources, all you have to do is delete the resource group.

若要删除资源组,请将以下代码添加到 Main 方法:To delete the resource group, add this code to the Main method:

azure.ResourceGroups.DeleteByName(groupName);

运行应用程序Run the application

控制台应用程序从头到尾完成运行大约需要五分钟时间。It should take about five minutes for this console application to run completely from start to finish.

  1. 若要运行控制台应用程序,请单击“启动” 。To run the console application, click Start.

  2. 在按 Enter 开始删除资源之前,可能需要在 Azure 门户中花几分钟时间来验证这些资源是否已创建。Before you press Enter to start deleting resources, you could take a few minutes to verify the creation of the resources in the Azure portal. 单击部署状态以查看有关部署的信息。Click the deployment status to see information about the deployment.

后续步骤Next steps