Beispiel #1
0
        public static DialogResult LogoffUser(RemoteLogonSession windowsUser)
        {
            // LogoffUser() forces the selected user to logoff.
            // It returns a DialogResult which will be used to display the results.
            var  dialog         = new DialogResult();
            bool didTaskSucceed = false;

            if (IsServerEdition)
            {
                try
                {
                    IntPtr server = WtsApi.WTSOpenServer(ComputerName);
                    if (WtsApi.LogOffUser(server, Convert.ToInt32(windowsUser.SessionId), windowsUser.Username) == true)
                    {
                        didTaskSucceed = true;
                    }
                }
                catch
                { }
            }
            else
            {
                // Setup WMI query.
                var options = new ConnectionOptions();
                if (GlobalVar.UseAlternateCredentials)
                {
                    options.Username  = GlobalVar.AlternateUsername;
                    options.Password  = GlobalVar.AlternatePassword;
                    options.Authority = $"NTLMDOMAIN:{GlobalVar.AlternateDomain}";
                }
                var scope    = new ManagementScope($@"\\{ComputerName}\root\CIMV2", options);
                var query    = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
                var searcher = new ManagementObjectSearcher(scope, query);

                try
                {
                    foreach (ManagementObject m in searcher.Get())
                    {
                        ManagementBaseObject inParams = m.GetMethodParameters("Win32Shutdown");
                        inParams["Flags"] = 4;
                        ManagementBaseObject outParams = m.InvokeMethod("Win32Shutdown", inParams, null);
                        int  returnValue;
                        bool isReturnValid = int.TryParse(outParams["ReturnValue"].ToString(), out returnValue);
                        if (isReturnValid && returnValue == 0)
                        {
                            didTaskSucceed = true;
                        }
                        break;
                    }
                }
                catch
                { }
            }

            if (didTaskSucceed)
            {
                // User has been logged off.  Build DialogResult to reflect success.
                dialog.DialogTitle     = "Success";
                dialog.DialogBody      = $"{windowsUser.Username} has been logged off.  It might take a few minutes for the target user to be fully logged out.";
                dialog.DialogIconPath  = "/Resources/success-48.png";
                dialog.ButtonIconPath  = "/Resources/checkmark-24.png";
                dialog.ButtonText      = "OK";
                dialog.IsCancelVisible = false;
            }
            else
            {
                // Error logging off user.  Build DialogResult to reflect failure.
                dialog.DialogTitle     = "Error";
                dialog.DialogBody      = $"Failed to logoff {windowsUser.Username}.";
                dialog.DialogIconPath  = "/Resources/error-48.png";
                dialog.ButtonIconPath  = "/Resources/checkmark-24.png";
                dialog.ButtonText      = "OK";
                dialog.IsCancelVisible = false;
            }

            return(dialog);
        }
Beispiel #2
0
        public static List <RemoteLogonSession> GetLogonSessions()
        {
            // GetProcesses() first uses WMI to determine if the target computer is running a desktop or server OS.
            // If running a server OS, it uses the Remote Desktop Service API to retrieve logon sessions.
            // If running a desktop OS, it uses WMI to retrieve logon sessions.
            // It returns a List of RemoteLogonSession which will be bound to a DataGrid on this UserControl.

            var logonSessions = new List <RemoteLogonSession>();
            var taskResult    = new TaskResult();

            Result = taskResult;
            UInt32 productType = 1;

            // Determine whether operating system is server or desktop edition.
            var options = new ConnectionOptions();

            if (GlobalVar.UseAlternateCredentials)
            {
                options.Username  = GlobalVar.AlternateUsername;
                options.Password  = GlobalVar.AlternatePassword;
                options.Authority = $"NTLMDOMAIN:{GlobalVar.AlternateDomain}";
            }
            var scope    = new ManagementScope($@"\\{ComputerName}\root\CIMV2", options);
            var query    = new ObjectQuery("SELECT ProductType FROM Win32_OperatingSystem");
            var searcher = new ManagementObjectSearcher(scope, query);

            try
            {
                foreach (ManagementObject m in searcher.Get())
                {
                    productType = (m["ProductType"] != null) ? (UInt32)m["ProductType"] : 1;
                    break;
                }
            }
            catch
            {
                taskResult.DidTaskSucceed = false;
                return(logonSessions);
            }
            IsServerEdition = productType > 1 ? true : false;

            // If operating system is server edition, use Remote Desktop Services API to retrieve logon sessions.
            if (IsServerEdition)
            {
                try
                {
                    using (
                        GlobalVar.UseAlternateCredentials
                        ? UserImpersonation.Impersonate(GlobalVar.AlternateUsername, GlobalVar.AlternateDomain, GlobalVar.AlternatePassword)
                        : null)
                    {
                        IntPtr server = WtsApi.WTSOpenServer(ComputerName);
                        logonSessions.AddRange(WtsApi.GetWindowsUsers(server));

                        foreach (RemoteLogonSession logonSession in logonSessions)
                        {
                            query    = new ObjectQuery($"SELECT CreationDate FROM Win32_Process WHERE SessionId = {logonSession.SessionId}");
                            searcher = new ManagementObjectSearcher(scope, query);
                            DateTime logonTime = DateTime.Now;
                            foreach (ManagementObject m in searcher.Get())
                            {
                                DateTime procCreationDate = ManagementDateTimeConverter.ToDateTime(m["CreationDate"].ToString());
                                if (procCreationDate < logonTime)
                                {
                                    logonSession.LogonTime = procCreationDate;
                                }
                            }
                        }
                    }
                    taskResult.DidTaskSucceed = true;
                }
                catch
                {
                    taskResult.DidTaskSucceed = false;
                }
            }
            // If operating system is desktop edition, query Win32_Process for explorer.exe to determine logged on users.
            else
            {
                query    = new ObjectQuery("SELECT * FROM Win32_Process WHERE Name = 'explorer.exe'");
                searcher = new ManagementObjectSearcher(scope, query);

                try
                {
                    foreach (ManagementObject m in searcher.Get())
                    {
                        var logonSession = new RemoteLogonSession();
                        logonSession.SessionId = (UInt32)m["SessionId"];
                        var dmtfDateTime = m["CreationDate"].ToString();
                        logonSession.LogonTime = ManagementDateTimeConverter.ToDateTime(dmtfDateTime);

                        string[] argList   = new string[] { string.Empty, string.Empty };
                        int      returnVal = Convert.ToInt32(m.InvokeMethod("GetOwner", argList));
                        if (returnVal == 0)
                        {
                            logonSession.Username = argList[0];
                            logonSession.Domain   = argList[1];
                        }
                        else
                        {
                            logonSession.Username = string.Empty;
                        }

                        int index = logonSessions.FindIndex(item => item.SessionId == logonSession.SessionId);
                        if (index >= 0)
                        {
                            continue;
                        }
                        else
                        {
                            logonSessions.Add(logonSession);
                        }
                    }
                    taskResult.DidTaskSucceed = true;
                }
                catch
                {
                    taskResult.DidTaskSucceed = false;
                }
            }

            return(logonSessions);
        }
Beispiel #3
0
        public static DialogResult TaskGpupdate(string targetComputer)
        {
            // TaskGpupdate() uses WMI to execute the GPUpdate command.
            // It returns a DialogResult which will be used to display the results.
            var          dialog           = new DialogResult();
            bool         didTaskSucceed   = false;
            const string gpupdateComputer = "cmd /c echo n | gpupdate /force";

            // Setup WMI query.
            var options = new ConnectionOptions();

            if (GlobalVar.UseAlternateCredentials)
            {
                options.Username  = GlobalVar.AlternateUsername;
                options.Password  = GlobalVar.AlternatePassword;
                options.Authority = $"NTLMDOMAIN:{GlobalVar.AlternateDomain}";
            }
            var scope = new ManagementScope($@"\\{targetComputer}\root\CIMV2", options);

            try
            {
                scope.Connect();
                var objectGetOptions = new ObjectGetOptions();
                var managementPath   = new ManagementPath("Win32_Process");
                var managementClass  = new ManagementClass(scope, managementPath, objectGetOptions);

                ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
                inParams["CommandLine"] = gpupdateComputer;
                ManagementBaseObject outParams = managementClass.InvokeMethod("Create", inParams, null);

                int  returnValue;
                bool isReturnValid = int.TryParse(outParams["ReturnValue"].ToString(), out returnValue);
                if (!isReturnValid || returnValue != 0)
                {
                    throw new Exception();
                }
            }
            catch
            { }

            try
            {
                // To apply user policies, gpupdate.exe MUST be run in the context of each logged in user.
                // In order to do so, a scheduled task is created on the target machine that is configured to run GPUpdate
                // as each currently logged in user.  Prior to running the task, a simple .VBS script that calls gpupdate.exe is
                // written to C:\Windows\TEMP on the target computer.  The scheduled task points to the .VBS script.  This is done
                // to hide any console windows that would appear if the task were to directly run gpupdate.exe.  The temporary
                // script file and task are then deleted once the execution has kicked off.
                const string gpupdateUser = "******"WScript.Shell\").Run \"cmd /c echo n | gpupdate /target:user /force\", 0";
                string       remotePathToGpupdateScript = $@"\\{targetComputer}\C$\Windows\Temp";
                string       localPathToGpupdateScript  = @"C:\Windows\Temp";

                RemoteLogonSession.ComputerName = targetComputer;
                var loggedOnUsers = RemoteLogonSession.GetLogonSessions();

                if (loggedOnUsers.Count > 0 && Directory.Exists(remotePathToGpupdateScript))
                {
                    var rnd       = new Random();
                    var rndNumber = rnd.Next(0, 1000);
                    remotePathToGpupdateScript += $@"\splc-{rndNumber}.vbs";
                    localPathToGpupdateScript  += $@"\splc-{rndNumber}.vbs";
                    var scheduledTaskName = "SpliceAdmin-Gpupdate-" + rndNumber;

                    // Write temporary .vbs script file.
                    File.WriteAllText(remotePathToGpupdateScript, gpupdateUser);

                    if (File.Exists(remotePathToGpupdateScript))
                    {
                        var fileInfo     = new FileInfo(remotePathToGpupdateScript);
                        var fileSecurity = fileInfo.GetAccessControl();
                        fileSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.ReadAndExecute, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
                        fileInfo.SetAccessControl(fileSecurity);

                        var startInfo = new ProcessStartInfo();
                        startInfo.RedirectStandardOutput = true;
                        startInfo.RedirectStandardError  = true;
                        startInfo.UseShellExecute        = false;
                        startInfo.CreateNoWindow         = true;
                        startInfo.FileName = "schtasks.exe";

                        foreach (var user in loggedOnUsers)
                        {
                            startInfo.Arguments = $"/create /f /s {targetComputer} /ru {user.Username} /sc once /st 00:00 /tn {scheduledTaskName} /tr \"wscript.exe //e:vbs //b \\\"{localPathToGpupdateScript}\\\"\"  /it";
                            Process.Start(startInfo);
                            Thread.Sleep(500);

                            startInfo.Arguments = $"/run /tn {scheduledTaskName} /s {targetComputer}";
                            Process.Start(startInfo);
                            Thread.Sleep(2000);
                        }

                        startInfo.Arguments = $"/delete /f /tn {scheduledTaskName} /s {targetComputer}";
                        Process.Start(startInfo);

                        File.Delete(remotePathToGpupdateScript);
                    }

                    Thread.Sleep(7000);
                    didTaskSucceed = true;
                }
            }
            catch
            { }

            if (didTaskSucceed)
            {
                // GPUpdate was successful.  Build DialogResult to reflect success.
                dialog.DialogTitle     = "Success";
                dialog.DialogBody      = $"{targetComputer} has successfuly refreshed all Group Policy Objects.";
                dialog.DialogIconPath  = "/Resources/success-48.png";
                dialog.ButtonIconPath  = "/Resources/checkmark-24.png";
                dialog.ButtonText      = "OK";
                dialog.IsCancelVisible = false;
            }
            else
            {
                // Failed to run GPUpdate.  Build DialogResult to reflect failure.
                dialog.DialogTitle     = "Error";
                dialog.DialogBody      = $"Failed to refresh Group Policy Objects on {targetComputer}.";
                dialog.DialogIconPath  = "/Resources/error-48.png";
                dialog.ButtonIconPath  = "/Resources/checkmark-24.png";
                dialog.ButtonText      = "OK";
                dialog.IsCancelVisible = false;
            }

            return(dialog);
        }