教程:了解如何使用 Azure PowerShell 控制 Windows 虚拟机

将资源部署到 Azure 时,可以灵活选择想要部署的资源类型、资源的位置以及对它们的设置方式。 但是,除了你想要在组织中允许的选项,这种灵活性可能还会开放更多其他选项。 在考虑将资源部署到 Azure 时,你可能想知道以下问题:

  • 如何满足特定国家/地区针对数据所有权制定的法规要求?
  • 如何控制成本?
  • 如何确保用户不会无意中更改关键系统?
  • 如何跟踪资源成本并准确地进行计费?

本文会为你解答这些问题。 具体而言,你需要:

  • 将用户分配到角色并分配角色对应的作用域,这样用户就能具备执行预期操作所需的权限,同时并不会涉及其他操作。
  • 应用策略来对订阅中的资源进行约定。
  • 锁定系统中的关键资源。
  • 标记资源,以便按它们对组织的价值进行跟踪。

本文重点介绍实现管理需要完成的任务。

本文中的示例需要版本 6.0 或更高版本的 Azure PowerShell。 如果在本地运行 PowerShell,并且未使用 6.0 或更高版本,请更新版本。 此外,还需要运行 Connect-AzureRmAccount -Environment AzureChinaCloud 以创建与 Azure 的连接。 对于本地安装,还必须下载 Azure AD PowerShell 模块来创建新的 Azure Active Directory 组。

了解范围

在创建任何项之前,让我们复习一下作用域的概念。 Azure 提供四个级别的管理:管理组、订阅、资源组和资源。 下图显示了一个这些层的示例。

作用域

将在上述任何级别的作用域中应用管理设置。 所选的级别确定应用设置的广泛程度。 较低级别继承较高级别的设置。 将设置应用到订阅时,该设置将应用于订阅中的所有资源组和资源。 将设置应用到资源组时,该设置将应用到资源组及其所有资源。 但是,其他资源组不具有该设置。

通常情况下,最好在较高级别应用关键设置,在较低级别应用特定于项目的要求。 例如,可能想要确保组织的所有资源均已部署到特定区域。 若要完成此要求,请将策略应用到指定允许位置的订阅。 当组织中的其他用户添加新资源组和资源时,会自动强制实施允许的位置。

在本教程中,你将所有管理设置应用于一个资源组,以便在完成后可以轻松地删除这些设置。

让我们创建该资源组。

New-AzureRmResourceGroup -Name myResourceGroup -Location ChinaEast

目前,资源组为空。

基于角色的访问控制

你希望确保你的组织中的用户对这些资源具有合适级别的访问权限。 你不希望向用户授予不受限的访问权限,但还需要确保他们可以执行其工作。 使用基于角色的访问控制,你可以管理哪些用户有权在某个范围内完成特定操作。

若要创建和删除角色分配,用户必须具有 Microsoft.Authorization/roleAssignments/* 访问权限。 此访问权限是通过“所有者”或“用户访问”管理员角色授权的。

若要管理虚拟机解决方案,可以使用三种特定于资源的角色来进行通常所需的访问:

通常情况下,与其向单个用户分配角色,不如使用其用户需要执行类似操作的 Azure Active Directory 组, 然后向该组分配相应的角色。 就本文来说,请使用现有的组来管理虚拟机,或者使用门户来创建 Azure Active Directory 组

创建新组或找到现有组以后,请使用 New-AzureRmRoleAssignment 命令将 Azure Active Directory 组分配到资源组的“虚拟机参与者”角色。

$adgroup = Get-AzureRmADGroup -DisplayName <your-group-name>

New-AzureRmRoleAssignment -ObjectId $adgroup.id `
  -ResourceGroupName myResourceGroup `
  -RoleDefinitionName "Virtual Machine Contributor"

如果收到一条错误,指出主体 不存在于目录中,则表明新组未在 Azure Active Directory 中完成传播。 请尝试再次运行命令。

通常情况下,请对网络参与者存储帐户参与者重复执行此过程,确保分配用户来管理已部署的资源。 在本文中,可以跳过这些步骤。

Azure Policy

Azure Policy 可帮助确保订阅中的所有资源符合企业标准。 订阅已经有多个策略定义。 若要查看可用的策略定义,请使用 Get-AzureRmPolicyDefinition 命令:

(Get-AzureRmPolicyDefinition).Properties | Format-Table displayName, policyType

可以看到现有的策略定义。 策略类型为“内置”或“自定义”。 在这些定义中查找所述条件正是你要分配的条件的定义。 在本文中,分配的策略要符合以下条件:

  • 限制所有资源的位置。
  • 限制虚拟机的 SKU。
  • 审核不使用托管磁盘的虚拟机。

在下面的示例中,你将基于显示名称检索三个策略定义。 并且使用 New-AzureRMPolicyAssignment 命令将这些定义分配到资源组。 对于某些策略,你将提供参数值来指定允许的值。

# Values to use for parameters
$locations ="chinaeast", "chinaeast2"
$skus = "Standard_DS1_v2", "Standard_E2s_v2"

# Get the resource group
$rg = Get-AzureRmResourceGroup -Name myResourceGroup

# Get policy definitions for allowed locations, allowed SKUs, and auditing VMs that don't use managed disks
$locationDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Allowed locations"}
$skuDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Allowed virtual machine SKUs"}
$auditDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Audit VMs that do not use managed disks"}

# Assign policy for allowed locations
New-AzureRMPolicyAssignment -Name "Set permitted locations" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $locationDefinition `
  -listOfAllowedLocations $locations

# Assign policy for allowed SKUs
New-AzureRMPolicyAssignment -Name "Set permitted VM SKUs" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $skuDefinition `
  -listOfAllowedSKUs $skus

# Assign policy for auditing unmanaged disks
New-AzureRMPolicyAssignment -Name "Audit unmanaged disks" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $auditDefinition

部署虚拟机

分配角色和策略以后,即可部署解决方案。 默认大小为 Standard_DS1_v2,这是允许的 SKU 之一。 运行此步骤时,会提示输入凭据。 你输入的值将配置为用于虚拟机的用户名和密码。

New-AzureRmVm -ResourceGroupName "myResourceGroup" `
     -Name "myVM" `
     -Location "China East" `
     -VirtualNetworkName "myVnet" `
     -SubnetName "mySubnet" `
     -SecurityGroupName "myNetworkSecurityGroup" `
     -PublicIpAddressName "myPublicIpAddress" `
     -OpenPorts 80,3389

部署完成后,可以对解决方案应用更多的管理设置。

锁定资源

资源锁可以防止组织中的用户意外删除或修改重要资源。 与基于角色的访问控制不同,资源锁对所有用户和角色应用限制。 可以将锁定级别设置为 CanNotDeleteReadOnly

若要锁定虚拟机和网络安全组,请使用 New-AzureRmResourceLock 命令:

# Add CanNotDelete lock to the VM
New-AzureRmResourceLock -LockLevel CanNotDelete `
  -LockName LockVM `
  -ResourceName myVM `
  -ResourceType Microsoft.Compute/virtualMachines `
  -ResourceGroupName myResourceGroup

# Add CanNotDelete lock to the network security group
New-AzureRmResourceLock -LockLevel CanNotDelete `
  -LockName LockNSG `
  -ResourceName myNetworkSecurityGroup `
  -ResourceType Microsoft.Network/networkSecurityGroups `
  -ResourceGroupName myResourceGroup

若要测试锁,请尝试运行以下命令:

Remove-AzureRmResourceGroup -Name myResourceGroup

将会显示一个错误,指出删除操作由于某个锁而无法完成。 只有在明确删除锁以后,才能删除资源组。 该步骤显示在清理资源中。

标记资源

可以将标记应用于 Azure 资源,以逻辑方式按类别对其进行组织。 每个标记包含一个名称和一个值。 例如,可以对生产中的所有资源应用名称“Environment”和值“Production”。

若要为资源组添加两个标记,请使用 Set-AzureRmResourceGroup 命令:

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ Dept="IT"; Environment="Test" }

让我们假设要添加第三个标记。 每次将标记应用到某个资源或资源组时,都会覆盖该资源或资源组中的现有标记。 若要添加新标记而不会丢失现有标记,必须检索现有标记、添加新标记,并重新应用标记集合:

# Get existing tags and add a new tag
$tags = (Get-AzureRmResourceGroup -Name myResourceGroup).Tags
$tags.Add("Project", "Documentation")

# Reapply the updated set of tags 
Set-AzureRmResourceGroup -Tag $tags -Name myResourceGroup

资源不从资源组继承标记。 目前,资源组有三个标记,但资源没有任何标记。 要将资源组中的所有标记应用于其资源,并且保留资源上不重复的现有标记,请使用以下脚本:

# Get the resource group
$group = Get-AzureRmResourceGroup myResourceGroup

if ($group.Tags -ne $null) {
    # Get the resources in the resource group
    $resources = Get-AzureRmResource -ResourceGroupName $group.ResourceGroupName

    # Loop through each resource
    foreach ($r in $resources)
    {
        # Get the tags for this resource
        $resourcetags = (Get-AzureRmResource -ResourceId $r.ResourceId).Tags

        # If the resource has existing tags, add new ones
        if ($resourcetags)
        {
            foreach ($key in $group.Tags.Keys)
            {
                if (-not($resourcetags.ContainsKey($key)))
                {
                    $resourcetags.Add($key, $group.Tags[$key])
                }
            }

            # Reapply the updated tags to the resource 
            Set-AzureRmResource -Tag $resourcetags -ResourceId $r.ResourceId -Force
        }
        else
        {
            Set-AzureRmResource -Tag $group.Tags -ResourceId $r.ResourceId -Force
        }
    }
}

或者,可以将资源组中的标记应用于资源而不保留现有标记:

# Get the resource group
$g = Get-AzureRmResourceGroup -Name myResourceGroup

# Find all the resources in the resource group, and for each resource apply the tags from the resource group
Get-AzureRmResource -ResourceGroupName $g.ResourceGroupName | ForEach-Object {Set-AzureRmResource -ResourceId $_.ResourceId -Tag $g.Tags -Force }

若要将几个值组合到单个标记中,请使用 JSON 字符串。

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ CostCenter="{`"Dept`":`"IT`",`"Environment`":`"Test`"}" }

若要删除所有标记,请传递一个空哈希表。

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ }

若要将标记应用于虚拟机,请使用 Set-AzureRmResource 命令:

# Get the virtual machine
$r = Get-AzureRmResource -ResourceName myVM `
  -ResourceGroupName myResourceGroup `
  -ResourceType Microsoft.Compute/virtualMachines

# Apply tags to the virtual machine
Set-AzureRmResource -Tag @{ Dept="IT"; Environment="Test"; Project="Documentation" } -ResourceId $r.ResourceId -Force

按标记查找资源

若要通过标记名称和值查找资源,请使用 Get-AzureRmResource 命令:

(Get-AzureRmResource -Tag @{ Environment="Test"}).Name

可以将返回的值用于管理任务,例如停止带有某个标记值的所有虚拟机。

Get-AzureRmResource -Tag @{ Environment="Test"} | Where-Object {$_.ResourceType -eq "Microsoft.Compute/virtualMachines"} | Stop-AzureRmVM

清理资源

在解除锁定之前,不能删除锁定的网络安全组。 若要删除锁,请使用 Remove-AzureRmResourceLock 命令:

Remove-AzureRmResourceLock -LockName LockVM `
  -ResourceName myVM `
  -ResourceType Microsoft.Compute/virtualMachines `
  -ResourceGroupName myResourceGroup
Remove-AzureRmResourceLock -LockName LockNSG `
  -ResourceName myNetworkSecurityGroup `
  -ResourceType Microsoft.Network/networkSecurityGroups `
  -ResourceGroupName myResourceGroup

如果不再需要资源组、VM 和所有相关的资源,可以使用 Remove-AzureRmResourceGroup 命令将其删除。

Remove-AzureRmResourceGroup -Name myResourceGroup

后续步骤

在本教程中,你已创建了一个自定义 VM 映像。 你已了解如何:

  • 为用户分配角色
  • 应用强制实施标准的策略
  • 使用锁保护重要资源
  • 标记用于计费和管理的资源

请转到下一教程,了解如何创建高度可用的虚拟机。