PowerShell: File Share inventory of all File Servers


Managing a large infra never happens to be easy without right kind of tools and tools usually come with cost. In past Unix users used to taunt Windows users on this point as they used to enjoy many open source products and scripts which Windows users weren’t privy of. Things changed a lot since PowerShell.

Presenting you a script to have a size and permission inventory of all your shares on all file servers. Below would be the pre-requisites:

1. Names of all file servers.
2. All the file servers should have WinRM enabled (Windows 2012 servers have it on by default and for Windows 2008, winrm quickconfig may do the trick).
3. Obviously Local Administrator permissions on all File Servers, which should have permissions on shares as well.

After that just change the variable $RemoteComputers value with the name of file servers in place of dummy values placed in form of array right now. That’s it.

This script lists names of all servers (provided by you), shares on them, NTFS permissions, Size in MB, Last modified date and Last accessed date.

The below would be PowerShell script for the task.. tell me what you think about it

# Author : Nitish Kumar
# Performs an audit of file shares
# Outputs the results to a csv file.
# version 1.0
# 26 March 2018

Function GetShareDetails
{
[CmdletBinding()]
Param (
$Server
)
$array= @()
$Shares = Get-WmiObject -class Win32_Share -Computername $Server
ForEach($Share in $Shares){
$Details = Get-Item $Share.Path
$SharePermissions = (Get-ACL -path $Share.Path).Access | Select-object IdentityReference, FileSystemRights, AccessControlType
$obj = New-Object PSObject
$Size = [Math]::Round((Get-ChildItem -Recurse $Share.Path -ErrorAction SilentlyContinue| Measure-Object Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB, 2)
$obj |Add-Member -MemberType NoteProperty -Name "ServerName" $env:Computername
$obj |Add-Member -MemberType NoteProperty -Name "ShareName" $Share.Name
$obj |Add-Member -MemberType NoteProperty -Name "Path" $Share.Path
$obj |Add-Member -MemberType NoteProperty -Name "Allowedusers" $($SharePermissions.IdentityReference -join ',')
$obj |Add-Member -MemberType NoteProperty -Name "Accesstype" $($SharePermissions.FileSystemRights -join ',')
$obj |Add-Member -MemberType NoteProperty -Name "SizeinMB" $Size
$obj |Add-Member -MemberType NoteProperty -Name "DateModified" $Details.LastWritetime
$obj |Add-Member -MemberType NoteProperty -Name "DateLastAccessed" $Details.LastAccesstime
$array +=$obj
} $array | select-object ServerName,ShareName,Path,Allowedusers,AccessType,SizeinMB,DateModified, DateLastAccessed
}

$RemoteComputers = ("ABC01", "XYZ01", "MNO01")

$Result = @()
$k = 0

ForEach ($Computer in $RemoteComputers)
{
$k++
Write-Progress -activity "Getting File Shares Details ($k / $($RemoteComputers.Count)):" -status "Percent Done: " -PercentComplete (($k / $RemoteComputers.Count) * 100) -CurrentOperation "Now processing $($Computer)"
$temp = Invoke-Command -ComputerName $Computer -ScriptBlock ${Function:GetShareDetails} -ArgumentList $Computer -ErrorAction Continue
$temp | ft ServerName,ShareName,Path,Allowedusers,AccessType, SizeinMB,DateModified, DateLastAccessed
$Result += $temp
}
$Result | Select-object ServerName,ShareName,Path,Allowedusers,AccessType, SizeinMB,DateModified, DateLastAccessed|export-csv -nti $env:userprofile\desktop\FileSharedata_$(get-date -Uformat "%Y%m%d-%H%M%S").csv

4 thoughts on “PowerShell: File Share inventory of all File Servers

  1. Im getting an error on every host with a $IPC share:

    Cannot bind argument to parameter ‘Path’ because it is an empty string.
    + CategoryInfo : InvalidData: (:) [Get-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.GetItemCommand

    Also, in the output the “Allowed Users” is being truncated.

    I also added the following to take the list of computers from a file.
    #$RemoteComputers = (“ABC01”, “XYZ01”, “MNO01”)
    $RemoteComputers = Get-Content “.\DFS_Servers.txt”

    1. $RemoteComputers via Get-Content seems fine.

      Get-Item getting empty string means output not coming from below line and shares have blank

      $Shares = Get-WmiObject -class Win32_Share -Computername $Server

      An IF statement can be added to check if $Shares.count -ge 0 and only then for loop to be processed.

      Any other error should be related to PS remoting access only

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.