Search code examples
powershellwindows-servicesaccess-denieduser-permissions

Windows service fails to start up with "Error 5: Access is denied"


I am struggling with a problem here. So I've created a windows service, made the install script and registered it with Windows. I am using a custom account that I create in that same script, and give it rights to "log on as a service" using a Carbon library to be able to do so from PowerShell (described here under "Set or Grant User Logon As A Service right via Powershell")

On starting the service (both manually and through cmd), I get "Error 5: Access is denied" error. I don't understand why though, I've even tried giving the account full permissions to the whole C:\ drive.

Here's how I create the user

net user MyServiceAccount MyPassword /add /expires:never /passwordchg:no

Here's how I grant it permission to log on as a service

$Identity = "MyServiceAccount"
$privilege = "SeServiceLogonRight" 
$CarbonDllPath = $PSScriptRoot + "\Carbon.dll"
 
[Reflection.Assembly]::LoadFile($CarbonDllPath)
[Carbon.Lsa]::GrantPrivileges( $Identity, $privilege )

(Log on as service permissions seem to work, since before it failed with an error regarding that issue) I've read through a big bunch of posts on the topic, but couldn't resolve the issue. So, again, my question is: what could be causing the Access is denied error?

update

Tried to run it under administrator account (log on as...), it does the same thing - Access is denied. EventLog has nothing except the "The MonitoringService service failed to start due to the following error: Access is denied." message in System event log.


Solution

  • Ok, so I've managed to resolve my problem by using a different installation routine for the service. It appears it was a problem of installation rather than user rights related problem. Below is the example of a working script in case anyone is interested:

    # ALISE MONITORING SERVICE INSTALLATION #
    
    $service_fullname = "Alise.MonitoringService"
    $username = ".\AliseMonitoring"
    $password = "mypassword"
    $pause = 0
    $exeName = "MonitoringService.exe"
    
    $ErrorActionPreference = "Stop"
    $nl = [Environment]::NewLine
    
    $dir = Split-Path $MyInvocation.MyCommand.Path
    $service_path = join-path $dir "$exeName"
    $service_path = resolve-path $service_path
    
    
    Write-Host $nl
    Write-Host "Service name: $service_fullname" -foregroundcolor green
    Write-Host "Service logon identity: $username" -foregroundcolor green
    Write-Host "Service installation path: $service_path" -foregroundcolor green
    Write-Host $nl
    
    Write-Host "Creating user if necessary..." -foregroundcolor green
    start-process create_user.bat -Wait
    Write-Host "Granting user log on as service rights..." -foregroundcolor green
    $PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
    $Identity = "AliseMonitoring"
    $privilege = "SeServiceLogonRight" 
    $CarbonDllPath = $PSScriptRoot + "\Carbon.dll"
    [Reflection.Assembly]::LoadFile($CarbonDllPath)
    [Carbon.Lsa]::GrantPrivileges( $Identity, $privilege )
    Write-Host $nl
    
    $service = Get-WmiObject -Class Win32_Service -Filter "Name = '$service_fullname'"
    if ($service -ne $null) 
    { 
        Write-Host "Service already exists, attempting stop and delete:" -foregroundcolor green
        Write-Host "Stop service $service_fullname..."
        $service | stop-service
        Write-Host "Delete service $service_fullname..."
        $service.Delete()
        Write-Host "Service $service_fullname deleted." 
        Write-Host $nl
    }
    
    Write-Host $nl
    
    Write-Host "Registering service $service_fullname for $service_path ..." -foregroundcolor green
    New-Service -Name $service_fullname -BinaryPathName $service_path -DisplayName $service_fullname -Description "Alise monitoring serviss." -StartupType Automatic
    $service = Get-WmiObject -Class Win32_Service -Filter "Name = '$service_fullname'"
    Write-Host "Service registred."
    
    $res = sc.exe config $service_fullname obj= $username password= $password
    
    if ($LASTEXITCODE -ne 0)
    {
       Write-Host "username: $username password: $password" -foregroundcolor green
       throw $res
    }
    
    #Event log and source registration
    Write-Host $nl
    Write-Host "Registering event source Alise.MonitoringService" -foregroundcolor green
    if ([system.diagnostics.eventlog]::SourceExists("Alise.MonitoringService") -eq $false) 
    {
      [system.diagnostics.eventlog]::CreateEventSource("Alise.MonitoringService", "Alise")
      Write-Host "Created event source: Alise.MonitoringService"
    }
    else
    {
        Write-Host "Event source Alise.MonitoringService allready exists."
    }
    
    Write-Host $nl
    Write-Host "Starting service..." -foregroundcolor green
    Start-Service $service_fullname
    Write-Host "Service started!" -foregroundcolor green
    
    if ($pause -eq 1)
    {
        read-host -prompt "Press enter to exit"
    }