Functions/GenXdev.Windows/Get-ActiveUser.cs
// ################################################################################
// Part of PowerShell module : GenXdev.Windows // Original cmdlet filename : Get-ActiveUser.cs // Original author : René Vaessen / GenXdev // Version : 1.302.2025 // ################################################################################ // Copyright (c) René Vaessen / GenXdev // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ################################################################################ using System; using System.Collections.Generic; using System.Diagnostics; using System.Management; using System.Management.Automation; namespace GenXdev.Windows { /// <summary> /// <para type="synopsis"> /// Retrieves a list of unique usernames from currently active system processes. /// </para> /// /// <para type="description"> /// Queries all running processes on the system, extracts the associated username for /// each process, and returns a deduplicated list of users who have active processes. /// This is useful for system administration and security monitoring. /// </para> /// /// <example> /// <para>Get-ActiveUser</para> /// <para>Returns a list of all unique usernames with active processes.</para> /// <code> /// Get-ActiveUser /// </code> /// </example> /// /// <example> /// <para>gusers</para> /// <para>Uses the alias to get the same results.</para> /// <code> /// gusers /// </code> /// </example> /// </summary> [Cmdlet(VerbsCommon.Get, "ActiveUser")] [Alias("gusers")] [OutputType(typeof(string))] public class GetActiveUserCommand : PSGenXdevCmdlet { private HashSet<string> users; /// <summary> /// Begin processing - initialization logic /// </summary> protected override void BeginProcessing() { // store original error preferences for restoration // Note: In C#, we handle errors directly, but maintain verbose output // inform about the start of process enumeration WriteVerbose("Starting to enumerate all system processes..."); users = new HashSet<string>(); } /// <summary> /// Process record - main cmdlet logic /// </summary> protected override void ProcessRecord() { try { // get all processes Process[] processes = Process.GetProcesses(); // extract and deduplicate usernames from process list foreach (Process process in processes) { try { // Use WMI to get process owner using (ManagementObjectSearcher searcher = new ManagementObjectSearcher( $"SELECT * FROM Win32_Process WHERE ProcessId = {process.Id}")) { foreach (ManagementObject obj in searcher.Get()) { // Invoke GetOwner method ManagementBaseObject owner = obj.InvokeMethod("GetOwner", null, null) as ManagementBaseObject; if (owner != null) { string domain = owner["Domain"] as string; string user = owner["User"] as string; if (!string.IsNullOrEmpty(user)) { string fullUser = string.IsNullOrEmpty(domain) ? user : $"{domain}\\{user}"; users.Add(fullUser); } } break; // Only need first result } } } catch (ManagementException ex) when (ex.ErrorCode == ManagementStatus.AccessDenied) { // Skip processes we can't access, similar to PowerShell behavior continue; } catch { // Skip other errors for individual processes continue; } } } catch (UnauthorizedAccessException) { WriteError(new ErrorRecord( new UnauthorizedAccessException("Access denied while retrieving processes. Run with elevated privileges."), "ActiveUserAccessDenied", ErrorCategory.PermissionDenied, null)); throw; } catch (ArgumentException ex) { WriteError(new ErrorRecord( ex, "ActiveUserInvalidArgument", ErrorCategory.InvalidArgument, null)); throw; } catch (Exception ex) { WriteError(new ErrorRecord( ex, "ActiveUserUnexpectedError", ErrorCategory.OperationStopped, null)); throw; } } /// <summary> /// End processing - cleanup logic /// </summary> protected override void EndProcessing() { // output the filtered list foreach (string user in users) { WriteObject(user); } // output completion status if users were found if (users.Count > 0) { WriteVerbose($"Process completed. Found {users.Count} unique active users."); } else { WriteVerbose("Process completed. No active users found or an error occurred."); } } } } |