PowerShell script is taking amazing long time to run.
I have one file share on our 2012 server. Users have it mapped to a drive. I want to create a spreadsheet of each folder on the share (recursively), what security groups have access to it, and what rights those groups have to the data within the folder.
Now, I have found and run several scripts. They all take an enormous amount of time. For example I am running one now on a small folder (393 files, 29 folders) it is still running after 23 minutes. To run this script on the entire file share of around 223,339 Files, 34,644 Folders will take many hours. I want to be able to get this info monthly to keep an audit trail on it.
All the scripts I find use the same basic methods to recursively search a tree. Does anybody else know a way to either speed this up or use something else? Bottom line I want a spreadsheet I can manipulate to see who can see or modify what with out having to look at each folder to confirm.
The script running on the whole share has been running for 11 hours and 15 minutes at this writing. It is running on the server.
Script:
# Define the parent folder to check permissions on
$foldertosearch = "c:\Company\";
# Where to save the results
$exportfile = "C:\Company\Scripts\Output\FolderPermissions.csv"
# Delimiter used in the output file - DO NOT use a comma
$exportdelimiter = "^";
# Get all folder and sub-folder paths
$parentfolder = @(get-item $foldertosearch);
$subfolders = @(get-childitem $foldertosearch -recurse);
$allfolders = $parentfolder + $subfolders;
# Get domain name as a wildcard
$domainwildcard = (get-addomain).netbiosname + "*";
# Recursive function to find groups and sub groups
function get-subgroups ($groupname, $foldername, $rights) {
# Get all members of the group
$members = get-adgroup $groupname | get-adgroupmember;
# Loop through each member
foreach ($member in $members) {
# If a sub-group is found, recurse
if ($member.objectclass -eq "group") {
get-subgroups $member.samaccountname $foldername $rights;
}
# If a user is found, export results
if ($member.objectclass -eq "user") {
$output = ($folder.fullname, $permission.filesystemrights, $groupname, $member.name) -join $script:exportdelimiter;
$output >> $script:exportfile;
}
}
}
# Loop through each folder
foreach ($folder in $allfolders) {
# Get ACLS
$acls = get-acl $folder.fullname;
# Loop through each ACL on the folder
foreach ($acl in $acls) {
$access = $acl.access;
# Loop through each permission within the ACL
foreach ($permission in $access) {
# Only check identities matching the domain name
if ($permission.identityreference -like $domainwildcard) {
# Remove the domain name from the identity
$identity = ($permission.identityreference -split "\\")[1];
# Get AD Object
$adobject = get-adobject -filter 'SamAccountName -eq $identity';
# If the identity is a group, recurse
if ($adobject.objectclass -eq "group") {
get-subgroups $identity $folder.fullname $permission.filesystemrights;
}
# If a user is found, export results
if ($adobject.objectclass -eq "user") {
$output = ($folder.fullname, $permission.filesystemrights, "Direct Assignment", $identity) -join $exportdelimiter;
$output >> $exportfile;
}
}
}
}
}