Can I speed this up?
-
Wednesday, April 14, 2010 10:08 AM
Hello,
I'm quite new to powershell and the way you can pass on variables and object and such.
Currently I'm working on a script which lists all the home-directories in a specified share and puts that in a variable. Another variable is filled with (all)AD-useraccounts with some properties such as homedirectory, profiledirectory etc..
I want to know is the folder I'm looking at is "attached" to an user (the homedirectory property). We need to do this because in the old days the removal of old data was not realy done properly. To do this I'm looping through the homedirectory variable within that loop, I loop throught the activedirectory variable to find a match. This way of looping works I get the results I want. BUT is takes very very long to loop through those variables (it costs around 13 minutes for 150 homedirectories and 5228 ad accounts, and that is a reduced set of homefolders, the real scan is much bigger). I there a way to speed this process up?
This is the loop I use (I stripped it a bit to make it more readable)
:folderloop foreach ( $folder in $current_folders ) {
#Here I'm setting some variables
:userresultloop foreach ($objResult in $colResults) {
$objSearched = $objResult.Properties
#Here I'm setting some variables
if ([string]$objSearched.homedirectory -eq $folder.FullName){
# Here I'm writing some info to an Excell object
$found = $true
break :userresultloop
}
}
if ($found -ne $true ){
# Here I'm writing some info to an Excell object
}
}
Thanks in advance,
Raymond
All Replies
-
Wednesday, April 14, 2010 10:56 AM
Instead of looping everything through the directory names, I'd do this first:
$folderlist = $current_folders | foreach-object {$_.fullname}
Then get rid of the nested loop, and change this:
if ([string]$objSearched.homedirectory -eq $folder.FullName){
to:
if ($flolderlist -contains [string]$objSearched.homedirectory){
- Marked As Answer by Marco ShawModerator Wednesday, April 14, 2010 6:45 PM
- Unmarked As Answer by Raymond_nl Friday, April 16, 2010 6:48 AM
-
Wednesday, April 14, 2010 11:33 AMModerator
Instead of looping everything through the directory names, I'd do this first:
$folderlist = $current_folders | foreach-object {$_.fullname}
Then get rid of the nested loop, and change this:
if ([string]$objSearched.homedirectory -eq $folder.FullName){
to:
if ($flolderlist -contains [string]$objSearched.homedirectory){
In PowerShell v1, ForEach-Object was known to be relatively slow (as compared to the construct foreach(...){}). You might also want to consider trying this:$folderlist=$current_folders|select fullname
**I've not tested ForEach-Object vs Select-Object though**
-
Wednesday, April 14, 2010 11:45 AM
In PowerShell v1, ForEach-Object was known to be relatively slow (as compared to the construct foreach(...){}). You might also want to consider trying this:$folderlist=$current_folders|select fullname
**I've not tested ForEach-Object vs Select-Object though**
Select-object may be slower, but in this application also presents another problem. The -contains test won't work because you'll be comparing dissimilar object types. The home directory attribute is a string object. Select-object will produce a custom psobject with the directory name as property of the object.
-
Wednesday, April 14, 2010 12:27 PM
Something else that might speed it up would be to do this:
$folderlist = $current_folders | sort lastwritetime -desc | foreach-object {$_.fullname}
Assuming -contains is going to check through $folderlist in order, as soon as it gets a hit, it's going to return $true, and quit. If you sort the folders by lastwritetime first, the currently active folders should all be at the top of the list, and the old, forgotten ones at the bottom.
- Marked As Answer by Raymond_nl Friday, April 16, 2010 6:48 AM
-
Wednesday, April 14, 2010 6:02 PM
I would also suggest to group the AD info based on its home directory value, then filter only the groups whose name is in the folder list.
1
2
3
4
5
6
7
8
9
10
11
12
13$folders = $current_folders | ForEach-Object {$_.FullName}
$colResults | Group-Object {$_.Properties.homedirectory} |
Where-Object {$folders -contains $_.Name} | ForEach-Object {
# if you want to retrieve data from the folder
$folder = Get-Item $_.Name
#Here I'm setting some variables
$_.Group
} | ForEach-Object {
# retrieve the AD data
$objResult = $_
#Here I'm setting some variables
# Here I'm writing some info to an Excell object
}
Important: My AD skills are limited, so the way the code groups the objects (line 2) may be different, but as long as you place the statement in a
ScriptBlockit should work.
Robert Robelo- Marked As Answer by Marco ShawModerator Wednesday, April 14, 2010 6:45 PM
-
Thursday, April 15, 2010 11:25 AM
Hello All,
Thank you for all the input. I'm looking to incorporate the tips in my script. Based on the sorting remark of mjolinor, I ordered the data that was in the colResults variable (since the folder data was already ordered), this action already decreased the processingtime with 10 minutes, the processingtime is now around 3 minutes (150 folders against 5229 accounts). YES!!!!
Thanks, Thanks, Thanks
Raymond

