使用 PowerShell 管理 Azure Data Lake Storage 中的 ACL
本文介绍如何使用 PowerShell 来获取、设置和更新目录和文件的访问控制列表。
ACL 继承已可用于在父目录下创建的新子项。 但是你也可以为父目录的现有子项以递归方式添加、更新和删除 ACL,而不必为每个子项单独进行这些更改。
先决条件
Azure 订阅。 有关详细信息,请参阅获取 Azure 试用版。
已启用分层命名空间 (HNS) 的存储帐户。 按这些说明创建一个。
Azure CLI 版本
2.6.0
或更高版本。以下安全权限之一:
一个预配的 Microsoft Entra ID 安全主体,它已分配有存储 Blob 数据所有者角色,并且范围限定为目标容器、存储帐户、父资源组或订阅。
计划将 ACL 设置应用到的目标容器或目录的拥有用户。 为了以递归方式设置 ACL,这包括目标容器或目录中的所有子项。
安装 PowerShell 模块
使用以下命令验证安装的 PowerShell 版本是否为
5.1
或以上。echo $PSVersionTable.PSVersion.ToString()
若要升级 PowerShell 版本,请参阅升级现有的 Windows PowerShell
安装 Az.Storage 模块。
Install-Module Az.Storage -Repository PSGallery -Force
有关如何安装 PowerShell 模块的详细信息,请参阅安装 Azure PowerShell 模块
连接到帐户
打开 Windows PowerShell 命令窗口,使用 Connect-AzAccount 命令登录到 Azure 订阅,然后按照屏幕上的指示进行操作。
Connect-AzAccount -Environment AzureChinaCloud
如果你的标识已关联到多个订阅,且系统未提示你选择订阅,请将活动订阅设置为要对器进行操作的存储帐户的订阅。 在此示例中,请将
<subscription-id>
占位符值替换为你的订阅 ID。Select-AzSubscription -SubscriptionId <subscription-id>
获取存储帐户上下文。
$ctx = New-AzStorageContext -StorageAccountName '<storage-account-name>' -UseConnectedAccount
获取 ACL
使用 Get-AzDataLakeGen2Item cmdlet 获取目录或文件的 ACL。
此示例获取某个容器根目录的 ACL,然后将该 ACL 输出到控制台。
$filesystemName = "my-file-system"
$filesystem = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName
$filesystem.ACL
此示例获取某个目录的 ACL,然后将 ACL 输出到控制台。
$filesystemName = "my-file-system"
$dirname = "my-directory/"
$dir = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname
$dir.ACL
此示例获取某个文件的 ACL,然后将 ACL 输出到控制台。
$filePath = "my-directory/upload.txt"
$file = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $filePath
$file.ACL
下图显示了获取目录 ACL 后的输出。
在本示例中,负责人用户具有读取、写入和执行权限。 负责人组仅具有读取和执行权限。 有关访问控制列表的详细信息,请参阅 Azure Data Lake Storage 中的访问控制。
设置 ACL
设置 ACL 时,你将替换整个 ACL,包括其所有条目。 如果要更改安全主体的权限级别,或将新的安全主体添加到 ACL 而不影响其他现有项,则应改为更新 ACL。 若要更新 ACL 而不是替换它,请参阅本文的更新 ACL 部分。
如果选择设置 ACL,则必须为责任用户添加一个条目,为责任组添加一个条目,为所有其他用户添加一个条目。 若要详细了解责任用户、责任组和所有其他用户,请参阅用户和标识。
本节介绍如何完成下列操作:
- 设置 ACL
- 以递归方式设置 ACL
设置 ACL
使用 Set-AzDataLakeGen2ItemAclObject cmdlet 为所有者用户、所有者组或其他用户创建 ACL。 然后,使用 Update-AzDataLakeGen2Item cmdlet 提交 ACL。
此示例针对所有者用户、所有者组或其他用户的容器根目录设置 ACL,然后将 ACL 输出到控制台。
$filesystemName = "my-file-system"
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rw-
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission -wx -InputObject $acl
Update-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Acl $acl
$filesystem = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName
$filesystem.ACL
此示例针对所有者用户、所有者组或其他用户的目录设置 ACL,然后将 ACL 输出到控制台。
$filesystemName = "my-file-system"
$dirname = "my-directory/"
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rw-
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission -wx -InputObject $acl
Update-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl
$dir = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname
$dir.ACL
注意
如果要设置默认 ACL 条目,请在运行 Set-AzDataLakeGen2ItemAclObject 命令时使用 -DefaultScope 参数。 例如:$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rwx -DefaultScope
。
此示例针对所有者用户、所有者组或其他用户的文件设置 ACL,然后将 ACL 输出到控制台。
$filesystemName = "my-file-system"
$filePath = "my-directory/upload.txt"
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rw-
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "-wx" -InputObject $acl
Update-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $filePath -Acl $acl
$file = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $filePath
$file.ACL
注意
要设置特定组或用户、服务主体或托管标识的 ACL,请使用它们各自的对象 ID。 例如,若要设置组的 ACL,请使用 group:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
。 若要设置用户的 ACL,请使用 user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
。
下图显示了设置文件 ACL 后的输出。
在本示例中,负责人用户和负责人组只有读取和写入权限。 所有其他用户都具有写入和执行权限。 有关访问控制列表的详细信息,请参阅 Azure Data Lake Storage 中的访问控制。
以递归方式设置 ACL
使用 Set-AzDataLakeGen2AclRecursive cmdlet 以递归方式设置 ACL。
此示例设置名为 my-parent-directory
的目录的 ACL。 这些条目为所有者用户提供读取、写入和执行权限,仅为负责人组授予读取和执行权限,不为所有其他用户提供任何访问权限。 此示例中的最后一个 ACL 条目为对象 ID 为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”的特定用户提供读取和执行权限。
$filesystemName = "my-container"
$dirname = "my-parent-directory/"
$userID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rwx
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission r-x -InputObject $acl
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "---" -InputObject $acl
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $userID -Permission r-x -InputObject $acl
Set-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl
注意
如果要设置默认 ACL 条目,请在运行 Set-AzDataLakeGen2ItemAclObject 命令时使用 -DefaultScope 参数。 例如:$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rwx -DefaultScope
。
若要查看通过指定批大小以递归方式成批设置 ACL 的示例,请查看 Set-AzDataLakeGen2AclRecursive 参考文章。
更新 ACL
更新 ACL 时,你将修改 ACL 而非替换 ACL。 例如,你可以将一个新的安全主体添加到 ACL,而不影响 ACL 中列出的其他安全主体。 若要替换 ACL 而不是更新它,请参阅本文的 设置 ACL 部分。
本节介绍如何完成下列操作:
- 更新 ACL
- 以递归方式更新 ACL
更新 ACL
首先,获取 ACL。 然后,使用 Set-AzDataLakeGen2ItemAclObject cmdlet 添加或更新 ACL 条目。 使用 Update-AzDataLakeGen2Item cmdlet 提交 ACL。
此示例创建或更新用户目录的 ACL。
$filesystemName = "my-file-system"
$dirname = "my-directory/"
$acl = (Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname).ACL
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityID aaaaaaaa-bbbb-cccc-1111-222222222222 -Permission r-x -InputObject $acl
Update-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl
注意
如果要更新默认 ACL 条目,请在运行 Set-AzDataLakeGen2ItemAclObject 命令时使用 -DefaultScope 参数。 例如:$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityID aaaaaaaa-bbbb-cccc-1111-222222222222 -Permission r-x -DefaultScope
。
以递归方式更新 ACL
使用 Update-AzDataLakeGen2AclRecursive cmdlet 以递归方式更新 ACL。
此示例以写入权限更新某个 ACL 条目。
$filesystemName = "my-container"
$dirname = "my-parent-directory/"
$userID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $userID -Permission rwx
Update-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl
注意
要设置特定组或用户、服务主体或托管标识的 ACL,请使用它们各自的对象 ID。 例如,若要设置组的 ACL,请使用 group:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
。 若要设置用户的 ACL,请使用 user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
。
若要查看通过指定批大小以递归方式成批更新 ACL 的示例,请查看 Update-AzDataLakeGen2AclRecursive 参考文章。
删除 ACL 条目
本节介绍如何完成下列操作:
- 删除 ACL 条目
- 以递归方式删除 ACL 条目
删除 ACL 条目
此示例从现有 ACL 中删除条目。
$id = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Create the new ACL object.
[Collections.Generic.List[System.Object]]$aclnew =$acl
foreach ($a in $aclnew)
{
if ($a.AccessControlType -eq "User" -and $a.DefaultScope -eq $false -and $a.EntityId -eq $id)
{
$aclnew.Remove($a);
break;
}
}
Update-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $aclnew
以递归方式删除 ACL 条目
你可以采用递归方式删除一个或多个 ACL 条目。 若要删除 ACL 条目,请为要删除的 ACL 条目创建一个新的 ACL 对象,然后在“删除 ACL”操作中使用该对象。 不要获取现有 ACL,只需要提供要删除的 ACL 条目。
使用 Remove-AzDataLakeGen2AclRecursive cmdlet 删除 ACL 条目。
此示例从容器的根目录中删除 ACL 条目。
$filesystemName = "my-container"
$userID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $userID -Permission "---"
Remove-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Acl $acl
注意
如果要删除默认 ACL 条目,请在运行 Set-AzDataLakeGen2ItemAclObject 命令时使用 -DefaultScope 参数。 例如:$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $userID -Permission "---" -DefaultScope
。
若要查看通过指定批大小以递归方式成批删除 ACL 的示例,请查看 Remove-AzDataLakeGen2AclRecursive 参考文章。
从故障中恢复
以递归方式修改 ACL 时,可能会遇到运行时或权限错误。
对于运行时错误,请从头开始重启此过程。 如果安全主体没有足够的权限修改要修改的目录层次结构中的目录或文件的 ACL,则会出现权限错误。 请解决权限问题,然后选择通过使用继续标记从故障点继续执行此过程,或者从头重启此过程。 如果希望从头开始重启,则无需使用继续标记。 你可以重新应用 ACL 条目,而不会产生任何负面影响。
此示例将结果返回到变量,然后将失败的条目通过管道传递给已设置格式的表。
$result = Set-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl
$result
$result.FailedEntries | ft
根据表的输出,你可以修复所有权限错误,然后使用继续标记继续执行。
$result = Set-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl -ContinuationToken $result.ContinuationToken
$result
若要查看通过指定批大小以递归方式成批设置 ACL 的示例,请查看 Set-AzDataLakeGen2AclRecursive 参考文章。
如果你希望过程继续完成而不被权限错误中断,则可以指定它。
此示例使用 ContinueOnFailure
参数,这样,即使操作遇到权限错误也会继续执行。
$result = Set-AzDataLakeGen2AclRecursive -Context $ctx -FileSystem $filesystemName -Path $dirname -Acl $acl -ContinueOnFailure
echo "[Result Summary]"
echo "TotalDirectoriesSuccessfulCount: `t$($result.TotalFilesSuccessfulCount)"
echo "TotalFilesSuccessfulCount: `t`t`t$($result.TotalDirectoriesSuccessfulCount)"
echo "TotalFailureCount: `t`t`t`t`t$($result.TotalFailureCount)"
echo "FailedEntries:"$($result.FailedEntries | ft)
若要查看通过指定批大小以递归方式成批设置 ACL 的示例,请查看 Set-AzDataLakeGen2AclRecursive 参考文章。
最佳实践
本部分提供了有关以递归方式设置 ACL 的一些最佳做法指南。
处理运行时错误
发生运行时错误可能有许多原因(例如:中断或客户端连接问题)。 如果遇到运行时错误,请重启递归 ACL 过程。 可以将 ACL 重新应用于项,而不会造成负面影响。
处理权限错误 (403)
如果在运行递归 ACL 过程时遇到访问控制异常,则表明 AD 安全主体可能没有足够的权限将 ACL 应用于目录层次结构中的一个或多个子项。 发生权限错误时,此过程会停止,系统会提供一个继续标记。 请修复权限问题,然后使用继续标记来处理剩余的数据集。 已成功处理的目录和文件不需要再次处理。 你还可以选择重启递归 ACL 过程。 可以将 ACL 重新应用于项,而不会造成负面影响。
凭据
建议你预配一个在目标存储帐户或容器范围中分配有存储 Blob 数据所有者角色的 Microsoft Entra 安全主体。
性能
为了减少延迟,建议你在与存储帐户位于同一区域中的 Azure 虚拟机 (VM) 中运行递归 ACL 过程。
ACL 限制
可应用于目录或文件的 ACL 的最大数目为 32 个访问 ACL 和 32 个默认 ACL。 有关详细信息,请参阅 Azure Data Lake Storage Gen2 中的访问控制。