I wrote a Powershell v3 script to list all the files owned by a user on our file server. It ran for 3 hours before I stopped it. It has to go through 619,238 Files and 57,452 Folders (517 GB). What order of magnitude should this take? Is there a way to improve the speed?
I tried to do this using pipes, but failed to get anything to work.
It's running on a Vmware virtual machine running Windows 2009 R2 SP1 with 4GB of memory. It uses about 60% of the CPU when I run it.
Here the code I wrote. I am very new to Powershell, but I have a lot of experience with Perl. My co-workers said to write a bat file.
<#
.SYNOPSIS
C:\ams\psscripts\list-files.ps1
.DESCRIPTION
List all the files that a given user owns
.PARAMETER none
username: user
logfile: path to log file. This is optional. If omitted the the log file is created "u:\scratch\<$username>-files.txt
.EXAMPLE
C:\ams\psscripts\list-files.ps1 plo
Example: C:\ams\psscripts\list-files.ps1 plo u:\scratch\log.txt
#>
param (
[string]$username,
[string]$logfile
)
# Load modules
Set-ExecutionPolicy Unrestricted
Import-Module ActiveDirectory
Add-PSSnapin Quest.ActiveRoles.ADManagement
function printHelp {
Write-Host "This script will find all the files owned by a user. It scans \\dfs\groups"
Write-Host "C:\ams\psscripts\list-files.ps1 user logfile (optional)"
Write-Host "Example: C:\ams\psscripts\list-files.ps1 plo"
Write-Host "Example: C:\ams\psscripts\list-files.ps1 plo u:\scratch\log.txt"
}
if ($logfile -eq "") {
$logfile = "u:\scratch\" + $username + "-files.txt"
Write-Host "Setting log file to $logfile"
}
# you must use a UNC path
[String]$path = "\\dfs\u$\groups"
[String]$AD_username = "AMS\" + $username
# check that we have a valid AD user
if (!(Get-QADUser $AD_username)){
Write-Host "ERROR: Not a valid AD User: $AD_username"
Exit 0
}
Write-Output "Listing all files owned by $username from $path" | Out-File -FilePath $logfile
Write-Host "Listing all files owned by $username from $path"
$d = Get-Date
Write-Output $d | Out-File -FilePath $logfile -Append
$files = Get-ChildItem $path -Recurse
Foreach ($file in $files)
{
$f = Get-Acl $file.FullName
$d = [string]::Compare($file.FullName, $username, $True)
if (($f.Owner -eq $username) -or ($f.Owner -eq $AD_username))
{
Write-Host "$file.FullName"
Write-Output $file.FullName | Out-File -FilePath $logfile -Append
}
}
Write-Host "Completed"
exit 0
The next step I have to do is modify the script above to find the files owned by a given user and change them to their manager.
This is the script I found to change the owner. It will be in a loop which walks the filesystem. Is this a good way to do this.
$username=”dnp”
$domain=”ams”
$ID = new-object System.Security.Principal.NTAccount($domain, $username)
# file to change owner. must be UNC path
$path = "\\dfs\c$\ams\psscripts\test.txt"
write-host $path
$acl = get-acl $path
$acl.SetOwner($ID)
set-acl -path $path -aclObject $acl
Thanks, Dan