Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Getting the Win10 service name "suffix"

May
12,845
164
On Win10, some services, I imagine those which need user-specific instances, are created on the fly (maybe at login?). The names of those services have a "suffix" which I suppose identifies the user ... like these (just to name a few).
Code:
AarSvc_646c6
BcastDVRUserService_646c6
BluetoothUserService_646c6
CaptureService_646c6

I want to get that suffix. I can do it somewhat crudely like this.
Code:
v:\> function svcsuffix `%@word["_",1,%@execstr[wmiquery /a . "select Name from Win32_Service" | ffind /k /m /e"_[0-9a-f]+$"]]`

v:\> echo %@svcsuffix[]
646c6

Does anyone have any better ideas?
 
Hmmm! I can put it in a variable (instead of a function) and after Googling SQL's "LIKE" keyword I can make it a little shorter and avoid the pipe.
Code:
v:\> set _svcsuffix
%@word["_",1,%@wmi[.,"select Name from Win32_Service where name like 'AarSvc_%%'"]]

v:\> echo %_svcsuffix
646c6

But I'd still like ideas. As far as I know this "suffix" only appears in service names (registry and WMI). I can also dig it out of REGDIR's output (with a pipe) but that's less elegant than what's above.
 
The suffix is called the _LUID, which is the locally unique identifier.

Here's a method to obtain it using PowerShell;

Code:
Get-Service '*_*' | Select-Object Name | ForEach-Object { $_.Name.Split('_')[-1] } | Group-Object | Sort-Object Count -Descending | Select-Object -First 1 -ExpandProperty Name

...although there must be an easier method.

Joe
 
Last edited:
Here it is as a TCC Function;
Code:
function luid=`%@pshell[Get-Service '*_*' | Select-Object Name | ForEach-Object { $_.Name.Split('_')[-1] } | Group-Object | Sort-Object Count -Descending | Select-Object -First 1 -ExpandProperty Name`]
Code:
e:\utils>echo %@luid[]
77aef

Joe
 
Very interesting, Joe. Can you explain how it works?

Something strange ... the first two times I use that function in a new instance of TCC, it fails, then works.
Code:
v:\> echo %@luid[]
PSHELL: System.Management.Automation.PSInvalidOperationException : The pipeline was not run because a pipeline is already running. Pipelines cannot be run concurrently.

v:\> echo %@luid[]
646c6
And it continues to work in that instance of TCC. Any ideas? ... maybe one for Rex?

I also noticed that using @PSHELL to do that doesn't seem, on the surface, to use WMI ... at least, it doesn't cause the creation of a temporary (90-second timeout) instance of WMIPRVSE.EXE. TCC's WMIQUERY and @WMI both cause the creation of such an instance of WMIPRVSE.EXE; so does starting FireFox or the WmiCodeGenerator. Any ideas?
 
Never mind how it works. I figured that out by building it pipe by pipe in PowerShell.
 
When I get a list of the Services thus;
Code:
PS E:\utils> $Services = Get-Service '*_*'
PS E:\utils> $Services

Status   Name               DisplayName
------   ----               -----------
Stopped  AarSvc_7a7bf       Agent Activation Runtime_7a7bf
Stopped  BcastDVRUserSer... GameDVR and Broadcast User Service_...
Stopped  BluetoothUserSe... Bluetooth User Support Service_7a7bf
Stopped  CaptureService_... CaptureService_7a7bf
Running  cbdhsvc_7a7bf      Clipboard User Service_7a7bf
Running  CDPUserSvc_7a7bf   Connected Devices Platform User Ser...
Stopped  ConsentUxUserSv... ConsentUX_7a7bf
Stopped  CredentialEnrol... CredentialEnrollmentManagerUserSvc_...
Stopped  DeviceAssociati... DeviceAssociationBroker_7a7bf
Stopped  DevicePickerUse... DevicePicker_7a7bf
Stopped  DevicesFlowUser... DevicesFlow_7a7bf
Running  jhi_service        Intel(R) Dynamic Application Loader...
Running  LxssManagerUser... LxssManagerUser_7a7bf
Stopped  MessagingServic... MessagingService_7a7bf
Running  OneSyncSvc_7a7bf   Sync Host_7a7bf
Stopped  PimIndexMainten... Contact Data_7a7bf
Stopped  PrintWorkflowUs... PrintWorkflow_7a7bf
Running  ss_conn_service    SAMSUNG Mobile Connectivity Service
Stopped  UnistoreSvc_7a7bf  User Data Storage_7a7bf
Stopped  UserDataSvc_7a7bf  User Data Access_7a7bf
Running  WpnUserService_... Windows Push Notifications User Ser...

Then, when I look at the ServiceType for each of the Services;
Code:
PS E:\utils> $Services.ServiceType
224
224
224
224
240
240
224
208
224
224
224
Win32OwnProcess
240
224
224
224
224
Win32OwnProcess
224
224
240

..the number 224 seems to come up quite often.

Not sure what a ServiceType of 224 is exactly.

Joe
 
224 includes 64 and 128 and 32. 32 is Win32ShareProcess. I can't find documentation on 64 or 128.

This works in PowerShell.
Code:
V:\> get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | select-object -first 1

646c6
But the "select-string" introduces an initial newline in the output (why?). That makes it a little hard to wrap up in TCC.
Code:
V:\> echo foo
foo

V:\> echo foo | select-string -Pattern 'f.o'

foo
 
Try this;
Code:
(get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | select-object -first 1 | out-string).trim()

Joe
 
Try this;
Code:
(get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | select-object -first 1 | out-string).trim()

Joe
Thanks. That works but it seems a bit much to correct something that (IMHO) shouldn't happen in the first place!
 
Well, you could also do;
Code:
get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1
...which gives the same result.

Select-String outputs MatchInfo Class objects, not strings.

Joe
 
When I tried that using PSHELL, it returns;
Code:
e:\utils>pshell /s "get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1"
PSHELL: System.Management.Automation.ParseException : At line:1 char:122
+ ... )[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | {$_.Line} | selec ...
+                                                         ~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.

The solution was to put the command into a .PS1 file, and then call the .PS1 file using PSHELL;
Code:
e:\utils>pshell luid.ps1
7a7bf

e:\utils>echo %@pshell[luid.ps1]
7a7bf

Joe
 
Well, you could also do;
Code:
get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1
...which gives the same result.

Select-String outputs MatchInfo Class objects, not strings.

Joe
It does OK matching the text. Does that explain the leading blank line?
 
When I tried that using PSHELL, it returns;
Code:
e:\utils>pshell /s "get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1"
PSHELL: System.Management.Automation.ParseException : At line:1 char:122
+ ... )[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | {$_.Line} | selec ...
+                                                         ~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.

The solution was to put the command into a .PS1 file, and then call the .PS1 file using PSHELL;
Code:
e:\utils>pshell luid.ps1
7a7bf

e:\utils>echo %@pshell[luid.ps1]
7a7bf

Joe
You can also just double the '%'.
Code:
v:\> pshell /s "get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] } | select-string -Pattern '^[0-9a-f]{5,}$' | %%{$_.Line} | select-object -first 1"
646c6
 
Yeah, I should have remembered the double % signs. Thanks.

Here's an example, showing what gets returned by select-string;
Code:
PS E:\utils> $j = ("One","Two","Three")
PS E:\utils> $j | select-string "One"

One


PS E:\utils> $j.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


PS E:\utils> $j = ("One","Two","Three") | select-string "One"
PS E:\utils> $j

One


PS E:\utils> $j.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    MatchInfo                                System.Object


PS E:\utils> $j = ("One","Two","Three") | select-string "One" | % {$_.Line}
PS E:\utils> $j
One
PS E:\utils> $j.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Thus, you have to cast the return type of the Object as a string to eliminate the leading blank line.

Joe
 
To wrap it in @PSHELL you have to double the '^' and not the '%'.
Code:
v:\> echo %@pshell[get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] }  | select-string -Pattern '^^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1]
646c6

To put it in a function, quadruple the '^'.
Code:
v:\> function zz `%@pshell[get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] }  | select-string-Pattern '^^^^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1]`

v:\> function zz
%@pshell[get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] }  | select-string -Pattern '^^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1]

v:\> echo %@zz[]
646c6

Ditto (apparently) for a variable.
Code:
v:\> set zz=`%@pshell[get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] }  | select-string -Pattern '^^^^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1]`

v:\> set zz
%@pshell[get-service | select-object Name | ForEach-Object { $_.Name.Split('_')[-1] }  | select-string -Pattern '^^[0-9a-f]{5,}$' | %{$_.Line} | select-object -first 1]

v:\> echo %zz
646c6

I wish I understood all this!
 
Placing the PowerShell commands into a .PS1 file, you do not have to make those changes, thus, you can call the .PS1 using @PSHELL, and call the .PS1 from a PowerShell command prompt.
Code:
e:\utils>echo %@pshell[luid.ps1]
7a7bf
Code:
PS E:\utils> .\luid.ps1
7a7bf

No changes to the code.

There are just too many quirks with the NSoftware PowerShell product, especially that
Code:
The pipeline was not run because a pipeline is already running.
error, as that is an error I get the majority of the time.

I find things work much better by just putting the code in a .PS1 file, and calling that .PS1 file using PSHELL or @PSHELL.

Joe
 
In Powershell:

Code:
PS C:\> get-service *_* | Where ServiceType -eq 224 | select -first 1 | % {$_.Name -creplace ('^.*_','')}
3a90a
PS C:\>

( -creplace is Powershell's regex search/replace (s/old/new/g )
 
Nice one, Maarten! Do you know of any documentation on service type 224?
 
Yes, that means "USER_SHARE_PROCESS INSTANCE"
(from the following command run against one of the user services; 224 (dec) = E0 (hex) )

Code:
PS C:\> sc.exe qc OneSyncSvc_3a90a
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: OneSyncSvc_3a90a
TYPE : e0 USER_SHARE_PROCESS INSTANCE
START_TYPE : 2 AUTO_START (DELAYED)
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : C:\WINDOWS\system32\svchost.exe -k UnistackSvcGroup
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Sync Host_3a90a
DEPENDENCIES :
SERVICE_START_NAME :
PS C:\>
 
TYPE : e0 USER_SHARE_PROCESS INSTANCE
There should be three in there since E0 is 80 + 40 +20 ... ?

While I have the attention of PowerShell experts, how do I get the colors to ALWAYS be the same? Below the one in the background was started from TCC with "START PowerShell". The one in the foreground was started from WinKey-R ... PowerShell. They even have different captions.
2338


This one (below) was started from simply the start button (type Power and "best match" shows PowerShell ... click it. It has a different size and font.
2339
 
I fixed the discrepancies among the three ways of starting PowerShell by, in turn, for each of the three, going to the console's properties and setting the colors and font. That said, I don't know where the different settings were coming from in the first place because both before and after my changes, I had only ONE x64 PowerShell key in HKCU\Console. This (below) is after the changes.
Code:
v:\> regdir /t hkcu\console
2019-06-10 21:22 hkcu\console
2019-06-06 23:47  SystemRoot_system32_cmd.exe
2019-06-10 21:34  SystemRoot_System32_WindowsPowerShell_v1.0_powershell.exe
2019-06-06 23:37  SystemRoot_SysWOW64_WindowsPowerShell_v1.0_powershell.exe
2019-06-06 23:47  c:_apps_tc23_tcc.exe
2019-06-10 21:18  c:_apps_tc24_tcc.exe
2019-06-06 23:47  g:_tc23_tcc.exe
2019-06-06 23:47  G:_TC24_TCC.EXE
 
There should be three in there since E0 is 80 + 40 +20 ... ?
Why? A service can be just of one type. Those are not flags/attributes.


BTW: I guess you need this because you want to stop those services from running?
In that case you can configure the matching template service not to "spawn" a userservice.

Example for the OneSyncSvc_3a90a userservice with matching template service OneSyncSvc

From an elevated prompt:
Code:
reg.exe ADD "HKLM\SYSTEM\CurrentControlSet\Services\OneSyncSvc" /v UserServiceFlags /t REG_DWORD /d 0 /f


Note: this will disbale the user service for all users.
 
Back
Top