Powershell взаимодействие между пользователем SYSTEM и вошедшими в систему пользователями - PullRequest
0 голосов
/ 21 мая 2019

Я хочу, чтобы сценарий powershell, выполняемый от имени пользователя SYSTEM, отображал форму Windows в сеансе других пользователей и взаимодействовал с ее элементами управления.

Я пытаюсь автоматизировать установку / восстановление Symantec Endpoint Protection с SolarwindsN-Способный.Эта платформа использует агентское программное обеспечение, которое установлено на клиентах для мониторинга и выполнения задач на них.

Агент использует пользователя NT AUTHORITY \ SYSTEM для выполнения задач на компьютере.Пока что установка SEP работает нормально, но перезагрузка между фазами удаления / установки все еще не контролируется обычным пользователем на компьютере.Я хочу, чтобы текущий активный пользователь мог контролировать циклы перезагрузки.Что-то вроде приглашения перезагрузки обновления Windows.

Моя идея состоит в том, чтобы отобразить форму окна на рабочем столе пользователя, вошедшего в систему, с элементами управления для выполнения или задержки перезагрузки.Мой вопрос сейчас заключается в том, как отобразить форму окна, определенную в powershell, на сеансе другого пользователя и как я собираюсь вернуть действия элементов управления обратно в сценарий, который выполняется для пользователя SYSTEM.

I 'Мы уже попробовали команду msg, чтобы отправить сообщение всем пользователям системы.Но это только односторонняя связь, и она не предназначена для использования в подобных ситуациях.

1 Ответ

0 голосов
/ 22 мая 2019

Я нашел решение для моей проблемы.Я использовал функцию WTSSendMessage, которую boxdog предложил в комментариях.Я объединил это со скриптом, который получает sessionID'ов вошедших в систему пользователей.Я свернул этот сценарий, чтобы получить только идентификатор пользователя «Активного».Затем он используется для отправки сообщения пользователю.Я протестировал его в Solarwinds, и пока он работает безупречно.

Мои навыки кодирования довольно просты, но это конечный результат.

function Send-MessageBox
{
[CmdletBinding()]
[OutputType([string])]
Param
(        
    [Parameter(Mandatory=$true, Position=0)]
    [string]$title,
    [Parameter(Mandatory=$true, Position=1)]
    [string]$message,
    [Parameter(Mandatory=$true, Position=2)]
    [int]$duration,
    [Parameter(Mandatory=$true, Position=3)]
    [int]$style
)

Begin
{
    $typeDefinition = @"
        using System;
        using System.Runtime.InteropServices;

        public class WTSMessage {
            [DllImport("wtsapi32.dll", SetLastError = true)]
            public static extern bool WTSSendMessage(
                IntPtr hServer,
                [MarshalAs(UnmanagedType.I4)] int SessionId,
                String pTitle,
                [MarshalAs(UnmanagedType.U4)] int TitleLength,
                String pMessage,
                [MarshalAs(UnmanagedType.U4)] int MessageLength,
                [MarshalAs(UnmanagedType.U4)] int Style,
                [MarshalAs(UnmanagedType.U4)] int Timeout,
                [MarshalAs(UnmanagedType.U4)] out int pResponse,
                bool bWait
            );

            static int response = 0;

            public static int SendMessage(int SessionID, String Title, String Message, int Timeout, int MessageBoxType) {
                WTSSendMessage(IntPtr.Zero, SessionID, Title, Title.Length, Message, Message.Length, MessageBoxType, Timeout, out response, true);

                return response;
            }
        }
"@
}

Process
{
    if (-not ([System.Management.Automation.PSTypeName]'WTSMessage').Type)
    {
        Add-Type -TypeDefinition $typeDefinition
    }

    $RawOuput = (quser) -replace '\s{2,}', ',' | ConvertFrom-Csv
    $sessionID = $null

    Foreach ($session in $RawOuput) {  
        if(($session.sessionname -notlike "console") -AND ($session.sessionname -notlike "rdp-tcp*")) {
            if($session.ID -eq "Active"){    
                $sessionID = $session.SESSIONNAME
            }                        
        }else{
            if($session.STATE -eq "Active"){      
                $sessionID = $session.ID
            }        
        }   
    }
    $response = [WTSMessage]::SendMessage($sessionID, $title, $message, $duration, $style )
}
End
{
    Return $response
}
}

Send-MessageBox -title "Title" -message "Message" -duration 60 -style 0x00001034L
...