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
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”
$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
Noticed that IPC share doesn’t give path, hence the error
Regards
Nitish Kumar
________________________________