Resolving PowerShell Service Control Permission Issues: Why sc.exe Works When Get-Service Fails


3 views

When managing Windows services remotely, many administrators encounter a frustrating scenario where PowerShell's native cmdlets fail while the legacy sc.exe utility succeeds. This typically manifests with error messages like:

Stop-Service : Cannot open MyService service on computer 'myservicehostname'

Both methods fundamentally require the same Windows security permissions:

  • SERVICE_QUERY_STATUS
  • SERVICE_START
  • SERVICE_STOP

However, they implement the security checks differently.

The Windows Service Control Manager (SCM) handles these two approaches distinctly:

# PowerShell approach (fails without proper permissions)
$svc = Get-Service -Name MyService -ComputerName myservicehostname
Stop-Service -InputObject $svc

# SC.exe approach (often succeeds with same permissions)
sc \\myservicehostname stop MyService

To make PowerShell work consistently, we need to properly configure the permissions using either subinacl.exe or the newer sc.exe sdset command:

# Using subinacl (legacy method)
subinacl.exe /service MyService /GRANT=domain\user=STO

# Modern SDDL approach
sc.exe sdshow MyService > currentSDDL.txt
# Edit the SDDL to add your user's SID with appropriate permissions
sc.exe sdset MyService [modifiedSDDL]

When direct permission modification isn't possible, consider these workarounds:

# Method 1: Using Invoke-Command
Invoke-Command -ComputerName myservicehostname -ScriptBlock {
    Stop-Service -Name MyService
    Start-Service -Name MyService
}

# Method 2: WMI approach
Get-WmiObject -ComputerName myservicehostname -Class Win32_Service -Filter "Name='MyService'" |
    ForEach-Object { $_.StopService(); $_.StartService() }
  • Verify the user has both remote access and service control rights
  • Check for firewall rules blocking RPC/DCOM traffic
  • Ensure the service isn't marked as "Disabled"
  • Confirm the service hostname resolves properly

html

When managing Windows services remotely, administrators often encounter a puzzling scenario where sc.exe commands work while PowerShell cmdlets fail with permission errors. This occurs because these tools use different underlying Windows APIs with varying security requirements.

PowerShell's Stop-Service and Start-Service cmdlets utilize the Service Control Manager (SCM) through .NET's System.ServiceProcess.ServiceController class, which requires:

1. SC_MANAGER_CONNECT (0x0001) access to SCM
2. SERVICE_STOP (0x0020) and SERVICE_START (0x0010) to the service
3. Additional query permissions for status checks

In contrast, sc.exe uses the native Windows API with different permission requirements that often align better with custom permission grants.

To make PowerShell work with your existing permissions, implement these solutions:

Option 1: Use SC.EXE Through PowerShell

Invoke-Command -ComputerName myservicehostname -ScriptBlock {
    & sc.exe stop MyService
    & sc.exe start MyService
}

Option 2: Modify Your Permission Grants

Update your subinacl command to include all required permissions:

subinacl.exe /service MyService /GRANT=MyServiceControlUser=STOPSTARTQUERY

Option 3: PowerShell Remoting Alternative

Invoke-Command -ComputerName myservicehostname -ScriptBlock {
    Stop-Service -Name MyService -Force
    Start-Service -Name MyService
}

If issues persist, verify these configuration points:

  • Windows Remote Management (WinRM) is enabled on both machines
  • PowerShell remoting is properly configured
  • The service's security descriptor includes all necessary permissions

When granting service control permissions:

- Always follow principle of least privilege
- Audit permission assignments regularly
- Consider using Group Policy Preferences for enterprise deployments
- Document all custom permission grants