How do I determine which services are running and which ones are not?
Use the Win32_Service class to check the state of all of the services. The state property lets you know if a service is stopped or running.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT Name, State FROM Win32_Service','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Name %s',[String(FWbemObject.Name)]));// String Writeln(Format('State %s',[String(FWbemObject.State)]));// String Writeln; FWbemObject:=Unassigned; end; end;
How do I stop Power Users from starting certain services?
Use the Win32_Service class and the ChangeStartMode method to set the StartMode property to Disabled. Disabled services cannot be started, and, by default, Power Users cannot change the start mode of a service.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Service where StartMode = "Manual"','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin FWbemObject.Change( varEmpty, varEmpty, varEmpty, varEmpty, 'Disabled'); FWbemObject:=Unassigned; end; end;
How do I start and stop services?
Use the Win32_Service class and the StopService and StartService methods.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Service where Name = "Alerter"','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; if oEnum.Next(1, FWbemObject, iValue) = 0 then FWbemObject.StartService(); end;
How do I change service account passwords?
Use the Win32_Service class and the Change method.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Service where StartName = ".\netsvc"','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; if oEnum.Next(1, FWbemObject, iValue) = 0 then FWbemObject.Change( varEmpty, varEmpty, varEmpty, varEmpty, varEmpty, varEmpty, varEmpty, 'password'); end;
How do I determine which services I can stop?
Use the Win32_Service class, and check the value of the AcceptStop property.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Service where AcceptStop = True','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Name %s',[String(FWbemObject.Name)]));// String FWbemObject:=Unassigned; end; end;
How do I find the services that must be running before I can start the DHCP service?
Query for ASSOCIATORS OF the Win32_Service class named “DHCP” that are in the Win32_DependentService class and have “Dependent” in the Role property. Role means the role of the rasman service: in this case, it is antecedent to—must be started before—the dependent services.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('Associators Of {Win32_Service.Name="dhcp"} Where AssocClass=Win32_DependentService Role=Dependent','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('%s - %s',[String(FWbemObject.Name),String(FWbemObject.DisplayName)]));// String FWbemObject:=Unassigned; end; end;
How do I find the services that require the WMI service (Winmgmt) service to be running before they can start?
Query for ASSOCIATORS OF the Win32_Service class named “winmgmt” that are in the Win32_DependentService class and have “Antecendent” in the Role property. Role means the role of the rasman service: in this case, it is antecedent to—must be started before—the dependent services.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('Associators of {Win32_Service.Name="winmgmt"} Where AssocClass=Win32_DependentService Role=Antecedent','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('%s - %s',[String(FWbemObject.Name),String(FWbemObject.DisplayName)]));// String FWbemObject:=Unassigned; end; end;
This post is based in the MSDN Entry WMI Tasks: Services
November 17, 2011 at 4:51 am
Thanks for your work.
Currently I use nothing of this information at all but it gives me good feeling to know what I can do with Delphi and WMI and to know the place where I can find all of this informations.
January 1, 2012 at 6:30 pm
Great Blog Rodrigo!
Just wondering if you’d be able to do a writeup or post on how to seperate multiple values from a WMI query into seperate strings.
For example, in a system with more than 1 RAM Module installed (root\cimv2\PhysicalMemory), being able to read the “Capacity” values, and seperate each return value/result into seperate strings (one string for each result). There’s a great many uses i can think of for this especially regarding hardware information (Multiple Video Card, Multi CPU/Multicore, Multiple Drives, etc).
I apologise that this isn’t directly related to this post, but i wanted to contact you via twitter (unfortunately, the character limit can be a hassle at times).
Keep up the good work either way!
January 1, 2012 at 9:15 pm
Scott, sorry but I don’t understand your question, anyway are you tried using the delphi wmi class generator http://code.google.com/p/delphi-wmi-class-generator/ or the wmi delphi code creator http://code.google.com/p/wmi-delphi-code-creator/?
January 2, 2012 at 1:16 pm
Hi. I did try both those tools, and both are great but i don’t see a way to achieve what i’m trying to do.
If i use the following code for example, in a system with 3 graphics cards, i get 3 values returned (in this case, 3 message boxes from ShowMessage). What i want to do is be able to do is put each value to a seperate string;
var
Locator: ISWbemLocator;
Services: ISWbemServices;
ObjSet: ISWbemObjectSet;
SObject: ISWbemObject;
PropSet: ISWbemPropertySet;
SProp1 : ISWbemProperty;
sValue1 : String;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
TmpInt : Integer;
begin
Locator:= CoSWbemLocator.Create;
Services:= Locator.ConnectServer(‘.’, ‘root\cimv2’, ”, ”, ”,”, 0, nil);
ObjSet:= Services.InstancesOf(‘Win32_VideoController’, wbemFlagReturnWhenComplete, nil);
Enum:= (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, tempObj, Value) = S_OK) do begin
SObject:= IUnknown(tempObj) as SWBemObject;
PropSet := SObject.Properties_;
SProp1:= PropSet.Item(‘AdapterRAM’,0);
sValue1:= SProp1.Get_Value;
TmpInt := StrToInt(sValue1);
ShowMessage(IntToStr(TmpInt div 1048576) + ‘ Mb VRAM’);
end;
end;
January 2, 2012 at 10:59 pm
Scott, your question is more related to delphi collections than to the WMI, you can use a TList or even a StringList to store the values returned by you WQL sentence and then use as you want.