icinga-powershell-plugins icon indicating copy to clipboard operation
icinga-powershell-plugins copied to clipboard

Invoke-IcingaCheckUsers should not count service/computer accounts

Open Mikesch-mp opened this issue 5 years ago • 11 comments
trafficstars

Hello,

right now the commands also counts service and cimputer accounts as logged in users and also a logged inuser multiple times even if he is logged in only once.

Iam not used to Powershell, but maybe this will help on how to get the user count correctly https://thesysadminchannel.com/get-logged-in-users-using-powershell/

Given on a test machine arte this users logged in: grafik

Invoke-IcingaCheckUsers:

PS C:\Users\Administrator> Invoke-IcingaCheckUsers
[OK] Check package "Users"
| 'logged_on_users_umfd2'=1;; 'logged_on_users_umfd4'=1;; 'logged_on_users_umfd0'=1;; 'logged_on_users_system'=1;; 'logged_on_users_umfd3'=1;; 'logged_on_users'=16;; 'logged_on_users_dwm3'=1;; 'logged_on_users_dwm4'=1;; 'logged_on_users_dwm2'=1;; 'logged_on_users_test'=3;; 'logged_on_users_lokaler_dienst'=1;; 'logged_on_users_administrator'=3;; 'logged_on_users_netzwerkdienst'=1;;

Get-LoggedInUser:

ComputerName UserName      SessionID SessionState
------------ --------      --------- ------------
VM35297      administrator 3         Aktiv
VM35297      test          4         Aktiv

Also iam not a windows administrator, so maybe remote powershell oder remote shell should also be testet, but for sure not system/service accounts

Best regards, Carsten

Mikesch-mp avatar Nov 16 '20 10:11 Mikesch-mp

Thank you for the issue. Actually this check depends a lot on user permissions. If you are running the plugin with Administrative privileges, you will receive every single user on the system. If you are using a default user or the NT Authority\NetworkService (Icinga Agent default) you will receive a lot fewer users because you are not having the permission to check who is actually running.

So this depends on the user running the command in general and I'm already aware of users who found the detailed about while running as admin very useful

LordHepipud avatar Nov 16 '20 16:11 LordHepipud

Hi,

would it be possible to enhance the check plugin with some kind of a filter? I have a use case where I am interested in the logged in users, but only where the session is active (and not disconnected).

Best regards Michael

mcktr avatar Nov 17 '20 07:11 mcktr

I think something like this should be possible. I will have a look on this a created a PR once ready. In case there is a "quick" solution I will add this with v1.3.0 then.

I will keep you posted!

LordHepipud avatar Nov 17 '20 08:11 LordHepipud

After digging into this issue I run into multiple issues. The only way to properly fetch if a user is currently active or disconnected, is by using a command line tool shipping with widows. The problem is, that the output is localised which means different languages will result in different outputs, making parsing impossible.

query user

 BENUTZERNAME          SITZUNGSNAME       ID  STATUS  LEERLAUF   ANMELDEZEIT
>icinga                 console             1  Aktiv       Kein   19.11.2020 19:34

The Query command will print all users, including domain users.

Another approach would be Wmi and the Win32_Process class:

(Get-WmiObject win32_process | Where-Object name -Match explorer).GetOwner().User

icinga

The problem: There is no way to check of the user session is currently connected or disconnected with that.

Then is there qwinsta

qwinsta 

 SITZUNGSNAME      BENUTZERNAME             ID  STATUS  TYP         GERÄT
 services                                    0  Getr.
 console                                     1  Verb.
>rdp-tcp#63        Administrator             2  Aktiv
                   icinga                    3  Getr.
 31c5ce94259d4...                        65536  Abh rdp-tcp                                 65537  Abh

Same problem localized content.

So the last resort would be to use the wtsapi32.dll and query the Win32 API directly for this. I would how ever like to keep Win32 API calls to a absolute minimum, because using C# in PowerShell works, but I would rather use more native solutions.

Andy ideas for solutions which I missed?

LordHepipud avatar Nov 20 '20 20:11 LordHepipud

Yell at Microsoft ;)

Only solution i see is to compare agains an array of translation for the "Status"

Mikesch-mp avatar Nov 23 '20 06:11 Mikesch-mp

I found the following PS module, maybe it is worth a look to learn how they did it.

https://archive.codeplex.com/?p=psterminalservices

Get-TSSession

The cmdlet sounds promising, but I think that they also use native API calls or some sort of parsing of the query user program.

mcktr avatar Nov 23 '20 06:11 mcktr

Thank you very much. I might be blind, but I can only download the site archive. I'm unable to locate any PowerShell modules/scripts there. Is it just me?

LordHepipud avatar Nov 23 '20 09:11 LordHepipud

@LordHepipud It is not just you, sorry for inconvenience. I found the project on GitHub:

https://github.com/imseandavis/PSTerminalServices/blob/master/PSTerminalServices/PSTerminalServices.psm1

Quick look into the source code, I found out that they are using a .NET library called cassia: https://github.com/danports/cassia

mcktr avatar Nov 23 '20 09:11 mcktr

Thank you very much. I will move this topic to 1.4.0 for now. The best approach will be a full re-write of the plugin and the provider and propably the solution is to directly access the Win32 api.

I don't feel comfortable to use a third party library not being shipped directly by Windows for possible incompatibility reasons.

Once a first draft is available, I will create a PR for testing.

Thank you for all the feedback so far!

LordHepipud avatar Nov 23 '20 12:11 LordHepipud

It also counts users accessing a fileserver (every session) and if you use JEA you'll have a lot of logged_on_users_winrm_va_151_servershortname_icinga users where 151 is a random id.

t3easy avatar Apr 29 '22 08:04 t3easy

Is there any progress on this? Would it be possible to somehow use an additional exclude parameter to exclude specified users, for example as in the Invoke-IcingaCheckUsedPartitionSpace where you can exclude volumes?

audiocoach avatar Jan 30 '24 22:01 audiocoach