Open stavros-k opened 1 year ago
@twangboy Hope this helps!
@stavros-k That's perfect! Thanks for writing this up.
I found this example (link bellow), which I hope it might be of help
Looks like with the already present modules and some small code changes the above request can be done easily, at least the execution part. Not sure how the output (eg changed values) will look like.
https://github.com/saltstack/salt/issues/50223#issuecomment-973668422
Aaand another more expanded jinja
{% for user in salt['user.list_users']() %}
{% if user not in ("DefaultAccount", "Guest", "WDAGUtilityAccount") %}
{% set sid = salt['user.getUserSid'](user) %}
{% if sid in salt['reg.list_keys']("HKEY_USERS") %}
Example Registry key {{ user }}:
reg.present:
- name: HKEY_USERS\{{ sid }}\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
- vname: HideFileExt
- vtype: REG_DWORD
- vdata: 0
{% endif %}
{% endif %}
{% endfor %}
Custom module:
def get_sids(exclude=("DefaultAccount", "Guest", "WDAGUtilityAccount")):
user_sids=[]
for user in __salt__["user.list_users"]():
if user not in exclude:
sid = __salt__['user.getUserSid'](user)
if __salt__['reg.key_exists']('HKEY_USERS', sid):
user_sids.append((user, sid))
return user_sids
#!jinja|yaml
{% for user, sid in salt['users_reg.get_sids']() %}
Example Registry key {{ user }}:
reg.present:
- name: HKEY_USERS\{{ sid }}\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
- vname: HideFileExt
- vtype: REG_DWORD
- vdata: 0
{% endfor %}
@stavros-k I have a PR adding this functionality above ^^^. I haven't written tests yet, but that's the idea. Pretty much your code.
@stavros-k I have a PR adding this functionality above ^^^. I haven't written tests yet, but that's the idea. Pretty much your code.
Thanks! I'll be able to test something after 2 weeks, as I'm on vacation. Do you think you could add the flag all_users to also apply to win_reg too?
Thanks again!
When you're logged in as administrator, can you see the other registry keys in HKEY_USERS
? They're not showing up in mine. This may not be possible.
Yes, you should be able to see keys for other users.
Here's a screenshot I just took of me connecting to a machine as an administrator and looking a another user's key:
When you're logged in as administrator, can you see the other registry keys in
HKEY_USERS
? They're not showing up in mine. This may not be possible.
This works fine for me, applies to all users. (Note that I'm running this with salt-minion installed as service, so its from SYSTEM user), but I'm pretty sure it was also working when I was testing in the target system locally, as a normal user with terminal launched as "Administrator".
{% for user, sid in salt['users_reg.get_sids']() %}
# https://answers.microsoft.com/en-us/windows/forum/all/windows-1011-touch-gesture/af9a6d19-8aa6-4d26-9693-55aa591110b3
Disable three and four finger guests (Hive -> {{ user }}):
reg.present:
- name: HKEY_USERS\{{ sid }}\Control Panel\Desktop
- vname: TouchGestureSetting
- vtype: REG_DWORD
- vdata: 0
{% endfor %}
I can get you some actual output next week if you want!
I'm trying to write tests for this. I created a test user, I logged in as that user, I see that user in user.list_users
, but I don't see the registry hive for that user in the registry in regedit, nor does salt.utils.win_reg.read_value
see it.
Ah, I see what's going on here... the hive is only loaded into HKEY_USERS if the user is logged in. Otherwise, you can't see it.
Just to clarify @twangboy I think they have to have signed in at least once in order for the key to be created. I don't think they need to be currently signed in to the machine.
@darkpixel on the machine I'm on, the hive is present only while the user is logged in. Once the user logs out, the hive is unloaded. At least on Windows 11.
I guess I'll have to do some testing on Windows 11. I don't know if the machine I connected to earlier was 10 or 11.
I know there is a group policy setting that will automatically delete profiles after a specific amount of time. Is that maybe applying to you?
On Fri, Aug 18, 2023, 17:41 Shane Lee @.***> wrote:
@darkpixel https://github.com/darkpixel on the machine I'm on, the hive is present only while the user is logged in. Once the user logs out, the hive is unloaded. At least on Windows 11.
— Reply to this email directly, view it on GitHub https://github.com/saltstack/salt/issues/64258#issuecomment-1684608730, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABGVLEM2ORMZNYM74MFIULXWADSFANCNFSM6AAAAAAX2J2UNU . You are receiving this because you were mentioned.Message ID: @.***>
@darkpixel on the machine I'm on, the hive is present only while the user is logged in. Once the user logs out, the hive is unloaded. At least on Windows 11.
Yes, thats correct.
Only logged in users are showing in the HKEY_USERS
.
Logged out users can only be manually mounted by mounting the C:\Users\<user>\ntuser.dat
as a hive.
(I'm not proposing doing that, it will be too expensive as it might be a ton of "old" users that are not pruned yet)
I guess I'll have to do some testing on Windows 11. I don't know if the machine I connected to earlier was 10 or 11.
I'm pretty sure it's the same (hive not loaded for logged out users) for W10. (Or I should say back to WinXP)
I'm not sure how useful this feature is if the user has to be logged in in order for all_users=True
to apply. Maybe I'll just document it and push it anyway... no way to really automate this test... easily...
I'm not sure how useful this feature is if the user has to be logged in in order for
all_users=True
to apply. Maybe I'll just document it and push it anyway... no way to really automate this test... easily...
For single user systems or for systems that are usually few users are logged it will be very useful. I'd imagine someone could also fire events to trigger salt's state apply on user logon.
As for testing I suppose you can login as a non admin (eg john doe
), but execute the salt process as admin and apply the all_users.
it should set the registry key in john doe
's hive.
Not familiar with the test suit and process, so I can't really help here.
I'm not sure how useful this feature is if the user has to be logged in in order for
all_users=True
to apply. Maybe I'll just document it and push it anyway... no way to really automate this test... easily...
If you apply it to the .DEFAULT
profile, new users that sign in will get it. Not entirely helpful if you are trying to apply to one specific user that hasn't signed in.
@stavros-k's template and ran into what will probably be a bigger issue. Salt is running as the SYSTEM account. The SYSTEM account apparently won't talk with AD to resolve sids.
I get pywintypes.error: (1332, 'LookupAccountName', 'No mapping between account names and security IDs was done.')
If I run it on a non-domain-joined PC it works just fine.
facepalm Sorry. I wasn't using a domain-qualified name. I was using bob
instead of domain\bob
.
I forgot to mention, I can confirm the keys only exist when the user is signed in. The reason they were showing up for my without users being signed in is due to the old Windows bug where the registry doesn't always unload properly when users sign out due to some program having a handle open to it.
Some more digging that might help... You can use the reg
command to load and unload hives that are stored in the NTUSER.DAT
file in each user's local profile directory.
Windows holds a lock on NTUSER.DAT
so if you try to open it and get an error, it means the user might already be signed in and their data is available under HKEY_USERS\S-1-5-whatever
.
I'm going to see if I can throw something together tomorrow, but here's the basic logic:
Given a state:
some_state:
reg.present:
- name: HKEY_USERS\{{ sid }}\Software\SomeProgram
- vname: SomeSetting
- vtype: REG_SZ
- vdata: foo
HKEY_USERS\{{ sid }}
exists, if so make the change and be done.HKEY_LOCAL_MACHINE
--this is important because you can create an AD account named 'bob', have him sign in, then delete the account, then create a new account named 'bob' and one would have c:\users\bob and the other would have c:\users\bob.DOMAIN).NTUSER.DAT
path, run reg load HKEY_USERS\<something> c:\users\joe\NTUSER.DAT
where something
probably shouldn't be their sid in case they happen to sign in while the state is running...not sure how Windows would handle that. Maybe stick it under HKEY_USERS\salt-reg\<pid>\username
.reg unload HKEY_USERS\salt-reg\<pid>\username
HKEY_USERS\salt-reg
and unloads everything, because Windows would probably handle a user signing in to an already-loaded and misplaced hive badly.Hacky and overly commented proof of concept:
# /srv/salt/base/_modules/hive.py
def load_hive(username):
# load hive from user profile path into HKEY_CURRENT_USER\salt-<munged-domain-and-username>
# Return the new path HKEY_CURRENT_USER\salt-<munged-domain-and-username>
# Get sids
sid = __salt__['user.getUserSid'](username)
# Check if sid exists under HKEY_USERS\{{ sid }} by looking for keys
keys = __salt__['reg.list_keys']('HKEY_USERS', sid)
if type(keys) is list:
# The user is already signed in, so the path is HKEY_USERS\{{ sid }}
return 'HKEY_USERS\%s' % (sid)
else:
# The user is not currently signed in so the hive needs to be loaded somewhere
# Find the user profile path on-disk by looking at the NT ProfileList
profile_path = __salt__['reg.read_value']('HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%s' % (sid), 'ProfileImagePath')['vdata']
# Since the path was found, load the hive into a known location. Windows won't let you load a hive anywhere other than HKCU or HKLM, so use HKCU
mount_hive = __salt__['cmd.run']('"c:\\windows\\system32\\reg.exe" load HKU\\salt-%s %s\\ntuser.dat' % (username.replace('\\', '-'), profile_path))
# Return the new path for the profile
return 'HKEY_USERS\salt-%s' % (username.replace('\\', '-'))
return None
def unload_hive(username):
# Check if HKEY_CURRENT_USER\salt-<munged-domain-and-username> exists, and unmount it.
keys = __salt__['reg.list_keys']('HKEY_CURRENT_USER', 'salt-%s' % (username.replace('\\', '-')))
if type(keys) is list:
# The hive appears to be loaded, unload it
return = __salt__['cmd.run']('reg unload HKU\\salt-%s' % (username.replace('\\', '-')))
else:
# The hive is not loaded, do nothing
return None
# reg_test.sls
{% set hive_path = salt['hive.load_hive']('domain\myuser') %}
just_testing:
reg.present:
- name: '{{ hive_path }}\test123'
- vname: test
- vtype: REG_SZ
- vdata: 'Just testing'
unload_hive:
module.run:
- hive.unload_hive:
- username: 'domain\\myuser'
Like I said, it's a bit hacky.
When I have time, I'll try to turn the module into something that mimics the reg
module functions, but works on the unloaded hives.
Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Currently both
lgpo_reg
andreg
states when dealing withuser
hives, it runs against theminion
's user context (usuallysystem
). While from a Windows perspective is kinda expected, as a salt end-user I would expect that at least thelgpo_reg
would apply to all users on the system when adding apolicy
in theuser
policy class.My actual problem is that I manage ~700 hosts (and growing) and I want to keep configuration of the users consistent (it's Kiosk machines) so it sometimes matter how the machines behave and/or look. Sadly some settings are only able to be managed either by the
user
hive registry or by manually clicking on the Settings GUI panel (I'm looking at you "disable touch gestures"). I already have minion installed as SYSTEM user that manages software etc. I wouldn't want to install a minion extra per user so it can manage theuser
reg hive.Describe the solution you'd like A clear and concise description of what you want to happen.
lgpo_reg
to check alluser
hives that the registry policies are applied to all of them. Optionallyreg
can do the same.Introduce 2 lists,
include
andexclude
that each string would be ausername
or apattern
that matches multiple usernames And check their hives underHKEY_USERS
.Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
Use
lgpo_reg
and rungpupdate /force
on schedule to ensure lgpo_reg is applied.Additional context Add any other context or screenshots about the feature request here.
User hives in
HKEY_USERS
are named after theirsid
and not the actual username.You can get the
sid
of a username with multiple ways.Please let me know if you need more info!
Please Note If this feature request would be considered a substantial change or addition, this should go through a SEP process here https://github.com/saltstack/salt-enhancement-proposals, instead of a feature request.