Error while auditing folder permissions

jjwolven
jjwolven used Ask the Experts™
on
I am trying to audit the permissions on a file server as a domain administrator and am getting an error for 'unauthorized operation' on some uses. When I use D:\Share\IT, I am able to get the command to run; when I use \Prod I cannot.

I am using the following in PowerShell:
Get-ChildItem D:\Share\Prod -Directory -Recurse | Get-Acl | Select-Object path,accesstostring,owner| Export-Csv C:\Temp\file.csv

I am receiving the following error:
Get-Acl : Attempted to perform an unauthorized operation.
At line:1 char:51
+ Get-ChildItem D:\Share\Prod -Directory -Recurse | Get-Acl |Select-Object  ...
    + CategoryInfo          : NotSpecified: (:) [Get-Acl], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetAclCommand

I am logged in as a domain administrator, with PowerShell using Run As Administrator.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Daniel_PLDB Expert/Architect
Top Expert 2011

Commented:
Hi,

This is the case where permissions are given to only Installer or other account, not administrators.
Please find following code which works fine. Please note that I'm wrapping Get-ChildItem in it's own try catch. That's because System.DirUnauthorizedAccessException is generated before this cmdlet gets its data from an item. If you want to you can later review errors generated by reviewing $gciErr variable. However, they should match those catch inside with Get-Acl :)

try {
	$rootDir="D:\Share\Prod";
	#for test
	#$rootDir="C:\Windows\System32";
	$dirs=Get-ChildItem $rootDir -Directory -Recurse -ErrorAction silentlycontinue -ErrorVariable +gciErr;
} catch {
	$ErrorMessage = $_.Exception.Message
	$FailedItem = $_.Exception.ItemName
	Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
	return;
}

[array]$results=$null;
foreach ($dir in $dirs)
{
	try {
		$acl=$dir | Get-Acl 
		$aclIn=$acl.Access | % {$_ | select @{Name="Path";Expression={$dir.FullName}},IdentityReference, FileSystemRights}
		$results+=$aclIn;
	} catch [System.UnauthorizedAccessException] {
		Write-Output "[WARNING] Unauthorized Access Exception::$($dir.FullName)"
	} catch {
		$ErrorMessage = $_.Exception.Message
		$FailedItem = $_.Exception.ItemName
		Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
		return;
	}	
}  
$results | Export-Csv C:\Temp\file.csv -NoTypeInformation -Delimiter ";";

Open in new window


Edit: I've adjusted your idea to get Access data. Since string returned by native method is impossible to be easily cut I read this information from Access method. Because you're getting all data into CSV I'm putting row for each permission for each directory, so you can work on results as a working set :)
Please note that Path property has type in its name and you implicitly defined childintems as directories, therefore I found it unusable and decided to take FullName property of the outer object which is a directory, not an ACL.

Regards,
Daniel
E ATech Lead

Commented:
Have you followed the above suggestion?

Regarding error it seems like permission issue. You can see who has which permissions on your file and folders by using this solution.

May be I am wrong, but in the PowerShell solution is to use a bare AccessControl object with only the Owner set and then use SetAccessControl to apply the change.  Once this change has taken effect, you can then use Get-Acl & Set-Acl as normal.

Same process as using the GUI; Change the ownership only, then modify as desired.

Get in detailed here:

https://blogs.technet.microsoft.com/josebda/2010/11/12/how-to-handle-ntfs-folder-permissions-security-descriptors-and-acls-in-powershell/

https://blogs.technet.microsoft.com/zarkatech/2012/01/14/audit-file-server-permissions-using-powershell/

https://social.technet.microsoft.com/Forums/lync/en-US/87679d43-04d5-4894-b35b-f37a6f5558cb/solved-how-to-take-ownership-and-change-permissions-for-blocked-files-and-folders-in-powershell?forum=winserverpowershell

Hope this helps!

Author

Commented:
Error when I tried to run (in PowerShell As Administrator):

Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\temp\Get-PermissionList.ps1:29 char:12
+ $results | Export-Csv C:\Temp\file.csv -NoTypeInformation -Delimiter ";";
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportCsvCommand
Should you be charging more for IT Services?

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Daniel_PLDB Expert/Architect
Top Expert 2011

Commented:
Sorry, formatting went off:

try {
	$rootDir="D:\Share\Prod";
	#for test
	#$rootDir="C:\Windows\System32";
	$dirs=Get-ChildItem $rootDir -Directory -Recurse -ErrorAction silentlycontinue -ErrorVariable +gciErr;
} catch {
	$ErrorMessage = $_.Exception.Message
	$FailedItem = $_.Exception.ItemName
	Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
	return;
}
[array]$results=$null;
foreach ($dir in $dirs) {
	try {
		$acl=$dir | Get-Acl 
		$aclIn=$acl.Access | % {$_ | select @{Name="Path";Expression={$dir.FullName}},IdentityReference, FileSystemRights}
		$results+=$aclIn;
	} catch [System.UnauthorizedAccessException] {
		Write-Output "[WARNING] Unauthorized Access Exception::$($dir.FullName)"
	} catch {
		$ErrorMessage = $_.Exception.Message
		$FailedItem = $_.Exception.ItemName
		Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
		return;
	}	
}  
$results | Export-Csv C:\Temp\file.csv -NoTypeInformation -Delimiter ";";

Open in new window

Author

Commented:
I am still receiving the same error.
Daniel_PLDB Expert/Architect
Top Expert 2011

Commented:
That's weird, I don't.

Permissions.jpg

Author

Commented:
Ok, looks like it is showing everything but the permissions at the top level.

To just show the top level, can I go up one level (D:\Shared), then run this after removing "-Recurse"

Is there anything else that would need to be removed?
DB Expert/Architect
Top Expert 2011
Commented:
Hi,

Just include Get-Acl for rootdir before getting into subfolders.

try {
	$rootDir="D:\Share\Prod";
	#for test
	#$rootDir="C:\Windows\System32";
	$dirs=Get-ChildItem $rootDir -Directory -Recurse -ErrorAction silentlycontinue -ErrorVariable +gciErr;
} catch {
	$ErrorMessage = $_.Exception.Message
	$FailedItem = $_.Exception.ItemName
	Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
	return;
}
[array]$results=$null;
#get root
try {
		$acl=$rootDir | Get-Acl 
		$aclIn=$acl.Access | % {$_ | select @{Name="Path";Expression={$rootDir}},IdentityReference, FileSystemRights}
		$results+=$aclIn;
	} catch [System.UnauthorizedAccessException] {
		Write-Output "[WARNING] Unauthorized Access Exception::$(rootDir)"
	} catch {
		$ErrorMessage = $_.Exception.Message
		$FailedItem = $_.Exception.ItemName
		Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
		return;
	}
foreach ($dir in $dirs) {
	try {
		$acl=$dir | Get-Acl 
		$aclIn=$acl.Access | % {$_ | select @{Name="Path";Expression={$dir.FullName}},IdentityReference, FileSystemRights}
		$results+=$aclIn;
	} catch [System.UnauthorizedAccessException] {
		Write-Output "[WARNING] Unauthorized Access Exception::$($dir.FullName)"
	} catch {
		$ErrorMessage = $_.Exception.Message
		$FailedItem = $_.Exception.ItemName
		Write-Output "[ERROR] $FailedItem :: `r`n`t`t$ErrorMessage"
		return;
	}	
}  
$results | Export-Csv C:\Temp\file.csv -NoTypeInformation -Delimiter ";";

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial