I am trying lock the workstation during a play while installing Windows Updates and doing some maintenance activities for an application.
This is a highly sensitive and regulated environment.
At the moment we are looking at two use cases, one where the process is manually initiated by the user.
I have done this through a handler (still new to Ansible).
Once this step happens I would require the workstation to be locked to avoid any potential user interference.
In the past I have done other projects with the help of MDT (HideShell, DisableTaskMgr) Task Sequences but this project requires much more, hence we are evaluating Ansible.
I have also tried to start the rundll method through a script (PowerShell and Batch) but I simply cannot get the function to work.
The playbook runs through with changed=1 but the workstation remains unlocked.
I am sure I am overlooking something (I apologize upfront for stupid mistakes as Ansible is really new for me).
You are delving deep into Windows stations and desktops [1] and the solution won’t be too pretty. When using WinRM, the service that spawns the initial process is located in session 0 which means our Ansible process is also in session 0. The docs for LockWorkStation [2] indicates that it will only work when you call it from the interactive desktop of the session you want to lock. In Windows station/desktop speak this would be on the station ‘WinSta0’ and the ‘Default’ desktop for the user’s session.
To see what session, station, and desktop a process is associated with, you can run the ‘Get-ProcessSessionStationAndDesktop’ function at [3]. Here is the result in various permutations in Ansible;
Plain WinRM
Can Lock: No
Session: 0
Station: Service-0x0-b66125$
Desktop: Default
Become with password
Can Lock: No
Session: 0
Station: Service-0x0-b68e5a$
Desktop: Default
Become without password and impersonation (2.8+)
Can Lock: No
Session: 0
Station: Service-0x0-b6d2ae$
Desktop: Default
PsExec
Can Lock: No
Session: 0
Station: Service-0x0-b717bc$
Desktop: Default
PsExec with credentials
Can Lock: No
Session: 0
Station: Service-0x0-b74e19$
Desktop: Default
PsExec interactive
Can Lock: No
Session: 0
Station: Service-0x0-b78771$
Desktop: Default
PsExec interactive with credentials
Can Lock: No
Session: 0
Station: Service-0x0-b7bc74$
Desktop: Default
PsExec explicit interactive session
Can Lock: No
Session: 2
Station: WinSta0
Desktop: Default
PsExec explicit interactive session with credentials
Can Lock: Yes
Session: 2
Station: WinSta0
Desktop: Default
Only PsExec with an explicit interactive session id that matches the session we want to lock is the only scenario that worked. I’ve found that the credentials you use doesn’t have to be the user who created the session, just one that can spawn the process in that session. By process of elimination it seems like you need to meet the following criteria to be able to lock a session;
The station and desktop must be set to ‘WinSta0\Default’. This is not something you can do currently with become but it’s quite trivial to add the code
Start the process in the session that needs to be locked. This is not something you can do in Ansible, and from a brief attempt it isn’t trivial to add. This is why PsExec is the only solution that works
The process must be spawned from an interactive logon type, this is why only PsExec with explicit credentials works
Point 3 is already possible as that is what become currently does, point 1 is easy to implement but when playing around with this point 2 seems to be a lot more complex. PsExec shows that this is possible to do and possibly something that would be added to become sometime in the future but currently it’s not something you can do in become right now.
While it is possible to do this it’s not something you should rely on because;
Once you’ve locked a user’s session there is nothing to stop them from just unlocking it
You need to enumerate the actual system sessions, this isn’t hard but it’s not something that’s built into Ansiblw
Much appreciated, Thank you!
I will think about it and also bring it up in the next Stakeholder Meeting to gather feedback.
May I ask if you would know of any other way (if you would have such a use case where you need to prevent user input at all during the patching process)?