概述
我想有一种方法来查询 Azure AD,并返回分配给 Azure 中不同资源组的 Azure AD 组列表。
当前解决方案
目前,我有一个作为服务原则运行的 powershell 脚本,该脚本通过 Azure 进行身份验证,然后获取当前订阅。基于此搜索登录用户并返回用户分配到的所有安全组。然后根据 AD 组分配到的所有资源组进行检查,这会返回登录用户可以访问的资源组中的 VM 列表。
这确实有效,但是运行大约需要 10 分钟。我们每个订阅有 100 个资源组,而且速度很慢。
我粘贴了下面的代码,并删除了所有私人信息。
问题
我正在使用 Az Powershell 2.4.0 库来创建代码。
function userLogin($azureAplicationId, $azureAppPassword)
{
$azureTenantId= ""
$azurePassword = ConvertTo-SecureString $azureAppPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
}
function userRGAccessCheck($RG)
{
$resoruceGroupChoice = Read-Host -Prompt "Enter Resource Group Name "
}
function userRTAccessCheck($RName)
{
$resoruceNameChoice = Read-Host -Prompt "Enter VM Name "
}
$subAccess = Read-Host -Prompt "Enter Subscription, Press (1) OR (2): `n(1) Microsoft Azure Enterprise Non-Production `n(2) Microsoft Azure Enterprise Production`n"
if ($subAccess -eq 1)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
} elseif ($subAccess -eq 2)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
#userRTAccessCheck -RName $resoruceNameChoice
} else
{
Write-Host "Please Enter 1 OR 2"
}
# Arrays for app
$groupArray = @()
$ADAccessGroupArray = @()
$resourceGroupArray = @()
$userObjectID = "USER_OBJECT_ID"
# Get AD User Groups and list of resource groups
$groupArray += (Get-AzADGroup -SearchString 'SS_*' | Select-Object -ExpandProperty Id)
foreach($group in $groupArray)
{
if(Get-AzADGroupMember -GroupObjectId $group | Where-Object {$_.Id -eq $userObjectID})
{
$ADAccessGroupArray += $group
Write-Host "User has access to group: " $group
} else
{
Write-Host "User does not have access to group: " $group
}
}
# Get a list of resource groups
$resourceGroupArray += Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName
# Check if the AD group has been assigned to the resource group
foreach ($resourceGroupName in $resourceGroupArray)
{
foreach ($ADAccessGroup in $ADAccessGroupArray)
{
if(Get-AzRoleAssignment -ResourceGroupName $resourceGroupName | Where-Object {$_.ObjectId -eq $ADAccessGroup})
{
Write-Host "User has access to group: " $resourceGroupName
}
}
}
$groupArray = $null
$ADAccessGroupArray = $null
$resourceGroupArray = $null
提前致谢
我做了一些应该有帮助的修改。
function userLogin($azureAplicationId, $azureAppPassword)
{
$azureTenantId= ""
$azurePassword = ConvertTo-SecureString $azureAppPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
}
function userRGAccessCheck($RG)
{
$resoruceGroupChoice = Read-Host -Prompt "Enter Resource Group Name "
}
function userRTAccessCheck($RName)
{
$resoruceNameChoice = Read-Host -Prompt "Enter VM Name "
}
$subAccess = Read-Host -Prompt "Enter Subscription, Press (1) OR (2): `n(1) Microsoft Azure Enterprise Non-Production `n(2) Microsoft Azure Enterprise Production`n"
if ($subAccess -eq 1)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
} elseif ($subAccess -eq 2)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
#userRTAccessCheck -RName $resoruceNameChoice
} else
{
Write-Host "Please Enter 1 OR 2"
}
# Arrays for app
$groupArray = @()
$ADAccessGroupArray = @() -as [System.Collections.Arraylist] # Using Arraylist type
$resourceGroupArray = @()
$userObjectID = "USER_OBJECT_ID"
# Get AD User Groups and list of resource groups
$groupArray = (Get-AzADGroup -SearchString 'SS_*' | Select-Object -ExpandProperty Id) # Removed += because it is unnecessary
foreach($group in $groupArray)
{
if((Get-AzADGroupMember -GroupObjectId $group).where({$_.Id -eq $userObjectID},'First')) # Used where method
{
$null = $ADAccessGroupArray.Add($group) # Add group to arraylist and suppress output. Removed += because it is a slow operation here.
Write-Host "User has access to group: " $group
} else
{
Write-Host "User does not have access to group: " $group
}
}
# Get a list of resource groups
$resourceGroupArray = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName # Removed += because it is unnecessary
# Check if the AD group has been assigned to the resource group
foreach ($resourceGroupName in $resourceGroupArray)
{
if((Get-AzRoleAssignment -ResourceGroupName $resourceGroupName).where({$_.ObjectId -in $ADAccessGroupArray},'First')) # used where method
{
Write-Host "User has access to group: " $resourceGroupName
}
}
$groupArray = $null
$ADAccessGroupArray = $null
$resourceGroupArray = $null
我在更改的行中添加了注释。以下是更改的摘要:
$ADAccessGroupArray
为 arraylist 类型。这样我们就可以访问固有的Add()
方法来更新它。如果我们使用不可变的数组,则必须创建一个新数组以添加更多条目。更新数组的一种方法是使用+=
,随着数组大小的增长,这是一种非常低效的操作。
+=
这不是最有效的方法。有时这是一个可以忽略不计的操作,但我会避免它,除非你知道它可以忽略不计。+=
从您的其他数组分配中删除了,因为当您将变量设置为返回数组的命令输出时,它们不是必需的。结果将是一个没有+=
. 在某些情况下,您的命令返回一个值,然后您的变量可能不会成为数组。有很多方法可以使用,
一元运算符或提前声明数组来解决这个问题。Where-Object
了赞成的where()
方法。where-object
(和where()
)不仅在执行任何操作之前等待 LHS 操作完成,它还将在返回结果之前枚举所有流水线项目。使用该where()
方法,我们可以访问模式。在您的两种情况下,我都使用该'First'
模式,以便where()
在找到第一个条件匹配后停止处理。如果您有一个包含 1000 个对象的列表并且匹配项位于该列表的上半部分,这将非常有用。foreach
循环中的嵌套$resourceGroupArray
foreach
循环。这可以通过更新下一个where()
条件来使用-in
运算符来实现。-in
允许您在一个集合中找到一个项目,这是您为每个组所做的。因此,我们将Get-AzRoleAssignment
调用次数从减少ResourceGroups x Groups
到ResourceGroups
。这里应该可以节省大量时间。本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句