Getting Folder Details from Remote Computers using PowerShell

This is post all about getting details about shared folders from remote computers using few techniques. We can get various information like last modified time, ACLs, etc. But it can get time consuming in a large production environment at the point when we have to calculate folder size.

Method 1: Measure-object

This can work for a small environment, but can take unreasonable long time on large work environment.

$CSVFile = "C:\logs.csv"
$machines = get-content "C:\servers.txt"
"Computer name,Foldername,Modified time,User/Group,Permissions" | 
out-file -FilePath $CSVFile -append
foreach ($machine in $machines) 
{
 $items = Get-ChildItem \\$machine\h$\USER , \\$machine\h$\USERS
 foreach ($item in $items)
  {
<#Check only folders and filter out files#>
   if ($item.Attributes -eq "Directory")            
    {         
<#-----Get folder name--------------------#>
     $FoldName = $item.Name          
     Write-Host $FoldName
<#------Get last modified timestamp-------#>
     $ModTime = $item.lastwritetime          
     Write-Host $ModTime
<#----------Get folder size---------------#>
     $size = ($item | measure Length -sum).sum/1mb
<# We will collect information about ACL where Folder name 
then matches the name of user
Also we can employ any other condition for our purpose here #>
     $ACLs = get-acl $item.fullname | ForEach-Object { $_.Access  }
     Foreach ($ACL in $ACLs)
      {
       if ($ACL.IdentityReference -eq “Company\" + $FoldName)
        {
         $OutInfo = $machine+","+$FoldName+","+$ModTime+","+$ACL.IdentityReference+","+$ACL.FileSystemRights+","+$size
         Write-Host $OutInfo
         Add-Content -Value $OutInfo -Path $CSVFile
        }
      }
    }
  } 
}

Method 2: File system object

It is observed that calculating folder size by using file system object deliver higher speed and more accurate folder sizes.

$fso = New-Object -comobject Scripting.FileSystemObject
$folder = $fso.GetFolder($path)
$size = [math]::round(($folder.size)/1mb , 2 , 1 )

Method 3: PSExec

There are certain things we need to ensure before proceeding with this method. Firstly, PSExec service must not be in disabled or marked for deletion state in target remote server. Secondly, the account launching the script should have appropriate administrative privileges. Thirdly, execution of scripts must not be disabled in remote computers via group policy.

Step 1> Proceeding with this method, first create a runme file with name, say runme.ps1 as follows:

$CSVFile = "C:\shared_folder\logs.csv"
"File Server,P Folder Name,P Folder Size,Last Modified time,`
User Name,NTFS Access" | out-file -FilePath $CSVFile -append
$machines = get-content "C:\shared_folder\servers.txt"
ForEach ($machine In $machines) 
{
 if (Test-Connection -ComputerName $machine -Count 2 -ErrorAction SilentlyContinue)   
  {
   Write-Host "$machine is up" -ForegroundColor Green
<#-----& is an alternative of start-process-------
accepteula switch will bypass dialog of accepting eula agreement #>     
& C:\Windows\System32\psexec.exe \\$machine -u Company\admin -p ### -h -accepteula1 cmd.exe /c "\\server1\shared_folder\Script.bat"  
  }
 else    
  {
   Write-Host "$machine is down" -ForegroundColor Red
   $info = $machine + "," + "is down"
   Add-content -value $info -Path $CSVFile
  }
}

Step 2> Above script will call out to following batch file “Script.bat” over network.

@Echo Off
Net Use T: /delete /yes
Net Use T: \\server1\shared_folder
CMD /C powershell.exe -ExecutionPolicy Bypass -Command T:\Get_ACL.ps1
Net Use T: /delete /yes
Exit

Step 3> Above script will map the folder with script as a network drive on remote computer and then call out to following Get_ACL.ps1 file which is actually responsible for gathering shared folder information. Note that now we won’t use network path of folders, instead we will write complete local path. As the script runs locally on the remote computer, this script will offset the delay caused due to network latency.

$CSVFile = "T:\logs.csv"
$machine = hostname
$Folders = Get-ChildItem h:\USER , h:\USERS


After this we have our usual script where we can employ either method 1 or method 2.

As a concluding remark, this method has highest speed among others mentioned here on this post and should ease off burden of lots of windows administrators.

Advertisements