How do I check in PowerShell if a service has read access to a certain folder?

1.4k views Asked by At

So far, I know to do the following:

  1. Determine the service logon account - (Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
  2. Get accounts that have read access to the folder - accesschk -q -d $env:TEMP

But this leads me nowhere:

PS C:\> (Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
LocalSystem
PS C:\> accesschk -q -d $env:TEMP
c:\Users\MKHARI~1\AppData\Local\Temp
  RW NT AUTHORITY\SYSTEM
  RW BUILTIN\Administrators
  RW DAYFORCE\mkharitonov
PS C:\> accesschk LocalSystem -q -d $env:TEMP

Accesschk v5.2 - Reports effective permissions for securable objects
Copyright (C) 2006-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

  Error looking up account: LocalSystem:
  The operation completed successfully.
PS C:\> accesschk "DAYFORCE\mkharitonov" -q -d $env:TEMP
RW c:\Users\MKHARI~1\AppData\Local\Temp
PS C:\>

The AccessChk does not seem to recognize LocalSystem. Also, if I run it with an account belonging to the BUILTIN\Administrators, it does not seem to acknowledge the access.

Does it mean AccessChk is not suitable for this or am I using it wrong? Is there a way to do it at all without actually trying to access the folder under the account in question?

When PowerShell is running not as administrator:

PS C:\> $service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "MSSQLSERVER"}
PS C:\> '{0:x}' -f $service.GetSecurityDescriptor().ReturnValue
80070522
PS C:\>

Which corresponds to A required privilege is not held by the client. The command works OK when the PowerShell is running as administrator. Ideally, I would like a solution that does not require elevation.

2

There are 2 answers

3
ClumsyPuffin On BEST ANSWER

localsystem uses the token of nt authority\System, so this command line will work (you will need to map the localsystem to system in code):

accesschk.exe system -q -d $env:temp

I have created a snippet to fetch the proper name and pass it to accesschk (tested in PowerShell v5 and requires elevated access):

$service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "wlidsvc"}
 $desc = (($service.GetSecurityDescriptor()).Descriptor).owner
 $desc.Domain + "\"+$desc.name | %{.\accesschk.exe $_ -q -d $env:temp}

$desc.Domain + "\"+$desc.name will return NT AUTHORITY\SYSTEM instead of localsystem

PS: The script can be optimized

6
4c74356b41 On
$account = 'whatever you like'
$acl = Get-Acl 'folder'
$acl.access | where { $_.IdentityReference -like "*$account*"}).FileSystemRights

I am not sure this will work with PowerShell v.2, but it will work for PowerShell v.3 and later.