Technology Blog

PowerShell: find files owned by user


Sometimes you need to find all files owned by a user. Recursively on your Windows Server NTFS file system. PowerShell has some nice cmdlets and features to automate this task for you. Here you’ll find an example script to Find files owned by a user with Powershell


Find files owned by a user with Powershell

Here is the example script to find files owned by a user, later on we’ll dive in to what it does:

[String]$username = "[username]"
[String]$outfile = "[output_file_path]"
$path = Get-ChildItem "." -Recurse
Foreach ($file in $path)
  $f = Get-Acl $file.FullName
  if ($f.Owner -eq $username)
    Write-Host (
      "{0}"-f $file.FullName | Out-File 
      -Encoding "UTF8" 
      -FilePath $outfile -Append

Don’t forget to fill out the variables [username] and [output_file_path] (yes, results are logged to a file). Some formatting was done in this code snippet.

PowerShell Cmdlets

Cmdlets are the heart-and-soul of Windows PowerShell. A cmdlet is a lightweight command that is used in the Windows PowerShell environment. The Windows PowerShell runtime invokes these cmdlets within the context of automation scripts that are provided at the command line. The Windows PowerShell runtime also invokes them programmatically through Windows PowerShell APIs. (Source: MSDN Cmdlet Overview, A Task-Based Guide to Windows PowerShell Cmdlets)

Script explanation

What the above PowerShell script, to find all files owned by a particular user, does is pretty straightforward. First we define a $username to look for, which can be either a AD user or local user. And we define a path for our results logfile with $outfile. Both are of the type String.

The Cmdlet Get-ChildItem is used to get the items and child items (folders and files) in a specified location. The specified location is the current directory: ".". Since we want to find all files, we recurse into subdirectories using the -Recurse parameter.
The result -all files- is stored into our $path variable, through which we loop with Foreach.

Within our PowerShell Foreach loop, the Get-Acl Cmdlet is used to retrieve the ACL’s, or Access Control Lists, of that file or directory. E.g, the “permissions”. We only want the files owned by the specified user, for which we use the Owner property. The file (or folder) path itself is stored in .FullName.

When we’ve found a match (if ($f.Owner -eq $username)), the result is written to our logfile with Write-Host and a piped Out-File.

Get-ChildItem memory usage

Yes, this example Powershell script can use a lot of memory when run on a directory with millions of files. Use with care.

PowerShell Cmdlets Recursiveness – why use Get-ChildItem?

You might wonder why we first use Get-ChildItem to dive into a file system before using Get-Acl? Simple: on the “Hey, Scripting Guy” blog we can read that Get-Acl doesn’t accept a sort of -Recurse parameter, that would enable you to retrieve the owners of all the files located in any subfolder. The Get-ChildItem cmdlet does accept the –Recurse parameter.

PowerShell Cmdlets used

Here are all PowerShell Cmdlets used in this script:

Pretty simple right?

Get-ChildItem and Get-Acl one-liner

The above can also be accomplished in a one-liner:

Get-ChildItem "." -recurse 
  -erroraction 'silentlycontinue' | 
  Get-Acl | where {
    $_.Owner -match "[username]"

Here, -erroraction 'silentlycontinue' is used to suppress PowerShell errors from being printed. Some formatting was done in this code snippet.