-
-
Save manesec/60ce5511137d821cf3666326212805b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/ | |
Add-Type @" | |
[System.FlagsAttribute] | |
public enum ServiceAccessFlags : uint | |
{ | |
QueryConfig = 1, | |
ChangeConfig = 2, | |
QueryStatus = 4, | |
EnumerateDependents = 8, | |
Start = 16, | |
Stop = 32, | |
PauseContinue = 64, | |
Interrogate = 128, | |
UserDefinedControl = 256, | |
Delete = 65536, | |
ReadControl = 131072, | |
WriteDac = 262144, | |
WriteOwner = 524288, | |
Synchronize = 1048576, | |
AccessSystemSecurity = 16777216, | |
GenericAll = 268435456, | |
GenericExecute = 536870912, | |
GenericWrite = 1073741824, | |
GenericRead = 2147483648 | |
} | |
"@ | |
function Get-ServiceAcl { | |
[CmdletBinding(DefaultParameterSetName="ByName")] | |
param( | |
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName="ByName")] | |
[string[]] $Name, | |
[Parameter(Mandatory=$true, Position=0, ParameterSetName="ByDisplayName")] | |
[string[]] $DisplayName, | |
[Parameter(Mandatory=$false, Position=1)] | |
[string] $ComputerName = $env:COMPUTERNAME | |
) | |
# If display name was provided, get the actual service name: | |
switch ($PSCmdlet.ParameterSetName) { | |
"ByDisplayName" { | |
$Name = Get-Service -DisplayName $DisplayName -ComputerName $ComputerName -ErrorAction Stop | | |
Select-Object -ExpandProperty Name | |
} | |
} | |
# Make sure computer has 'sc.exe': | |
$ServiceControlCmd = Get-Command "$env:SystemRoot\system32\sc.exe" | |
if (-not $ServiceControlCmd) { | |
throw "Could not find $env:SystemRoot\system32\sc.exe command!" | |
} | |
# Get-Service does the work looking up the service the user requested: | |
Get-Service -Name $Name | ForEach-Object { | |
# We might need this info in catch block, so store it to a variable | |
$CurrentName = $_.Name | |
# Get SDDL using sc.exe | |
$Sddl = & $ServiceControlCmd.Definition "\\$ComputerName" sdshow "$CurrentName" | Where-Object { $_ } | |
try { | |
# Get the DACL from the SDDL string | |
$Dacl = New-Object System.Security.AccessControl.RawSecurityDescriptor($Sddl) | |
} | |
catch { | |
Write-Warning "Couldn't get security descriptor for service '$CurrentName': $Sddl" | |
return | |
} | |
# Create the custom object with the note properties | |
$CustomObject = New-Object -TypeName PSObject -Property ([ordered] @{ Name = $_.Name | |
Dacl = $Dacl | |
}) | |
# Add the 'Access' property: | |
$CustomObject | Add-Member -MemberType ScriptProperty -Name Access -Value { | |
$this.Dacl.DiscretionaryAcl | ForEach-Object { | |
$CurrentDacl = $_ | |
try { | |
$IdentityReference = $CurrentDacl.SecurityIdentifier.Translate([System.Security.Principal.NTAccount]) | |
} | |
catch { | |
$IdentityReference = $CurrentDacl.SecurityIdentifier.Value | |
} | |
New-Object -TypeName PSObject -Property ([ordered] @{ | |
ServiceRights = [ServiceAccessFlags] $CurrentDacl.AccessMask | |
AccessControlType = $CurrentDacl.AceType | |
IdentityReference = $IdentityReference | |
IsInherited = $CurrentDacl.IsInherited | |
InheritanceFlags = $CurrentDacl.InheritanceFlags | |
PropagationFlags = $CurrentDacl.PropagationFlags | |
}) | |
} | |
} | |
# Add 'AccessToString' property that mimics a property of the same name from normal Get-Acl call | |
$CustomObject | Add-Member -MemberType ScriptProperty -Name AccessToString -Value { | |
$this.Access | ForEach-Object { | |
"{0} {1} {2}" -f $_.IdentityReference, $_.AccessControlType, $_.ServiceRights | |
} | Out-String | |
} | |
$CustomObject | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment