How to change windows service account password

Hello everyone,
I am trying to change the password of a windows server service account. I eventually saw that I can call wmi to do this but it is not working for me. Can anyone see what I am missing? Is there a better way to do this?

Thanks,
Leslie

Code below.

import wmi
import getpass
import subprocess
import sys

c = wmi.WMI()

username = str.casefold("maria")
pwd = getpass.getpass()
services = list()

def Find_Service(username, pwd):
    for s in c.Win32_Service():
        if username in str.casefold(str(s.StartName)):
            print (str(s.Name))
            change_CMD = ("(, , , , , , , ")
            passwd = ( "'" + pwd + "')")
            print (change_CMD + passwd)
            print (s)
            s.Change(change_CMD + passwd)
            

Find_Service(username, pwd)

The error i get is:

Traceback (most recent call last):
  File "C:\Users\lmaclachlan\AppData\Local\Programs\Python\Python310\lib\site-packages\wmi.py", line 440, in __call__
    parameter.Value = arg
  File "C:\Users\lmaclachlan\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 686, in __setattr__
    self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'SWbemProperty', 'Type mismatch ', None, 0, -2147217403), None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\lmaclachlan\OneDrive - Unitec IT Solutions\Documents\dev\services.py", line 22, in <module>
    Find_Service(username, pwd)
  File "C:\Users\lmaclachlan\OneDrive - Unitec IT Solutions\Documents\dev\services.py", line 19, in Find_Service
    s.Change(change_CMD + passwd)
  File "C:\Users\lmaclachlan\AppData\Local\Programs\Python\Python310\lib\site-packages\wmi.py", line 473, in __call__
    handle_com_error()
  File "C:\Users\lmaclachlan\AppData\Local\Programs\Python\Python310\lib\site-packages\wmi.py", line 258, in handle_com_error
    raise klass(com_error=err)
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147352567, 'Exception occurred.', (0, 'SWbemProperty', 'Type mismatch ', None, 0, -2147217403), None)>

Hi,
I have cut down the code to only work on 1 service account.
I now get a different error:

import wmi

c = wmi.WMI()
pwd = "blah"

for s in c.win32_Service(Name="MariaDB"):
    print(s.Name)
    change_CMD = ("(, , , , , , , ")
    passwd = ( "'" + pwd + "')")
    to_Change = (str(change_CMD + passwd))
    result = s.change(to_Change)

Error:
TypeError: ‘int’ object is not callable

The username and password of a service can be configured easily from the command line using the classic “sc.exe” application. For example:

sc.exe config <service name> obj= <username> password= <password>

Note that sc requires command-line options exactly of the form name= value, such as obj= spam and password= eggs. The way it parses the command line is extremely unforgiving. Also, usernames need to be in “domain\name” form, such as “.\maria”.

Nowadays most scripted system administration uses PowerShell. Credential support was added to the set-service cmdlet in PowerShell 6+ (i.e. “pwsh.exe”). I’m not the most adept with PowerShell, but the following seems to get the job done:

$cred = get-credential
foreach ($svc in get-service | where {$_.UserName -eq $cred.UserName}) {set-service -name $svc.Name -credential $cred}

Hi Eryk,
Thanks for the reply. I will take a look at this; may be the best option.

Regards,
Leslie

I wanted to get the ‘easy’ ways covered first. It’s relatively simple to use subprocess to run an “sc.exe” or “pwsh.exe” command. I’ll look into using the WMI Win32_Service Change() method in Python. Personally, I’d use the Windows service API via ctypes. It’s more work, but it avoids depending on the PyWin32 and wmi packages.