Solved

ManagementObject.SetPropertyValue fails to change Service property

Posted on 2008-10-17
11
1,624 Views
Last Modified: 2012-05-05
I am using System.Management.ManagementObject in VB.NET to change the "StartName" property of a service.  If I check the property in the program immediately after changing it to "LocalSystem" it appears to have been changed.  Yet once I exit the program and check the service via the "Services" utility, the property has not changed.  Is there some programmatic "commit" required, or perhaps (heaven forbid) a reboot?

Thanks for any help!
0
Comment
Question by:rberrett
  • 4
  • 4
11 Comments
 
LVL 27

Expert Comment

by:Dabas
ID: 22751691
Hello rberrett,

Can you please post your code as a snippet?

Regards,

Dabas
0
 

Author Comment

by:rberrett
ID: 22760400
I've attached it here.  I tried doing the "Put" in hopes that was my problem, but it still doesn't change the "StartName" property.  Thanks for any help.
Imports System.ServiceProcess

Imports System.Management
 

Module Module1

    'Public Shared Function GetServices() As ServiceController()

    Sub Main()

        Dim scServices() As ServiceController

        scServices = ServiceController.GetServices()
 

        ' Loop through services currently running on this computer.

        Console.WriteLine("Local Computer Services :")
 

        Dim scTemp As ServiceController

        For Each scTemp In scServices
 

            'If scTemp.Status = ServiceControllerStatus.Running Then

            If scTemp.DisplayName = "ClipBook" Then

                ' Write the service name and the display name

                ' for each running service.

                Console.WriteLine()

                Console.WriteLine("  Service :        {0}", scTemp.ServiceName)

                Console.WriteLine("    Display name:    {0}", scTemp.DisplayName)
 

                ' Query WMI for additional information about this service.

                ' Display the start name (LocalSytem, etc) and the service

                ' description.

                Dim wmiService As ManagementObject

                wmiService = New ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'")

                wmiService.Get()

                Console.WriteLine("    Start name:      {0}", wmiService("StartName"))

                Console.WriteLine("    Description:     {0}", wmiService("Description"))

                'Console.WriteLine("    StartPassword:     {0}", wmiService("StartPassword"))

                wmiService.SetPropertyValue("StartName", "LocalSystem")

                'wmiService.SetPropertyValue("StartPassword", "")

                Console.WriteLine("    Start name2:      {0}", wmiService("StartName"))

                Dim PutOptionsVal As PutOptions = New PutOptions

                PutOptionsVal.Type = PutType.UpdateOnly

                wmiService.Put(PutOptionsVal)

            End If
 

        Next scTemp
 

    End Sub
 

End Module

Open in new window

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22845885
My first thought is that you might need to remove the service (from the Service Manager's internal database) and then add it back using the new name.
However, I then saw this:

   Service Login -- API to Change it?
   http://bytes.com/forum/thread236775.html
It seems that there is a method (as opposed to a property) that you can use to affect this change.
    Change Method of the Win32_Service Class
    http://msdn.microsoft.com/en-us/library/aa384901(VS.85).aspx
0
 

Author Comment

by:rberrett
ID: 22870314
Thanks for the info!  Unfortunately when I try doing the change to "StartName" it still doesn't work (see snippet).  However, now I at least get a return value.  The value returned is 22 which is "Invalid Service Account".  So I tried using other account names and it always returns 22 unless I just try to change to the current account in which case it returns 0.  So I guess I may have a little more insight but still no luck.  When I used my previous code then check the value immediately after it appeared to have changed, but upon program exit it really had not changed.  With this code using a method it just errors (22) and when I check has not changed even temporarily.  Any further ideas? (thanks again for the help thus far)

Imports System.ServiceProcess

Imports System.Management
 
 

Module Module1

    'Public Shared Function GetServices() As ServiceController()

    Sub Main()

        Dim scServices() As ServiceController

        Dim inParams As ManagementBaseObject

        Dim options As New InvokeMethodOptions

        Dim returnValue As ManagementBaseObject
 

        'Dim svrc As New ManagementObject("\\.\root\cimv2")

        'inParams = svrc.GetMethodParameters("Change")

        'inParams("StartName") = "LocalService"
 
 

        scServices = ServiceController.GetServices()
 

        ' Loop through services currently running on this computer.

        Console.WriteLine("Local Computer Services :")
 

        Dim scTemp As ServiceController

        For Each scTemp In scServices
 

            'If scTemp.Status = ServiceControllerStatus.Running Then

            If scTemp.DisplayName = "ClipBook" Then

                ' Write the service name and the display name

                ' for each running service.

                Console.WriteLine()

                Console.WriteLine("  Service :        {0}", scTemp.ServiceName)

                Console.WriteLine("    Display name:    {0}", scTemp.DisplayName)
 

                ' Query WMI for additional information about this service.

                ' Display the start name (LocalSytem, etc) and the service

                ' description.

                Dim wmiService As ManagementObject

                wmiService = New ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'")

                wmiService.Get()

                Console.WriteLine("    Start name:      {0}", wmiService("StartName"))

                Console.WriteLine("    Description:     {0}", wmiService("Description"))
 

                ''Console.WriteLine("    StartPassword:     {0}", wmiService("StartPassword"))

                'wmiService.SetPropertyValue("StartName", "LocalSystem")

                ''wmiService.SetPropertyValue("StartPassword", "")

                'Console.WriteLine("    Start name2:      {0}", wmiService("StartName"))

                'Dim PutOptionsVal As PutOptions = New PutOptions

                'PutOptionsVal.Type = PutType.UpdateOnly

                'wmiService.Put(PutOptionsVal)
 

                inParams = wmiService.GetMethodParameters("Change")

                inParams("StartName") = "LocalSystem"

                returnValue = wmiService.InvokeMethod("Change", inParams, options) 'System.Management.InvokeMethodOptions.InfiniteTimeout)

                Console.WriteLine("    ReturnValue:     {0}", System.Convert.ToInt32(returnValue.Properties("ReturnValue").Value))

                Console.WriteLine("    Start name:      {0}", wmiService("StartName"))

                'Dim svrc As New ManagementObject("\\.\root\cimv2")

                'inParams = svrc.GetMethodParameters("Change")

                'inParams("StartName") = "LocalService"
 

            End If
 

        Next scTemp
 

    End Sub
 

End Module

Open in new window

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 49

Expert Comment

by:DanRollins
ID: 22871649
There might be underlying constraints; for instance, different parts of the system probably cache service names and have no direct way to update the cache -- short of a system reset.  
In general, the system probably assumes that a service will never change its name once it has been added to the Service Manager's database -- why should it?  
Of course, any service that has a dependancy of any kind would not be a good target for testing.   For instance, lots of subsystems might depend on a service named "ClipBook".  I suggest testing using a very simple Service that no other systems use.
One other thought:  In your code, you are cycling though the services and then changing one of them.  If WMI queries are similar to DBMS queries, then you have an "open recordset" which could cause failure of an update.  What if you omit the looping and just get the one record and invoke it's Change function?
0
 

Author Comment

by:rberrett
ID: 22900410
Thanks for the ideas.  The property I'm trying to change is actually the "StartName" which is the account under which the service starts.  I tried a different service (with no dependencies) and also to excute the change directly rather than in the loop, but unfortunately I get the same result.

I think the issue may lie in the "Invalid Service Account" error, but I can't seem to find out just why I get that error.  I've tried several accounts, as well as the string "LocalSystem", all to no avail.

Anyway, any further ideas would be appreciated!  This is a tough one.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22914470
Invalid Service Account
The account which this service is to run under is not valid, or it lacks the permissions to run the service.
Can you use manual means to do this?  For instance, use the ControlPanel Services applet or
   net stop (et. al)
or the
   SC
command to change service settings using your current login?  I know I can, but I use an administrative account when doing these things.
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 500 total points
ID: 22914488
Another thought:  Notice the different syntac used in the Change() function on this page of examples:
http://msdn.microsoft.com/en-us/library/aa394602(VS.85).aspx

Use the Win32_Service class and the Change method. 
 

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

    & "{impersonationLevel=impersonate}!\\" _

    & strComputer & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _

    ("Select * from Win32_Service")

For Each objservice in colServiceList

    If objService.StartName = ".\netsvc" Then

        errReturn = objService.Change( , , , , , , , "password")  

    End If 

Next

Open in new window

0
 

Author Comment

by:rberrett
ID: 22935845
That last thing, modified to change the StartName, did the trick!  It took me a bit to realize I need to run it as a vbscript with "cscript" but that seems to work.  Thank you, thank you!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Linq Help 1 35
Need to pass a connection through class/Method 1 39
Allow User To Arrange Columns At Datagridview 3 19
Help with LINQ and XML 10 26
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now