PDA

Показать полную графическую версию : Powershell GUI и создание пользователей в AD


Charg
04-01-2019, 14:10
Начинаю понемногу изучать Powershell, и решил сразу сделать что-то полезное - например делегировать создание учетки в AD отделу HR.
Поскольку давать доступ к серверам им, понятное дело, никто не будет - решил сделать такую схему:
1. гуй на павершеле всю введенную инфу экспортирует в csv.
2. со стороны сервера второй скрипт импортирует этот csv и распихивает все ранее введенные данные по параметрам к командлету new-aduser.
И в итоге мне остается только включить учетку, опционально присвоить пароль, раздать права и т.д. А все задрочки "как там правильно называется должность вот этого человека которого надо добавить в АД" отпадут.

В общем нашел такой сайтец https://poshgui.com/Editor, накидал примерную форму.
Но так и не понял как достать введенное в TextBox значение и использовать его далее?

Kazun
04-01-2019, 14:50
Смотреть, как устроены примеры:

1. Arposh
http://blog.richprescott.com/2011/10/arposh-new-user-creation-anuc.html
https://github.com/RichPrescott/UserCreation

http://2.bp.blogspot.com/-sQOJw2LgV80/TokIccZVoQI/AAAAAAAAAEU/_5bXouqs4bY/s1600/ANUCv0.2CSV.png

2. Z-Hire
Z-Hire Active Directory, Exchange, Lync, Office 365 User Creation Tool - https://gallery.technet.microsoft.com/office/Z-Hire-Employee-Provisionin-e4854d6b

http://i1.gallery.technet.s-msft.com/office/z-hire-employee-provisionin-e4854d6b/image/file/85698/1/zhire_active_directory_2.png

Charg
04-01-2019, 15:36
Kazun, второй вариант не на павершеле а первый строит GUI с помощью XML. В принципе тоже вариант, попробую и так, но он менее удобен тем что придется всё вручную писать.
Но исходный вопрос остается открытым - как работать с введенным в TextBox значением?
Может под спойлер картинки то?


Чтоб говорить предметно - вот есть такая формочка:
<# This form was created using POSHGUI.com a free online gui designer for PowerShell
.NAME
Untitled
#>

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '350,250'
$Form.text = "Form"
$Form.TopMost = $false

$TextBox = New-Object system.Windows.Forms.TextBox
$TextBox.multiline = $false
$TextBox.text = "Textbox content"
$TextBox.width = 100
$TextBox.height = 20
$TextBox.location = New-Object System.Drawing.Point(150,50)
$TextBox.Font = 'Microsoft Sans Serif,10'

$label = New-Object system.Windows.Forms.Label
$label.text = "useless text"
$label.AutoSize = $true
$label.width = 25
$label.height = 10
$label.location = New-Object System.Drawing.Point(150,100)
$label.Font = 'Microsoft Sans Serif,10'

$Button1 = New-Object system.Windows.Forms.Button
$Button1.text = "button"
$Button1.width = 60
$Button1.height = 30
$Button1.location = New-Object System.Drawing.Point(174,194)
$Button1.Font = 'Microsoft Sans Serif,10'
$Button1.Add_Click({ fApply })

function fApply {
$Form.TextBox.text = $Form.label.text
}

$Form.controls.AddRange(@($TextBox,$label,$Button1))
$Form.ShowDialog()

По задумке как это должно работать - есть TextBox, в нём уже введен полезный текст "Textbox content".
Ниже есть Label в котором написано useless text. По нажатию на кнопку "useless text" должен поменяться на "Textbox content"
Павершелл выдает ошибку:
The property 'text' cannot be found on this object. Verify that the property exists and can be set.
At line:39 char:4
+ $Form.label.text = $Form.TextBox.text
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound

Kazun
04-01-2019, 16:45
function fApply {
$Label.text = $TextBox.text
}

Serguei Kouzmine
04-01-2019, 17:02
5 лет назад написал статью в codeproject про разные windows forms, wpf и повершел - посмотрите может что пригодится - 130 k views :-)
http://www.codeproject.com/Articles/799161/Dealing-with-Powershell-Inputs-via-Basic-Windows-F

Iska
04-01-2019, 18:29
Павершелл выдает ошибку: »
Так нет у формы, на которую ссылается переменная $Form, свойств label и textbox. Вы можете, например, дать имена надписи и полю ввода в основной части кода (задать свойства .Name у надписи и поля ввода):
$TextBox.Name = "MyTextBox"

$label.Name = "MyLabel"
а в функции обработки ссылаться на элементы управления по этим заданным именам, наподобие:
function fApply {
$Form.Controls.Item("MyLabel").text = $Form.Controls.Item("MyTextBox").text
}

Busla
05-01-2019, 11:40
Поскольку давать доступ к серверам им, понятное дело, никто не будет »
по-моему, вы не понимаете как работает AD
и как следствие не стоит браться автоматизировать то, что непонятно как работает

1. гуй на павершеле всю введенную инфу экспортирует в csv. »
а чего бы им не заполнять табличку в привычном excel, вместо сомнительного самопального GUI?

Charg
05-01-2019, 13:01
по-моему, вы не понимаете как работает AD
и как следствие не стоит браться автоматизировать то, что непонятно как работает »
А по-моему - понимаю.
Ну либо конструктивнее как-нибудь, пожалуйста.

а чего бы им не заполнять табличку в привычном excel»
Потому что контент экселя еще парсить нужно, в то время как в результате экспорта и импорта в\из csv павершел работает с объектом; далее в ячейку можно записать всякое разное ненужное, файлик можно случайно удалить, и куча других причин. Короче говоря - защита от дурака.

вместо сомнительного самопального GUI? »
Изначально задачи автоматизировать процесс нет. Я этим занялся чтобы Powershell изучить, на примере какого-нибудь реального мини-проекта который бы в работе помогал и по мере углубления в PS дорабатывался\оптимизировался\переделывался.
И я прекрасно понимаю что уже есть решения, что они работают, что они отлаженные и более функциональные. Но если просто скачать какой-то скрипт из интернета и запустить даблкликом - ничему не научишься.

Busla
05-01-2019, 16:22
Charg, чтобы вносить изменения в AD не нужно по RDP конектиться к контроллеру домена
Если компьютер в домене и пользователь - доменный - у него уже все необходимые "доступы к серверам". И даже (по умолчанию) права на создание некоторых новых объектов в домене.

контент экселя еще парсить нужно, в то время как в результате экспорта и импорта в\из csv »
Приложение excel прекрасно умеет сохранять данные в формат csv

в ячейку можно записать всякое разное ненужное, файлик можно случайно удалить, и куча других причин. Короче говоря - защита от дурака »
csv генерируемый вашим скриптом очевидно "можно случайно удалить" ровно так же ;-)
равно как и в поле формы вписать ненужное
вообще надеяться на проверку в форме - наивно. Нужно проверять корректность именно файла, и в нём ещё раз прочекать корректность/допустимость всех значений.

Charg
05-01-2019, 17:32
чтобы вносить изменения в AD не нужно по RDP конектиться к контроллеру домена
Если компьютер в домене и пользователь - доменный - у него уже все необходимые "доступы к серверам". »
Я в курсе, просто так выразился для краткости.
И даже (по умолчанию) права на создание некоторых новых объектов в домене. »
А вот этого я не знал. Какие объекты и в каком контейнере могут создавать простые пользователи по умолчанию?
csv генерируемый вашим скриптом очевидно "можно случайно удалить" ровно так же ;-) »
Ну, фактически права есть, да, но если скрипт запускается пользователем с ярлыка на рабочем столе - маловероятно что кто-то полезет смотреть на содержимое скрипта и выискивать по какому пути сохраняется этот csv.
равно как и в поле формы вписать ненужное
вообще надеяться на проверку в форме - наивно. Нужно проверять корректность именно файла, и в нём ещё раз прочекать корректность/допустимость всех значений. »
Почему нужно проверять именно файл? Я вот вижу только минусы.
Юзер, введя какое-то недопустимое значение в форму, должен сразу увидеть о том что что-то не так и ввести вместо этого корректное значение, что говорит о том что проверка на ввод в форме должна быть. А раз она там есть - какой смысл дублировать её еще и на импортирующей стороне?

DJ Mogarych
05-01-2019, 20:15
А не проще делегировать кадровикам создание пользователей в AD и поставить им на компьютеры RSAT?

Charg
05-01-2019, 21:03
DJ Mogarych, проще, но как я уже упомянул - цель не делегировать задачу, а научиться в павершелл путем решения какой-нибудь задачи - и эта просто подвернулась под руку.

Charg
06-01-2019, 14:59
Как создавать такие элементы?
Как ComboBox и TextBox только без возможности туда что-то вписать (ну и чтоб визуально было понятно что написать туда ничего нельзя.
https://i.imgur.com/I3wrSmg.png

Kazun
06-01-2019, 15:33
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName PresentationFramework
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '400,400'
$Form.text = "Form"
$Form.TopMost = $false

$TextBox = New-Object system.Windows.Forms.TextBox
$TextBox.multiline = $false
$TextBox.text = "ReadOnly Text"
$TextBox.width = 100
$TextBox.height = 20
$TextBox.location = New-Object System.Drawing.Point(150,50)
$TextBox.Font = 'Microsoft Sans Serif,10'
$TextBox.ReadOnly = $true

$ComboBox = New-Object system.Windows.Forms.ComboBox
$ComboBox.text = "comboBox"
$ComboBox.width = 100
$ComboBox.height = 20
$ComboBox.location = New-Object System.Drawing.Point(150,81)
$ComboBox.Font = 'Microsoft Sans Serif,10'
$ComboBox.DropDownStyle = "DropDownList"
$ComboBox.Items.AddRange(@(
"One","Two","Three","Four"
))

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Point(150, 120)
$Button.Size = New-Object System.Drawing.Size(98, 23)
$Button.Text = "Output"
$Button.add_Click({[System.Windows.MessageBox]::Show($ComboBox.SelectedItem.ToString())})

$Form.controls.AddRange(@($ComboBox,$TextBox,$Button))
$Form.ShowDialog()

Iska
07-01-2019, 01:32
Я бы токмо заменил:
$ComboBox.DropDownStyle = "DropDownList" »
на:
$ComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
дабы зараз привыкать к правильному стилю написания и пониманию, откуда сие берётся.

YuS_2
07-01-2019, 07:33
привыкать к правильному стилю написания »
На паре форм ни привыкнуть, ни понять, наверное, не получится... тут мануалы по Windows Forms (WF) читать придется, как минимум. А ему сейчас на смену дабпиэф (https://docs.microsoft.com/ru-ru/dotnet/framework/wpf/getting-started/) продвигают с более продвинутыми возможностями и функционалом, хотя пока ещё и схожим с WF. Но, как обычно, микрософт поплевал в сторону старой наработки, ибо трудозатратно развивать, и сказал, что будет исправлять и поддерживать, но обновлять и добавлять - ни-ни... такшта, лучше уж сразу на WPF замахиваться, если уж и изучать. :)

Iska
09-01-2019, 05:41
Почему нужно проверять именно файл? Я вот вижу только минусы. »
Проверять данные нужно как на этапе ввода из формы, так и сам файл перед внесением изменений в AD. Последнее можно исключить только в одном случае — если Вы, не генерируя никакого файла, зараз отрабатываете внесение изменений в AD непосредственно из формы.

Charg
14-01-2019, 14:55
Как лучше всего экспортировать данные введенные в гуй пользователями в csv?
Я себе это изначально представлял так:
function fButtonClick {

# user-defined variables
[string]$name = $givenNameTextBox.text
[string]$surname = $snTextBox.text
[string]$fullname = "$surname $name"
[string]$title = $titleTextBox.text
[string]$dept = $departmentTextBox.text
[string]$company = $companyTextBox.text
[string]$login = $loginTextBox.text
[string]$emailaddress = "$login" + "@" + "$domainoption1"
[string]$upn = "$login$domainsuffix"

$ADParams = @{
Path = $ADPath
Name = $fullname
GivenName = $name
Surname = $surname
DisplayName = $fullname
Company = $company
Department = $dept
Title = $title
SamAccountName = $login
EmailAddress = $emailaddress
UserPrincipalName = $upn
}
# save user with all params as an object inside csv
New-ADUser @ADParams -PassThru | Export-Csv -Path ("$exportPath"+'\'+"$login"+".csv") -Encoding UTF8

}
В результате (как мне хотелось) - появлялись бы по 1-му *.csv файлу на пользователя с именем login.csv.
Но так оно не работает. Проблема в том что командлет new-aduser пробует добавить пользователя в любом случае (для того он всё-таки и нужен), а уже потом если указана опция -passthru - дополнительно шлет данные дальше по конвейеру. И получается что если у пользователя, запускающего скрипт, есть права на добавления пользователя в AD - пользователь добавляется (и шаг с экспортом\импортом становится бессмысленным), а если нету - выдает ошибку (и до экспорта дело не доходит).
Выходит я выбрал неправильный подход к экспорту данных о пользователе. А какие еще могут быть варианты?
Экспортировать я хочу объект со свойствами (1 объект = 1 пользователь), которые в дальнейшем пойдут на вход командлету new-aduser в импортирующий скрипт.

Или шаг с экспортом\импортом вообще тухлая идея и нужно просто нужным людям раздать права на добавление пользователей в AD, поставить им RSAT (чтоб модуль содержащий командлеты для работы с AD установился) и пусть добавляют напрямую из GUI в AD? Так вроде много проще но... я не знаю какие могут быть подводные камни.




© OSzone.net 2001-2012