Archive for the ‘File Server Administration’ Category

This month I find myself in the need for a quick way to do a simple audit on share permissions on a bunch of files servers. As always I wanted to use PowerShell Remoting (with the code executing on the local server) to accomplish this as enumerating shares is a slow process at the best of times and over the wire this would have been painfully slow.

Before writing a script I always see if anyone has done this already and in this case yes, I stumbled upon

The only thing missing for my requirements was the need to have both the share name and server name adding to the object, this obviously is very minor and only required a couple of alterations, for example:

function Get-SharePermissions
	$ShareSec = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -ComputerName $computername
	ForEach ($ShareS in ($ShareSec | Where {$_.Name -eq $sharename}))
		$SecurityDescriptor = $ShareS.GetSecurityDescriptor()
		$Global:myCol = @()
		ForEach ($DACL in $SecurityDescriptor.Descriptor.DACL)
			$myObj = "" | Select ID, AccessMask, AceType
			$myObj.ID = $DACL.Trustee.Name
			$myObj | Add-Member -MemberType NoteProperty -Name Server -Value $computername
			$myObj | Add-Member -MemberType NoteProperty -Name Share -Value $sharename
			Switch ($DACL.AccessMask)
				2032127 {$AccessMask = "FullControl"}
				1179785 {$AccessMask = "Read"}
				1180063 {$AccessMask = "Read, Write"}
				1179817 {$AccessMask = "ReadAndExecute"}
				-1610612736 {$AccessMask = "ReadAndExecuteExtended"}
				1245631 {$AccessMask = "ReadAndExecute, Modify, Write"}
				1180095 {$AccessMask = "ReadAndExecute, Write"}
				268435456 {$AccessMask = "FullControl (Sub Only)"}
				default {$AccessMask = $DACL.AccessMask}
			$myObj.AccessMask = $AccessMask
			Switch ($DACL.AceType)
				0 {$AceType = "Allow"}
				1 {$AceType = "Deny"}
				2 {$AceType = "Audit"}
			$myObj.AceType = $AceType
			Clear-Variable AccessMask -ErrorAction SilentlyContinue
			Clear-Variable AceType -ErrorAction SilentlyContinue
			$myCol += $myObj
	Return $myCol

Get-SharePermissions -computername $ENV:COMPUTERNAME -sharename $args[0]

Like previous post on my blog I will use PowerShell remoting with a variable for the Servers ($allServers) and having saved the above code (C:\Scripts\Get-SharePermissions.ps1):

icm $allServers -FilePath C:\Scripts\Get-SharePermissions.ps1 -ArgumentList Wallpaper$

And the results:

Thanks for reading and I hope you find this useful. Also special thanks to the orginal author of this excellent script Hugo Peeters @



One of my clients was experiencing slow logon times after enabling roaming profiles and this was tracked down to large profiles. I needed to write a quick script that would tell me the folder size across a bunch of file servers.

I decided to create a function for this task named Get-FolderSize and this is the code:

function Get-FolderSize {
param ( [Parameter(Mandatory=$true)] [System.String]${Path}	)

$objFSO = New-Object -com  Scripting.FileSystemObject
$folders = (dir $path | ? {$_.PSIsContainer -eq $True})
foreach ($folder in $folders)
    $folder | Add-Member -MemberType NoteProperty -Name "SizeMB" -Value (($objFSO.GetFolder($folder.FullName).Size) / 1MB) -PassThru

Get-FolderSize $args[0]

To use this code on a local machine simply execute the above function and call it, for example Get-FolderSize D:\FileData. Now as previously mentioned I wanted to be able to check a large bunch of File Servers and to do that I would first need to create a variable to hold my servers, for example $allServers, then save the above code to the executing server for example C:\Scripts\Get-FolderSize.ps1. This finally allowed me to run the following command:

$folders = icm $allServers -FilePath C:\Scripts\Get-FolderSize.ps1 -ArgumentList "E:\Profiles"

Now to see the top 10 worst offenders with a filter to show only two decimal places:

 $folders | sort -Property SizeMB -Descending | select fullname,@{n='SizeMBN2';e={"{0:N2}" -f $_.SizeMB}} | select -First 10

Well as you can see from the below screen my client has some profiles to clean up but at least now they know which ones.

Thanks for reading and I hope you find this useful.