Jump to content

Can I modify the properties of an existing Windows service?


TheLug
 Share

Recommended Posts

  • Moderators

Short answer, yes you can.

Slightly longer answer - open command line, type sc config /? and hit enter. Happy reading :) 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Ok so I have it working with an admin CMD prompt.

sc config "RapiMgr" obj= "localsystem"

When I try to run it with AutoIt I can't get it to change the option:

$Srv1= "RapiMgr"
$obj= "localsystem"

Run (@ComSpec & " /c " & 'sc config ' & $Srv1 & ' obj= ' & $obj & "", @SW_HIDE)

I'm sure I've screwed something up with my quotes but everything else is working. What am I missing here?

Edited by TheLug
Link to comment
Share on other sites

  • Moderators

Are you running the script as an admin? Look at either #RequireAdmin at the top of your script or RunAs in the help file.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

15 hours ago, JLogan3o13 said:

Are you running the script as an admin? Look at either #RequireAdmin at the top of your script or RunAs in the help file.

Yes, running it as an admin. I added #RequireAdmin already with no change.

Playing around with RunAs but it isn't working...

 

Link to comment
Share on other sites

  • Moderators

Well 'Failed 5' is an access denied. I would take your RunWait command and try writing it to the ConsoleWrite - just to ensure the syntax is what you expect if you were typing it manually into the command line. Sometimes with a mix of vars and text you can get unintended results. After that, I would try simply writing the command out manually in your Run line, hard coding the vars, just to confirm that it is not a syntax issue. Let me know if this does not work and we can troubleshoot further.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

What @JLogan3o13 said about syntax is the most likely root cause, ConsoleWrite() is your friend.

For me, I get messed up when I am mixing "'" and '"' because my brain is muddled by age, poor eyesight, and use of a 4k display.

What I try to do is reduce the probability I will introduce an error by assembling the commands into a string then passing that to the command, something like this:

$Srv1= "RapiMgr"
$obj= "localsystem"
$s_cfgCmd = $Srv1 & " obj=" & $obj
;~ $s_cfgCmd = "RapiMgr obj=localsystem" ; or you can just hard code the whole string on one line

RunWait (@ComSpec & " /k " & "sc config " & $s_cfgCmd, @SW_SHOW)

Also:

And from my own stuff:

; --------------------------------------------------
; Check if a service exists, if it does we can then
; set service start type, where valid start types are:
; boot|system|auto|demand|disabled|delayed-auto
; --------------------------------------------------
Func _setService($service, $setting, $ScriptSource = "Set Service")
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $s_svcfound = 0
    If IsObj($objWMIService) Then
        $objQueryCollection = $objWMIService.ExecQuery("SELECT * FROM Win32_Service Where Name = '" & $service & "'")
        If IsObj($objQueryCollection) Then
            For $hObj In $objQueryCollection ;<== parse through $hObj
                If $hObj.Name = $service Then $s_svcfound = 1 ;Service found
            Next
        EndIf
    Else
        ; do some error logging here
;~         _errorLog("There was an error querying Windows services. Service settings were not performed.", $ScriptSource)
    EndIf
    If $s_svcfound = 0 Then
        ; do some info logging here
;~      _infoLog("An attempt to configure service " & $service & " to " & $setting & " was made, but the service does not exist.", $ScriptSource)
    Else ; we can modify the service as needed
        Local $s_Stop = _RunDos("sc stop " & $service) ; stop the service
        Local $s_ConfigSvc = _RunDos("sc config " & $service & " start= " & $setting) ; change the service
        If $s_ConfigSvc = 0 Then
            ; do some info logging here
;~          _infoLog("The service " & $service & " has been set to " & $setting & ".", $ScriptSource)
        Else
            ; do some error logging here
;~          _errorLog("There was an error attempting to set the service " & $service & " to setting " & $setting & ".", $ScriptSource)
        EndIf
        If $setting = "boot" Or $setting = "system" Or $setting = "auto" Or $setting = "demand" Or $setting = "delayed-auto" Then
            Local $s_Start = _RunDos("sc start " & $service) ; only to check and log if the service can run successfully
            If $s_Start = 0 Then
                ; do some info logging here
;~              _infoLog("The service " & $service & " has been started successfully.", $ScriptSource)
            Else
                ; do some error logging here
;~              _errorLog("There was an error starting the service " & $service & ".", $ScriptSource)
            EndIf
        EndIf
    EndIf
    Sleep(1000)
EndFunc   ;==>_setService

; --------------------------------------------------
; Check if a service exists and report the state
; possible returns are "Running", "Stopped", "Not found"
; --------------------------------------------------
Func _CheckService($s_ServiceName)
    Local $s_State = "Not found"
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Service WHERE Name = '" & $s_ServiceName & "'")
    If IsObj($colItems) Then
        For $objItem In $colItems
            $s_State = $objItem.State
        Next
    EndIf
    Return $s_State
EndFunc   ;==>_CheckService

 

Edited by ModemJunki
I'M BORED!

Always carry a towel.

Link to comment
Share on other sites

@ModemJunki

Since you have locate the exact service object, I would suggest using the properties and the methods of the object instead of going with SC dos command.  Here is the list of all the methods of a service object !  Quite impressive.  With these methods, you do not need to use any external programs.

Change method
ChangeStartMode method
Create method
Delete method
GetSecurityDescriptor method
InterrogateService method
PauseService method
ResumeService method
SetSecurityDescriptor method
StartService method
StopService method
UserControlService method

Link to comment
Share on other sites

30 minutes ago, Nine said:

I would suggest using the properties and the methods of the object instead of going with SC dos command

You mean, extending the ServiceControl functions? It's a good idea, but I don't know that I'm the right person for it.

Always carry a towel.

Link to comment
Share on other sites

2 hours ago, Nine said:

It is kind of straightforward - look at this

Arrrrgh! The WMI methods don't support setting Delayed Auto Start at all, but I can use them for the rest. Apparently setting the Delayed Auto can't be done with the API calls, either. It's brute-force registry or SC for that one in any case.

I did play around with it, but given the shortcoming I'll keep SC for now.

$s_Svc = "Fax"

    _changeServiceStartMode($s_Svc, "Automatic")
;~  _changeServiceStartMode($s_Svc, "Boot") ; Only for drivers
;~  _changeServiceStartMode($s_Svc, "System")  ; Only for drivers
;~  _changeServiceStartMode($s_Svc, "Manual")
;~  _changeServiceStartMode($s_Svc, "Disabled")

Func _changeServiceStartMode($service, $setting, $ScriptSource = "Set Service")
    Local $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    If IsObj($objWMIService) Then
        $objQueryCollection = $objWMIService.ExecQuery("SELECT * FROM Win32_Service WHERE NAME LIKE '%" & $service & "%'")
        If IsObj($objQueryCollection) Then
            For $hObj In $objQueryCollection ;<== parse through $hObj
                    $rtn = $hObj.changestartmode($setting) ; we need to capture the return for our return
                    ConsoleWrite("$rtn = " & $rtn & @CRLF)
            ; do some info logging here
;~          _infoLog("The service " & $service & " has been set to " & $setting & ".", $ScriptSource)
            Next
        EndIf
    Else
;~      ; do some error logging here
;~      _errorLog("There was an error querying Windows services. Service settings were not performed.", $ScriptSource)
    EndIf
EndFunc   ;==>_changeServiceStartMode

 

Always carry a towel.

Link to comment
Share on other sites

  • 1 year later...

Hi,

I need to make a script that can modify 2 windows services ( "RapiMGR" and "WcesComm") from a non-elevated account (standard) and I'm stuck at how to make it work without the user of the standard account to know the password of the Administrator account.
Or to provide them the password, but the script only to ask for password without displaying the account for which they provide this password.

This is what I have done so far, it works if command prompt has administrator rights:

sc stop "RapiMgr"
sc config "RapiMgr" obj= "localsystem" type= own type= interact
sc start "RapiMgr"

sc stop "WcesComm"
sc config "WcesComm" obj= "localsystem" type= own type= interact
sc start "WcesComm"

Link to comment
Share on other sites

As an alternative to "safely" granting admin rights, you might be able to grant permissions to the specific services to allow non admin users to modify the service.

Check out the links in this thread I made years ago where I was able to grant non-admins rights to remotely restart a print spooler service.

It's been a hot minute since I messed with service permissions, but feel free to ask me questions if you get stuck and I'll try my best to help.

 

More info here:
https://docs.microsoft.com/en-us/windows/win32/services/service-security-and-access-rights

Also, here is another general guide:
https://cqureacademy.com/blog/windows-internals/sddl

Edited by spudw2k
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...