我正在编写一个脚本,用于查询我们所有AD域的工作,然后返回具有管理权限的计算机。下面的脚本工作并返回预期的结果,但它在我们较大的域上非常缓慢。如何加快AD对象上的PowerShell操作
当使用23k以下的对象时,只需几分钟(6分钟左右)就可以运行,但当它处理90k +时,就会花费数小时。
我是PowerShell的新手,不知道这里有什么操作会有指数运行时增加,所以我一直无法缩小它。我的直觉是它必须以这种方式来处理PowerShell扩展数组以不断添加更多对象?我也在考虑更好地使用管道......但是从新来的新人来我不熟悉这个概念以及如何在此代码中使用它
有没有一种方法可以加速运行快几个小时?任何帮助将不胜感激。
$date = Get-Date -uFormat %d-%m-%y
ForEach($domain in $domains)
{
$all_computers = Get-ADComputer -Server $domain -filter * -Properties enabled | select-object name,enabled,@{name="distinguishedname";expression={$_.DistinguishedName -replace "(CN[^,]+,)"}}
#Gets all of the objects that are in a group and pulls their names this is to get the admin flag that is appended to names in this group
$group_name = (Get-ADGroup -Server $domain -Filter{name -like "*admin*"}).Name
#Counts the devices pulled from the computer query
$DevNum = $all_computers.count
echo "Number of devices: " $DevNum > "$domain LARGE $date.txt"
#Remove servers from the list
$all_computers = $all_computers | ?{ $_ -NotMatch "Servers" }
#Counts the number of servers we removed
$NumSkipped = $DevNum - $all_computers.count
Switch($all_computers){
#Finding all of the accounts where both types of admins exist and removing them from the master list
{$group_name -contains $($_.name + "Admins") -and $group_name -contains $($_.name + "UPEPAdmins")} {$_ | Add-Member "admintype" "both";Continue}
#Finding all of the accounts with only exception admins and removing them from the master list
{$group_name -contains $($_.name + "Admins")} {$_ | Add-Member "admintype" "old";Continue}
#Finding all of the accounts with only upep admins and removing them from the master list
{$group_name -contains $($_.name + "UPEPAdmins")} {$_ | Add-Member "admintype" "UPEP";Continue}
#These accounts have no admin
default {$_ | Add-Member "admintype" "No"}
}
echo "Number of servers skipped: " $NumSkipped >> "$domain LARGE $date.txt"
echo "Number of workstations: " $all_computers.count >> "$domain LARGE $date.txt"
echo "Number of Exception admins found: " $($all_computers|?{$_.admintype -match "old|both"}).count >> "$domain LARGE $date.txt"
echo "Number of UPEP admins found: " $($all_computers|?{$_.admintype -match "upep|both"}).count >> "$domain LARGE $date.txt"
echo "Number of both UPEP and Exception admins found: " $($all_computers|?{$_.admintype -eq "both"}).count >> "$domain LARGE $date.txt"
#output
$all_computers | Export-Csv "$domain LARGE $date.csv"
}
编辑1:
更新代码,以反映从SodaWillow,TheMadTechnician和 除去修剪并用-replace替换它通过一点点降低运行时的建议。
编辑2:
更新了代码的正确解,TheMadTechnician的建议ontop的我过滤组以降低它们的数量,并且还插入组名称到一个数组,而不是一个表。与减少的组数相结合,阵列的使用显着加快了操作速度。
当前错误:“两个”管理员类型正确导出到CSV,但没有在文本文件中报告,我认为它与if语句中的逻辑有关。我在看,目前
编辑3:
固定两种管理类型的逻辑错误,这是对这个问题的最终解决方案。 由于私人信息,$ domains var会在此代码块的视图之外声明。
谢谢大家,你的时间!
您可能想尝试LDAP过滤器和'System.DirectoryServices.DirectorySearcher'(示例在这里:http://www.powershelladmin.com/wiki/Getting_usernames_from_active_directory_with_powershell)。测量代码的每个部分所耗费的时间以查找最长的查询,然后从优化那些开始(如果您还没有这样做) – sodawillow
我试图在代码块上运行并使用Measure-Command来测试看看我可能会增加不必要的时间。没有什么似乎是过度的,但是如果放在一起需要很长时间 – Mack
我会想象L2和L4的持续时间比其他时间长得多。也许可以用'Get-ADGroup'来重写L4? – sodawillow