Пользователь
0,1
рейтинг
11 февраля 2012 в 18:30

Разработка → PowerShell и GUI. Это — не сложно tutorial

.NET*
Некоторое время назад в компании была развернута терминальная ферма.
Первым делом в неё были выселены пользователи некой желтой программы.
После чего отдел поддержки желтой программы спросил меня, можно ли отсылать сообщения пользователям фермы всем сразу. XaocCPS посоветовал мне играться в сторону WPF. Нужный скрипт был написан, но его работой я неудовлетворился:
1. Надо ставить внешний компонент PowerShellPack.
2. Компонент ставиться на сервера фермы (х64) отказался.
3. Распространять такое решение из за пункта 1 всем желающим не очень удобно.

Xaegr подсказал что я могу избавиться от прослойки WPF.
Писать можно, можно даже писать красиво. Скрипт выполняется везде где есть .Net Framework — XP, Win7 и скорее всего пойдет даже на х64 серверах фермы.
Как писать — под катом.

UPD по просьбам скрипт выложен на SkyDrive, ссылка в конце

И так — ТЗ, полученное от отдела поддержки было «отправка сообщений всем пользователям терминальной фермы».
Мною ТЗ было расширено:
1. Выбор серверов.
2. Выбор пользователей.
3. Ввод текста сообщения.
4. Вставка подписи — идентификатор отправившего сообщения пользователя — виден в заголовке окна, но на него внимание обращают мало, выбрал вариант из нескольких предустановленных вариантов.
5. Защита от нечаянной отправки.

Предварительно было найдено, что в Win7 и 2008* есть команда msg, с помощью которой данные сообщения и будут отправляться, но прием сообщений надо разрешить, что и сделал простеньким regedit файлом:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"AllowRemoteRPC"=dword:00000001


К сожалению, если пользователь из списка не подключен к серверу — скрипт много и сильно ругается. Я пока не придумал как получить вывод msg, и его обрабатывать.
Скрипт по максимуму комментирован.
~15kb

# Подключаем то, с помощью чего будем рисовать нашу форму
Add-Type -assembly System.Windows.Forms

	# Все просто, массивы из списка серверов, списка пользоватей, и варианты подписи - чтобы использовать могла не только поддержка.
	$Server        = @("rdp1-1, rdp1-2, rdp1-3, rdp1-4", "rdp2-1, rdp2-2, rdp2-3, rdp2-4")
	$User          = @("*", "1c-admin1, 1c-admin2")
	$Message       = "Умолчательное сообщение"
	# По хорошему, надо бы сделать так, чтобы если умолчательное сообщение не менялось и шло нажатие на кнопку отправить, то выводилось бы предупреждение.
	# Так же по аналогии с тем что есть, тут тоже можно повесить список со стандартными сообщениями

	# Подписываемся
	$Sign          = @("С уважением, администраторы 1С", "С уважением, системные администраторы")

	# Повелось, что все функции описываются до их использования.
	# Функция отправки сообщения. Принимаем параметры, проверяем, если чекбокс включен (а он включен по умолчанию), устанавливаем параметры отправки только на консоль локалхоста, иначе проходим по списку серверов, внутри каждого сервера инициируем цикл по списку пользователей с предварительно отрезанными пробелами до и после текста(помните формат: "сервер1, сервер2, сервер3" для красивой читаемости текста), вызываем сам msg для отправки сообщения и после чего вызываем диалогов окно с подтверждением отправки и закрытием программы.
Function SendMessage {
        param ($Server, $User, $Message, $Sign)
       # Write-Host $Server, $User, $Message, $Sign
        If ($TestRunCheckBox.Checked -eq 1 ) { Write-Host $TestRunCheckBox.Checked; $Server="localhost"; $User = "Console" }
        ForEach ($Item in $Server) {
            ForEach ($UserX in $User) {
                    $UserTrim = $UserX.Trim()
                    $ServerTrim = $Item.Trim()
                    $MsgTrim = $Message.Trim()
                    $SignTrim = $SignX.Trim()
                    # Отладочный вывод, оставлен на всякий случай.
                    # Write-Host "User: $UserTrim; Server: $ServerTrim; Message: $MsgTrim; Signature: $SignTrim"
                    c:\windows\system32\msg.exe $UserTrim /Server:$ServerTrim $MsgTrim $SignTrim
                }
        }
     Confirm
    }

# Вывод окна с подтверждением
Function Confirm {
        $ConfirmWin = New-Object System.Windows.Forms.Form
        $ConfirmWin.StartPosition  = "CenterScreen"
        $ConfirmWin.Text = "Подтверждение отправки"
        $ConfirmWin.Width = 200
        $ConfirmWin.Height = 120
        $ConfirmWin.ControlBox = 0

        $ConfirmWinOKButton = New-Object System.Windows.Forms.Button
        $ConfirmWinOKButton.add_click({ $MainSendWindow.Close(); $ConfirmWin.Close() })
        $ConfirmWinOKButton.Text = "Закрыть"
        $ConfirmWinOKButton.AutoSize = 1
        $ConfirmWinOKButton.Location        = New-Object System.Drawing.Point(50,50)

        $ConfirmLabel = New-Object System.Windows.Forms.Label
        $ConfirmLabel.Text = "Сообщение было отправлено"
        $ConfirmLabel.AutoSize = 1
        $ConfirmLabel.Location  = New-Object System.Drawing.Point(10,10)

        $ConfirmWin.Controls.Add($ConfirmLabel)
        $ConfirmWin.Controls.Add($ConfirmWinOKButton)
        $ConfirmWin.ShowDialog() | Out-Null
    }

# Главное окно, по хорошему тоже стоило бы оформить в виде функции
     $MainSendWindow                = New-Object System.Windows.Forms.Form
     $ToolTip = New-Object System.Windows.Forms.ToolTip

     $ToolTip.BackColor = [System.Drawing.Color]::LightGoldenrodYellow
     $ToolTip.IsBalloon = $true
     # $ToolTip.InitialDelay = 500
     # $ToolTip.ReshowDelay = 500

     # Инициализация контролов формы
     # Кнопки и чекбокс
     $SendButton                   = New-Object System.Windows.Forms.Button
     $CloseButton                   = New-Object System.Windows.Forms.Button
     $TestRunCheckBox           = New-Object System.Windows.Forms.CheckBox

     # Текстовые поля и списки
     $ServerTextBox                = New-Object System.Windows.Forms.ComboBox
     $UserTextBox                   = New-Object System.Windows.Forms.ComboBox
     $MessageTextBox             = New-Object System.Windows.Forms.TextBox
     $SignTextBox                   = New-Object System.Windows.Forms.ComboBox

     # Подписи
     $ServerTextBoxLabel           = New-Object System.Windows.Forms.Label
     $UserTextBoxLabel              = New-Object System.Windows.Forms.Label
     $MessageTextBoxLabel        = New-Object System.Windows.Forms.Label
     $SignTextBoxLabel              = New-Object System.Windows.Forms.Label

# Описываем свойства (комментариями я еще добавлю несколько нагугленных
# интересных свойств для общего развития и чтобы далеко не бегать ;))

# Главная форма
$MainSendWindow.StartPosition  = "CenterScreen"
$MainSendWindow.Text           = "Отправка сообщения пользователям"
$MainSendWindow.Width          = 470
$MainSendWindow.Height         = 220
# несколько плюшек и обещанных красивостей
#$Win.ControlBox           = 0 # отключить кнопки свернуть, минимизацию и закрытие.
# $Win.ShowIcon             = 0
# $Win.ShowInTaskbar        = 0
# $Win.HelpButton           = 1
# авторазмер может отрабатывать если вся форма - к примеру одна кнопка "Сделать хорошо"
# $Win.Autosize             = 1
# $Win.AutoSizeMode         = "GrowAndShrink"
# стиль обрамления и шрифт.
# $Win.FormBorderStyle      = [System.Windows.Forms.FormBorderStyle]::Fixed3D
# $Win.Font                 = New-Object System.Drawing.Font("Verdana",32)

# Подписи к текстовым полям
$ServerTextBoxLabel.Location   = New-Object System.Drawing.Point(10,12)
$ServerTextBoxLabel.Text       = "Список серверов"
$ServerTextBoxLabel.Autosize     = 1

$UserTextBoxLabel.Location     = New-Object System.Drawing.Point(10,42)
$UserTextBoxLabel.Text         = "Список пользователей"
$UserTextBoxLabel.Autosize     = 1

$MessageTextBoxLabel.Location  = New-Object System.Drawing.Point(10,73)
$MessageTextBoxLabel.Text      = "Сообщение"
$MessageTextBoxLabel.Autosize  = 1
# Плюшка в виде красивой подсказки, делается другим методом вызова, поэтому идет к каждому обьекту в блоке, чтобы не теряться.
$ToolTip.SetToolTip($MessageTextBoxLabel, "Надо подписаться, а то в заголовке окна с сообщениями не видно")

$SignTextBoxLabel.Location     = New-Object System.Drawing.Point(10,103)
$SignTextBoxLabel.Text         = "Подпись"
$SignTextBoxLabel.Autosize     = 1
$ToolTip.SetToolTip($SignTextBoxLabel, "Надо подписаться, а то в заголовке окна с сообщениями не видно")

# Описание текстбокса
# Позиция
$ServerTextBox.Location        = New-Object System.Drawing.Point(140,10)
# Источник данных
$ServerTextBox.DataSource      = $Server
# Размер
$ServerTextBox.Width           = 300
# Обработка события - при смене текста в поле, присваиваем переменной новое полученное значение.
$ServerTextBox.add_TextChanged({ $Server = $ServerTextBox.Text })
# индекс порядка перехода по Tab
$ServerTextBox.TabIndex        = 1
$ToolTip.SetToolTip($ServerTextBox, "Укажите список серверов")

$UserTextBox.Location          = New-Object System.Drawing.Point(140,40)
$UserTextBox.DataSource        = $User
# Не забываем про массив
$UserTextBox.Text              = $User[1]
$UserTextBox.add_TextChanged({ $User = $UserTextBox.Text })
$UserTextBox.Width             = 300
$UserTextBox.TabIndex          = 2
$ToolTip.SetToolTip($UserTextBox, "Кому отправлять будем? (* для *всех* пользователей, по умолчанию)")

# Поле сообщения
$MessageTextBox.Location       = New-Object System.Drawing.Point(140,70)
$MessageTextBox.Text           = $Message
# По клику в поле ввода - автоматически выделяем весь текст, чтобы не надо было
# нажимать удаление
$MessageTextBox.add_click({ $MessageTextBox.SelectAll() })
$MessageTextBox.add_TextChanged( { $Message = $MessageTextBox.Text })
$MessageTextBox.Width          = 300
$MessageTextBox.TabIndex       = 3
$ToolTip.SetToolTip($MessageTextBox, "И шо мы таки хотим сказать?")

# Поле подписи - отправляемая переменная уже другая
$SignTextBox.Location          = New-Object System.Drawing.Point(140,103)
# Источник текста для подписи
$SignTextBox.DataSource        = $Sign
# А мы помним, что там массив?:)
$SignTextBox.Text              = $Sign[1]
$SignTextBox.add_TextChanged({ $SignX = $SignTextBox.Text })
$SignTextBox.Width             = 300
$SignTextBox.TabIndex          = 4
$ToolTip.SetToolTip($SignTextBox, "Страна должна знать своих героев")

# Нопка отправки.
$SendButton.Location           = New-Object System.Drawing.Point(10,150)
$SendButton.Text               = "Отправить сообщение"
# Выполняем разделения строк на массивы с разделителем запятая, вызываем функцию отправки сообщения
$SendButton.add_click({ $User  = $UserTextBox.Text.Split(","); $Server = $ServerTextBox.Text.Split(","); $SignX = $SignTextBox.Text; SendMessage $Server $User $Message $SignX} )
$SendButton.Autosize           = 1
$SendButton.TabIndex           = 5
$ToolTip.SetToolTip($SendButton, "Тыцни пимпочку")

# Прописываем блокировочный чекбокс
$TestRunCheckBox.Location      = New-Object System.Drawing.Point(200,150)
$TestRunCheckBox.Text          = "Тест"
$TestRunCheckBox.Checked       = 1
$TestRunCheckBox.AutoSize      = 1
$TestRunCheckBox.TabIndex      = 6
$ToolTip.SetToolTip($TestRunCheckBox, "Сними меня, а то работать не будет")

# Кнопочка выхода, по событию вызывает метод закрытия
$CloseButton.Location          = New-Object System.Drawing.Point(315,150)
$CloseButton.Text              = "Выйти из программы"
$CloseButton.add_click({ $MainSendWindow.Close() })
$CloseButton.Autosize          = 1
$CloseButton.TabIndex          = 7
$ToolTip.SetToolTip($CloseButton, "Пойдем ка отсюда")


# Добавляем контролы в форму и вызываем её запуск
$MainSendWindow.Controls.Add($SendButton)
$MainSendWindow.Controls.Add($TestRunCheckBox)
$MainSendWindow.Controls.Add($CloseButton)

$MainSendWindow.Controls.Add($ServerTextBox)
$MainSendWindow.Controls.Add($UserTextBox)
$MainSendWindow.Controls.Add($MessageTextBox)
$MainSendWindow.Controls.Add($SignTextBox)

$MainSendWindow.Controls.Add($ServerTextBoxLabel)
$MainSendWindow.Controls.Add($UserTextBoxLabel)
$MainSendWindow.Controls.Add($MessageTextBoxLabel)
$MainSendWindow.Controls.Add($SignTextBoxLabel)

$MainSendWindow.ShowDialog() | Out-Null


В результате получилась вот такая вот красивость
image

Скрипт могу выложить, при желании читателей, куда-то.

Не уверен, что хватит кармы публировать в профильный, поэтому выложил сюда

Исходник скрипта на GitHub'е
Nikolay Turnaviotov @foxmuldercp
карма
10,0
рейтинг 0,1
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (37)

  • 0
    Прошу прощения за битое форматирование.
    Надеюсь, что это кому-то поможет
  • –2
    Простите, а зачем это нужно?
    • +5
      Что приятнее конечному пользователю:
      Непонятная консоль (которую надо знать)
      Или же ввести текст в графический интерфейс?
  • –1
    Мне, как конечному пользователю всегда приятнее использовать стандартные формы передачи сообщений.
    • +7
      Простите, что значит «стандартная форма передачи сообщений»?
      У нас в компании официальная почта, затем аська/скайп. Уведомления, которые рассылаются службой поддержки 1С — стандартны для пользователей 1С, поскольку если окно TSC открыто на весь экран (а в бухгалтерии это чуть ли не штатная ситуация 99% рабочего времени) ни всплывающее окно аутлука, ни аськи ни скайпа не будет замечено в 90% случаев.
      В отличие от окошка по центру экрана, которое перекрывает платежку/проводку и т.п.
      Кстати реакцию на нажатие ОК в этом окне можно попробовать отловить и обработать, но это уже другая история…
  • –2
    По роду деятельности я стараюсь избегать работающих с 1с и подобными продуктами (читать: украинский сектор), поэтому плаваю в потребностях пользователей 1с, и даже не подозревал что кому-то может понадобиться возвращение в win95 с его pop-up. Если у Вас, как и у большинства официальная почта, потом аська/скайп, то логично предположить что и приоритет у этих систем соответствующий: почта, аська/скайп, все остальное. Если кто-то не умеет оперативно пользоваться почтой то это другой разговор. Я высказываю лично свое мнение, и подобного рода финты, я бы отключил и не принимал во внимание до официального письма в почте. Лично мне не нравятся pop-up, они у меня в браузере тоже выключены, а у Вас?
    • +3
      Видите ли, ПопАп об обновлениях 1С это немного другое. обзванивать стопицот пользователей — не выход, а письма в почту половина из них пропустит по причине полноэкранного режима клиента RDP
      • –1
        Мы говорим немного о разных вещах. Я говорю что у каждого есть свои официальные обязанности и свои официальные правила. Соответственно если в правилах написано: официальный способ общения — почта, то это не повод вообще кого-то обзванивать, это больше повод кого-то штрафовать. Есть правила их надо выполнять. Новый человек, который приходит в компанию не должен тонуть в разнообразных негласных фичах, и потом оправдываться что был не прав, поп-апы не читал. Хотя Дело Ваше, Написано в правилах официальный способ общения — поп-ап, я думаю никто из сторонних наблюдателей не будет против, так возможно зададутся вопросом, как я, не более того.
        • +3
          Да, все таки о разных вещах.
          Потому как в разных отделах могут быть разные штуки. не смотря на корпоративный стандарт — почту.
        • 0
          Сам очень часто работаю по рдп, проверять регулярно почту обязательно. Но у такого способа есть плюс, работая по рдп бухгалтер не будут смотреть в почту каждые 5 минут. А если админу или 1с прогерам необходимо чтобы все корректно вышли из 1с? самым быстрым будет обзвон отделов или вот такое решение как описал автор.
    • +3
      Win95 тут ни при чем, это стандартный net send $)
  • 0
    Ну возможно тем кто работает с более чем 10-ю терминальными серверами это и будет полезно, но мне с 3-я серверами пока хватало net send'a и без GUI…
  • +2
    Вам, но не нашим 1Сникам :) а net send'а в семерке и нету.
    • 0
      Хм… чего-то я не понял…
      net send нужен на терминальном сервере с серверной виндой. Причём тут семёрка?
      • 0
        На Win2008 тоже нет
        • 0
          да, net send нет = вместо него есть msg, обертку к которому я и нарисовал
  • 0
    ленивая у вас служба поддержки «некоей желтой программы».
    средствами самой одинэсины прекрасненько организуется и обмен сообщениями (сключая рассылку) по всем рабочим сеансам, и отключение сеансов (с таймаутом если нужно).
    (если не лениться — даже можно хоть IM, хоть чаты, хоть борды сварганить)
    • 0
      «сключая» — в смысле «включая», как бы это парадоксально ни выглядело, простите, клавадурапасерлохивсётакоэ…
    • +1
      Скажем так — есть задача, я ее решил, плюс узнал для себя кучу новых интересных штук в рамках того языка программирования, который мне интересен :)
      Что там умеет желтая программа и насколько ее юзают пользователи и программеры для меня вообще тайна за семью печатями…
      • 0
        да я разве же тебя в чем-то упрекаю? нет, что ты, ни полуслогом.
        просто показательно, что имея точно так же задачу и имея возможность руками сделать кучу интересных штук, мои, извиняюсь за выражение, коллеги перевесили её на кого-то другого.
        (ох, чувствую, огребу)
        • +2
          Возможно Ваши коллеги и мои сотрудники просто не представляют себе функционал того что они используют :)
          про .Net из повершелла я тоже узнал, в общем-то с недели полторы назад :)
          А сколько еще узнаю в процессе ковыряния екченджа/шарепоинта и прочих технолгий )))
  • +1
    По форме все верно, а по сути извращение. Для создание форм под повершеллом не нужно использовать создание контролов из пространства имен System.Windows.Forms, ведь сами видите, в этом случае 95% скрипта занимает собственно отрисовка формы, а 5% — смысловая нагрузка скрипта. А отладка? Сколько раз вы запустили скрипт, чтобы убедиться, что вы положение каждой кнопочки и комбобоксика указали в пикселях правильно?
    Воспользуйтесь Windows Presentation Framework!
    Вот, набросал за пять минут:

    --[testform.xml]--
    <Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="Заголовочек" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="146" Width="205">
     <Grid Height="103" Width="180">
      <Button Content="Кнопочка А" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
      <Button Content="Кнопочка Б" Height="23" HorizontalAlignment="Left" Margin="93,12,0,0" Name="button2" VerticalAlignment="Top" Width="75" />
      <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" Name="textBlock1" Text="Текст" VerticalAlignment="Top" Width="156" />
      <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,70,0,0" Name="comboBox1" VerticalAlignment="Top" Width="156">
        <ComboBoxItem Content="Выбор 1" />
        <ComboBoxItem Content="Выбор 2" />
      </ComboBox>
     </Grid>
    </Window>
    

    --[testform.ps1 — изменить путь к testform.xml во второй строке]--
    Add-Type -AssemblyName presentationframework
    $xaml = [xml](Get-Content ".\Documents\testform.xml")
    $reader=(New-Object System.Xml.XmlNodeReader $xaml)
    $Form=[Windows.Markup.XamlReader]::Load( $reader )
    $Form.ShowDialog() | out-null


    Формы xaml легко редактируются в том же visual studio или даже visual c# express, а на выходе мы получаем без лишних усилий что-то вроде этого:
    • 0
      Спасибо за интересный вариант, но ни MSVS ни VSC#E у меня нет. А применить документацию из пространства System.Windows.Forms к повершеллу оказалось просто и быстро, с подсказками ребят.
      XMLный код мне вообще непонятен из-за кучи тегов.
      WPF через повершелпак — мне жутко не понравился, я это в после описал
      • 0
        VSxE бесплатен
      • +4
        WPF можно без пака и без xml

        Add-Type -Assembly PresentationFramework
        function add($control, $children)
        {
           $children | %{ $control.Children.Add($_)} | Out-Null
           $control
        }
        $w = New-Object System.Windows.Window -prop @{
            SizeToContent = [System.Windows.SizeToContent]::WidthAndHeight;
            Content = add (New-Object System.Windows.Controls.StackPanel) @(        
                add (New-Object System.Windows.Controls.StackPanel -prop @{ Orientation = [System.Windows.Controls.Orientation]::Horizontal}) @(
                    New-Object System.Windows.Controls.Button -prop @{Content="Кнопочка A";}
                    New-Object System.Windows.Controls.Button -prop @{Content="Кнопочка Б";}
                )
                New-Object System.Windows.Controls.TextBlock -prop @{Text="Текст"}        
                New-Object System.Windows.Controls.Combobox -prop @{ItemsSource=@("Выбор 1", "Выбор 2")}
            );    
        }
        $w.ShowDialog()
        
        • 0
          Заметьте, что в этом коде нет ни одного захардкоженного числа — мы объясняем WPF как расположить элементы управления и оно располагает за нас.

          Если вы освоите WPF, то сможете применить эти знания для написания приложений для WP7, и Metro-style приложений в W8.

          Я бы конечно в реальности предпочел сделать так, как сделал thunderquack — нарисовать xml в VS или Expression Blend и соединить его потом с кодом.

          • 0
            Спасибо, попробую поиграться
      • 0
        Еще прило в голову, что если отформатировать сгенерированный XML и убрать лишние атрибуты, то его вполне можно прочитать

        <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                Title="Заголовочек" 
                Height="146" Width="205">
            <Grid Height="103" Width="180">
                <Button 
                    Content="Кнопочка А" 
                    HorizontalAlignment="Left" 
                    Margin="12,12,0,0" 
                    Name="button1" 
                    VerticalAlignment="Top" />
                <Button 
                    Content="Кнопочка Б" 
                    HorizontalAlignment="Left" 
                    Margin="93,12,0,0" 
                    Name="button2" 
                    VerticalAlignment="Top" />
                <TextBlock 
                    HorizontalAlignment="Left" 
                    Margin="12,41,0,0" 
                    Name="textBlock1" 
                    Text="Текст" 
                    VerticalAlignment="Top" />
                <ComboBox 
                    HorizontalAlignment="Left" 
                    Margin="12,70,0,0" 
                    Name="comboBox1" VerticalAlignment="Top" 
                    >
                    <ComboBoxItem Content="Выбор 1" />
                    <ComboBoxItem Content="Выбор 2" />
                </ComboBox>
            </Grid>
        </Window>
        
        
        
  • 0
    а перевод работы желто/красной программы в seamless window не пробовали? и тогда уж можно разделять — уведомления системные по программе — средствами программы. Общение пользователей пусть будет отдано скайпу или почте. всем все видно и все работает
    • 0
      Этот скрипт большей частью написан just for fun :)
      для повышения ХР. опять же, уведомление о закрытии баз к обеду — прерогатива поддержки 1С.
      а что там умеет или нет 1С — мне и без нее мороки хватает :)
      Если Так превычнее бухгалтерии — пусть живет.
      А для меня это красивая мордочка к консольным командам.
      Опять же, средствами повершелл можно управлять огромнейшей сетью, и делать всё, что угодно — а GUI — я сейчас могу раздать скрипт нашим региональным админам, к примеру, где будет одна кнопка «сбросить пароль» и поле для выбора учетной записи. чтобы они меня не дергали, к примеру.
      К этому я и веду, в общем.
  • +1
    PoSh действительно прикольная вещичка, сам пытаюсь почти все свои телодвижения на работе пытаюсь делать через PoSh.
    Скрипт интересный, но я так понимаю, что данным скриптом нельзя отправить сообщение, скажем, с Win7 на WinXP или наоборот, т.к. на машинах с XP нет msg.exe а на Win7 нет net send.
    Сам сейчас маюсь с написанием такой машинки, что бы раскидывала сообщения на любые машины.
    • 0
      Спасибо за мысль, можно проверять версию ОС и в зависимости от неё запускать net send/msg.
      • 0
        А разве можно, скажем, на Win7 установить net send? Или msg на WinXP?
        • 0
          Фразу про «проверить версию ос и в зависимости от неё запускать ...» пропустили?:)
          • +1
            Я имел другое ввиду, но сейчас уже разобрался. Просто не был уверен, что msg.exe отправит на WinXp сообщение. Оказалось — работает. Вам спасибо, а то бы не разобрался))
        • 0
          Ставить же необязательно. Хотя я встречал в инете API net send, возможно оно и не поменялось.
          Я сейчас собираюсь активно изучать С#, может попробую этот API использовать напрямую.
          при отправке сообщения в консоли можно использовать несколько строк,
          но при использовании mesg $User /server:server message такого функционала нет :( ентер там не катит…

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.