need to speedup this script

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 6 years and 4 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
ActiveDirectory
Posts: 6
Last visit: Wed May 05, 2021 1:29 am

need to speedup this script

Post by ActiveDirectory »

Hi together ..
i need to speedup this script.. it has a RunTime more than 4 days in our enviroment does someone has an Idea ? and of course to replace the Quest Stuff.. unfortunally i was not so successfull with using ADFind which is very fast for Query AD stuff

  1.  
  2. ForEach ($which in $DC)
  3. {
  4.     if (($i % 200) -eq 0)
  5.     {
  6.         [System.GC]::Collect()
  7.     }
  8.     Connect-QADService -Service $which |Out-Null
  9.     $DomName  = ($which | Select-Object -unique -First 2).Split(".")[1]
  10.     # $path = "d:\reports\KPIReports\KPI OUAdmins $DomName $((Get-Date).ToString('yyyy.MM.dd-HH.mm')).csv"
  11.     $path = "d:\reports\KPIReports\KPI OUAdmins $DomName.csv"
  12.     Write-output "KPI OUAdmins $DomName has started at $((Get-Date).ToString('yyyy.MM.dd-HH.mm'))"
  13.    
  14.     $Domain  = ($which | Select-Object -First 2).Split(".")[1]+ ".contiwan.com"
  15.     $Domain_Manfred  = ($which | Select-Object -First 2).Split(".")[1]
  16.     $Domain_Manfred
  17.     $Admins = Get-QADGroup -SearchRoot "$Domain/groups"  | Where-Object {$_.Name -match 'Administrative Users'}
  18.     $AllOuAdmins = Get-QADGroup -SearchRoot "$Domain/groups" | Where-Object {$_.Name -match 'All-OU-Administrators'}
  19.     $FRs = Get-QADGroup -SearchRoot "$Domain/lda" -SizeLimit 0 | Where-Object {$_.Name -match '_[fm]r[\d][0-99]' } | Sort-Object "Name"
  20.     $MRs = Get-QADGroup -SearchRoot "$Domain/cda/Administration/FuncRoles" -SizeLimit 0 | Where-Object {$_.Name -match '_[fm]r[\d][0-99]' } | Sort-Object "Name"
  21.  
  22.     $Groups = $FRs + $MRs + $Admins + $AllOuAdmins
  23.     #$Groups = $Admins + $AllOuAdmins
  24.  
  25.     $Result = @()
  26.     $Result += "Group Name|Members|Type|Parent Container|Group Description|Domain"
  27.  
  28.     ForEach ($Group in $Groups) {
  29.         $Members = Get-QADGroupMember $Group.DN -Indirect -SizeLimit 0
  30.         #If ($Members -eq $null) {Write-output $Group.CanonicalName -fore red; $Result += "$($Group.Name)|-|-|-|$($Group.Description)"}
  31.         If ($null -eq $Members) {$Result += "$($Group.Name)|-|-|-|$($Group.Description)|$Domain_Manfred"}
  32.        
  33.         Else {$Members | Sort-Object -Property type,name | ForEach-Object{$Result += "$($Group.Name)|$($_.Name)|$($_.Type)|$($_.ParentContainer)|$($Group.Description)|$Domain_Manfred"}}
  34.     }  
  35.    
  36. # Export permissions for all the Members into csv
  37.     Set-Content -Path $path -Value $Result
  38.     Write-output "KPI OUAdmins $DomName has finished at $((Get-Date).ToString('yyyy.MM.dd-HH.mm'))"
  39.     # copy "D:\reports\KPIReports\KPI*.csv" "d:\reports\KPIReports\KPI OUAdmins.csv"
  40.    
  41.    
  42. }
  43. Set-Location D:\scripts\KPIReports
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: need to speedup this script

Post by jvierra »

Install RSAT and use the MS AD CmdLets.

It would also be helpful if you tried to format your code so that it is readable.
User avatar
ActiveDirectory
Posts: 6
Last visit: Wed May 05, 2021 1:29 am

Re: need to speedup this script

Post by ActiveDirectory »

I use as well the RSAT with the AD modules, only in case of these old scripts it is not working (not my invention)

may I tell you the Goal what I have .. we have a very fine and granular RoleConecept that means we have for everything a FuncRole or Master Role.. our Monthly Report should have the number of AdminUsers which are a member of an Administrative Role (rough number of groups are 1800000)

my Problem is now the RunTime and the old Quest Stuff which is not supported anymore for us.

$Admins = Get-QADGroup -SearchRoot "$Domain/groups" | Where-Object {$_.Name -match 'Administrative Users'}
$AllOuAdmins = Get-QADGroup -SearchRoot "$Domain/groups" | Where-Object {$_.Name -match 'All-OU-Administrators'}
$FRs = Get-QADGroup -SearchRoot "$Domain/lda" -SizeLimit 0 | Where-Object {$_.Name -match '_[fm]r[\d][0-99]' } | Sort-Object "Name"
$MRs = Get-QADGroup -SearchRoot "$Domain/cda/Administration/FuncRoles" -SizeLimit 0 | Where-Object {$_.Name -match '_[fm]r[\d][0-99]' } | Sort-Object "Name"

does someone have an Idea how to speed up this 4 parts?
and this one
$Members = Get-QADGroupMember $Group.DN -Indirect -SizeLimit 0

thx
Michael
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: need to speedup this script

Post by jvierra »

The CmdLets would be faster if you used a filter and not a "Where". Using "Where" to filter causes you to return ALL groups everytime.
Also returning all groups once then filter the results would also be faster.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: need to speedup this script

Post by jvierra »

Example:
$Admins = Get-QADGroup -SearchRoot "$Domain/groups" -LDAPFilter '(CN='Administrative Users)'

This will always be faster the a "Where".
User avatar
ActiveDirectory
Posts: 6
Last visit: Wed May 05, 2021 1:29 am

Re: need to speedup this script

Post by ActiveDirectory »

ok with ldapfilter its faster .. thx

now I just need to speed up the Main task in this script.. this is the longest RunTime it will check the collected Groups from before for all Members recursive
$Result = @()
$Result += "Group Name|Members|Type|Parent Container|Group Description|Domain"

ForEach ($Group in $Groups) {
$Members = Get-QADGroupMember $Group.DN -Indirect -SizeLimit 0 | Measure-Object
#If ($Members -eq $null) {Write-output $Group.CanonicalName -fore red; $Result += "$($Group.Name)|-|-|-|$($Group.Description)"}
If ($null -eq $Members) {$Result += "$($Group.Name)|-|-|-|$($Group.Description)|$Domain_Manfred"}

Else {$Members | Sort-Object -Property type,name | ForEach-Object{$Result += "$($Group.Name)|$($_.Name)|$($_.Type)|$($_.ParentContainer)|$($Group.Description)|$Domain_Manfred"}}
}
this takes days to get all discovered :(

Michael
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: need to speedup this script

Post by jvierra »

Try this:

Code: Select all

$allgroups = $Groups |
    ForEach-Object{
        $groupname = $_.Name
        Get-QADGroupMember $_.DN -Indirect -SizeLimit 0 |
            select @{n='GroupName';e={$groupname}},*
    } 
     
If this takes too long then you need to fix your system. The old Quest CmdLets are not compatible with the newer PowerShell and Windows. You may need to upgrade.
This topic is 6 years and 4 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked