Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/29: Рейтинг темы: голосов - 29, средняя оценка - 4.52
 Аватар для mutaborio
1 / 1 / 0
Регистрация: 06.10.2017
Сообщений: 39

Поиск пользователя в корневом домене леса

29.05.2018, 18:29. Показов 5851. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго вечера всем!
Накидал сценарий для удобства просмотра свойств учетных записей пользователей (сроки действия УЗ и пароля, участие в группах и др.) в одном списке, с возможностью copy/paste в иные места. Для поиска одно поле: УЗ или ФИО польностью (разделять ФИО не стал, чтобы максимально конкретизировать результат, т.к. очень много пользователей - лес всероссийский).
Все работает, пока не попадается пользователь внешнего предприятия, которые "сидят" в корневом домене - их не находит. Поиск таких пользователей не частый, поэтому обходился оснасткой Active Directory, но хотелось допилить использование одного инструмента. Дописал, но где-то ошибся, завис, не могу понять. По прежнему убежден, что для PS нет ничего невозможного, ну может за редким исключением.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
Import-Module -Name ActiveDirectory
Clear-Host
Write-Host "Ждите..."
$Default = @("domen1","domen2") #массив имен доменов для поиска по умолчанию
 
Add-Type -assembly System.Windows.Forms
#Формирование основной формы
$main_form = New-Object System.Windows.Forms.Form
$main_form.Text ='Свойства учетных данных пользователя'
$main_form.Width = 340
$main_form.Height = 600
$main_form.AutoSize = $true
$Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell.exe")
$main_form.Icon = $Icon
$main_form.AutoSizeMode = "GrowAndShrink" #или GrowOnly
$main_form.MinimizeBox = $False
$main_form.MaximizeBox = $False
$main_form.StartPosition = "CenterScreen" #CenterScreen, Manual, WindowsDefaultLocation, WindowsDefaultBounds, CenterParent
$main_form.Topmost = $true
 
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "ФИО (полностью) или учетная запись пользователя:"
$Label1.Location  = New-Object System.Drawing.Point(10,10)
$Label1.AutoSize = $true
$main_form.Controls.Add($Label1)
 
$TextBox = New-Object System.Windows.Forms.TextBox
$TextBox.Text = '' #поле для поиска
$TextBox.Location  = New-Object System.Drawing.Point(10,30)
$TextBox.Width = 300
$main_form.Controls.Add($TextBox)
 
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "Домены для поиска"
$Label2.Location  = New-Object System.Drawing.Point(10,60)
$Label2.AutoSize = $true
$main_form.Controls.Add($Label2)
 
$Forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() #текущий лес
#Формирование группы объектов CheckBox по количеству доменов леса
$Position = 80
$N = 1
$CheckBox = @{} #хэш таблица доменов леса для объектов CheckBox
ForEach ($Domain in $Forest.Domains | Sort Name){
    If ($Domain.Parent -match $Forest) { #исключение корневого домена
        $CheckBox.$N = New-Object System.Windows.Forms.CheckBox
        $CheckBox.$N.Text = $Domain.Name.Substring(0,$Domain.Name.IndexOf("."+$Forest.Name)).ToUpper() #отсечение родительского суффикса
        $CheckBox.$N.AutoSize = $true
        If ($CheckBox.$N.Text -in $Default) {$CheckBox.$N.Checked = $true} #отмтка доменов из массива значений по умолчанию
        #If ($Default -contains $CheckBox.$N.Text) {$CheckBox.$N.Checked = $true}
                Else {$CheckBox.$N.Checked = $false}
        $CheckBox.$N.Location  = New-Object System.Drawing.Point(10,$Position)
        $main_form.Controls.Add($CheckBox.$N)
        $Position += 20
        $N++
        }
    }
 
$SelectButton = New-Object System.Windows.Forms.Button
$SelectButton.Location = New-Object System.Drawing.Point(20,500)
$SelectButton.Text = 'Выделить все'
$SelectButton.AutoSize = $True
$SelectButton.DialogResult = [System.Windows.Forms.DialogResult]::Yes
$main_form.AcceptButton = $SelectButton
$main_form.Controls.Add($SelectButton)
 
$DefaultButton = New-Object System.Windows.Forms.Button
$DefaultButton.Location = New-Object System.Drawing.Point(120,500)
$DefaultButton.Text = 'По умолчанию'
$DefaultButton.AutoSize = $True
$DefaultButton.DialogResult = [System.Windows.Forms.DialogResult]::No
$main_form.AcceptButton = $DefaultButton
$main_form.Controls.Add($DefaultButton)
 
$SearchButton = New-Object System.Windows.Forms.Button
$SearchButton.Location = New-Object System.Drawing.Point(220,500)
$SearchButton.Text = 'Поиск'
$DefaultButton.AutoSize = $True
$SearchButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$main_form.AcceptButton = $SearchButton
$main_form.Controls.Add($SearchButton)
 
$main_form.Add_Shown({$TextBox.Select()})
 
Clear-Host
:Select While (($result -ne [System.Windows.Forms.DialogResult]::OK) -or ($TextBox.Text -eq '')) { #ожидание действий пользователя
    $result = $main_form.ShowDialog()
    If ($result -eq [System.Windows.Forms.DialogResult]::Yes) { #действие на выделение всех доменов
        $NN = 1
        Do {
            $CheckBox.$NN.Checked = $True
            $NN++
            }
        While ($NN -ne $N)
        Continue
        }
    If ($result -eq [System.Windows.Forms.DialogResult]::No) { #действие на восстановление значений по умолчанию
        $NN = 1
        Do {
            If ($CheckBox.$NN.Text -in $Default) {$CheckBox.$NN.Checked = $true}
            #If ($Default -contains $CheckBox.$NN.Text) {$CheckBox.$NN.Checked = $true}
                    Else {$CheckBox.$NN.Checked = $false}
            $NN++
            }
        While ($NN -ne $N)
        Continue
        }
    If ($result -eq [System.Windows.Forms.DialogResult]::Cancel) { #действие на закрытие формы
        Clear-Host
        Write-Host "Выполнение прервано!"
        Return
        }
    If ($TextBox.Text -eq '') { #действие на поиск пустого значения в поле для поиска
        Write-Host "Введите данные для поиска!"
        }
    }
[void]{Break Select}
 
$Select = @() #массив имен окончательно выделенных доменов
$UName = $TextBox.Text
$NN = 1
Do {
    If ($CheckBox.$NN.Checked -eq $True) {$Select += $CheckBox.$NN.Text}
    $NN++
    }
While ($NN -ne $N)
 
Write-Host "Выполняется поиск..."
ForEach ($Domain in $Select){
    $User = Get-ADUser -filter{(Name -like $UName) -or (SamAccountName -eq $UName)} -Server "$Domain.$Forest" -Properties *
    $User | Select-Object -Property @{n="Полное имя"; e={$_.Name}},
                                    @{n="Организация | Отдел"; e={$_.Company + " | " + $_.Department}},
                                    @{n="Домен\Учетная запись"; e={$Domain + "\" + $_.SamAccountName}},
                                    @{n="УЗ активна | Срок УЗ истекает"; e={[Convert]::ToString($_.Enabled) + " | " + [Convert]::ToString($_.AccountExpirationDate)}},
                                    @{n="Пароль истек | Последняя смена"; e={[Convert]::ToString($_.PasswordExpired) + " | " + [Convert]::ToString($_.PasswordLastSet)}},
                                    @{n="Запрет смены | Срок не ограничен"; e={[Convert]::ToString($_.CannotChangePassword) + " | " + [Convert]::ToString($_.PasswordNeverExpires)}},
                                    @{n="Последняя авторизация"; e={$_.LastLogonDate}},
                                    #@{n="Ветвь AD"; e={$_.DistinguishedName.Split(",")[1].Remove(0,3) + ", " + $_.DistinguishedName.Split(",")[2].Remove(0,3)}},
                                    @{n="Участник AD групп"; e={($_.MemberOf | Get-ADGroup -Server "$Domain.$Forest" | Sort Name | ForEach {$_.Name}) -join "`n"}} | Format-List
    }
 
If ($User -eq $Null) { #если поиск не дал результата
    
    #формирование формы запроса дополнительного поиска
    $form = New-Object System.Windows.Forms.Form
    $form.Text ='Внимание!'
    $form.Width = 300
    $form.Height = 100
    $form.AutoSize = $true
    $form.Icon = $Icon
    $form.AutoSizeMode = "GrowAndShrink" #или GrowOnly
    $form.MinimizeBox = $False
    $form.MaximizeBox = $False
    $form.StartPosition = "CenterScreen" #CenterScreen, Manual, WindowsDefaultLocation, WindowsDefaultBounds, CenterParent
    $form.Topmost = $true
     
    $Label_1 = New-Object System.Windows.Forms.Label
    $Label_1.Text = "Пользователь $UName не найден в доменах:"
    $Label_1.Location  = New-Object System.Drawing.Point(10,10)
    $Label_1.AutoSize = $true
    $form.Controls.Add($Label_1)
 
    $Label_2 = New-Object System.Windows.Forms.Label
    $Label_2.Text = "$Select"
    $Label_2.Location  = New-Object System.Drawing.Point(10,30)
    $Label_2.AutoSize = $true
    $form.Controls.Add($Label_2)
        
    $Label_3 = New-Object System.Windows.Forms.Label
    $Label_3.Text = "Выполнить поиск в корневом домене леса $Forest ?"
    $Label_3.Location  = New-Object System.Drawing.Point(10,50)
    $Label_3.AutoSize = $true
    $form.Controls.Add($Label_3)
    
    $YesButton = New-Object System.Windows.Forms.Button
    $YesButton.Location = New-Object System.Drawing.Point(20,70)
    $YesButton.Text = 'Да'
    $YesButton.AutoSize = $True
    $YesButton.DialogResult = [System.Windows.Forms.DialogResult]::Yes
    $form.AcceptButton = $YesButton
    $form.Controls.Add($YesButton)
    
    $NoButton = New-Object System.Windows.Forms.Button
    $NoButton.Location = New-Object System.Drawing.Point(190,70)
    $NoButton.Text = 'Нет'
    $NoButton.AutoSize = $True
    $NoButton.DialogResult = [System.Windows.Forms.DialogResult]::No
    $form.AcceptButton = $NoButton
    $form.Controls.Add($NoButton)
    
    $result = $form.ShowDialog()
    
    If ($result -eq [System.Windows.Forms.DialogResult]::Yes) { #действия для поиска в корневом домене леса
        Write-Host "Выполняется дополнительный поиск..."
        $Domain = Get-ADDomain -Server $Forest.RootDomain
        $User = Get-ADUser -filter{(Name -like $UName) -or (SamAccountName -eq $UName)} -Server "$Domain" -Properties *
        $User | Select-Object -Property @{n="Полное имя"; e={$_.Name}},
                                        @{n="Организация | Отдел"; e={$_.Company + " | " + $_.Department}},
                                        @{n="Домен\Учетная запись"; e={$_.Name + "\" + $_.SamAccountName}},
                                        #@{n="Домен\Учетная запись"; e={(Get-ADDomain -Server $_.Name | ForEach {$_.NetBIOSName}) + "\" + $_.SamAccountName}},
                                        @{n="УЗ активна | Срок УЗ истекает"; e={[Convert]::ToString($_.Enabled) + " | " + [Convert]::ToString($_.AccountExpirationDate)}},
                                        @{n="Пароль истек | Последняя смена"; e={[Convert]::ToString($_.PasswordExpired) + " | " + [Convert]::ToString($_.PasswordLastSet)}},
                                        @{n="Запрет смены | Срок не ограничен"; e={[Convert]::ToString($_.CannotChangePassword) + " | " + [Convert]::ToString($_.PasswordNeverExpires)}},
                                        @{n="Последняя авторизация"; e={$_.LastLogonDate}},
                                        #@{n="Ветвь AD"; e={$_.DistinguishedName.Split(",")[1].Remove(0,3) + ", " + $_.DistinguishedName.Split(",")[2].Remove(0,3)}},
                                        @{n="Участник AD групп"; e={($_.MemberOf | Get-ADGroup -Server "$Domain" | Sort Name | ForEach {$_.Name}) -join "`n"}} | Format-List
        }
        ElseIf ($result -eq [System.Windows.Forms.DialogResult]::No) { #действия при отмене или закрытии формы
            Write-Host "Выполнение прервано!"
            Break
            }
    }
Ошибки скорее всего в строках 195, 196.
И подтормаживает при формировании главной формы в строках 43-57
Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.05.2018, 18:29
Ответы с готовыми решениями:

Имя пользователя в домене
Как узнать имя пользователя с помощью которого был выполнен вход в домен на текущем компьютере не обладая правами админа? И можно ли это...

Установка программ в домене с правами пользователя
Добрый день. Такая ситуация: комп в домене (Компьютеры домена), пользователь (Пользователи домена) захожу из под пользователя на сайт...

Назначение прав (контроль) пользователя в домене
1. Создал Подразделение; 2. Прикрепил свежую GPO; 3. Отредактировал отображение имени последнего входящего пользователя. Политики...

8
 Аватар для KDE777
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
29.05.2018, 18:54
Цитата Сообщение от mutaborio Посмотреть сообщение
Все работает, пока не попадается пользователь внешнего предприятия, которые "сидят" в корневом домене - их не находит.
Использовать поиск сразу в GC (global catalog) не пробовали?

PowerShell
1
Get-ADUser -Filter {SamAccountName -eq 'ivanov'} -Server "dc1.mydomain.ru:3268"
0
 Аватар для mutaborio
1 / 1 / 0
Регистрация: 06.10.2017
Сообщений: 39
30.05.2018, 12:49  [ТС]
PowerShell
1
2
$LocalGC =$Forest.Name” + “:3268”
Get-ADUser -Filter {(Name -like $UName) -or (SamAccountName -eq $UName)} -Server "$LocalGC"
Не удается установить связь с сервером. Возможные причины: сервер не существует, выключен или на нем не запущены веб-службы Active Directory.,Microsoft.ActiveDirectory.Man agement.Commands.GetADUser
0
 Аватар для KDE777
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
30.05.2018, 13:08
Цитата Сообщение от mutaborio Посмотреть сообщение
Не удается установить связь с сервером
Вместо $Forest.Name напишите fqdn-имя ближайшего к вас DC с ролью GC

Добавлено через 1 минуту
и вместо [System.DirectoryServices.ActiveDirectory .Forest]::GetCurrentForest() есть штатный Get-ADForest + имеется Get-DomainController

Добавлено через 9 минут
и вот тут, у вас явно что-то не то написано

PowerShell
1
2
3
$Forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$Domain = Get-ADDomain -Server $Forest.RootDomain
$User = Get-ADUser -Server "$Domain"
В "$Domain" - будет DN корня вашего леса, а ключ -Server предназначен для имени домена или для имени DC. Если же нужно указать DN путь, тогда используется ключ -SearchBase

PowerShell
1
2
man Get-ADUser -Parameter Server
man Get-ADUser -Parameter SearchBase
0
 Аватар для mutaborio
1 / 1 / 0
Регистрация: 06.10.2017
Сообщений: 39
30.05.2018, 16:14  [ТС]
Если я не ошибаюсь, так я получу ближайший DC с ролью GC?
PowerShell
1
$DomainGC = (Get-ADForest) | %{Get-ADDomainController -Discover -Service "GlobalCatalog"}
0
 Аватар для KDE777
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
30.05.2018, 16:29
Цитата Сообщение от mutaborio Посмотреть сообщение
Если я не ошибаюсь, так я получу ближайший DC с ролью GC?
PowerShell
1
2
$DomainGC = (Get-ADDomainController -Discover -Service "GlobalCatalog").HostName.Value + ':3268'
Get-ADUser -filter{SamAccountName -eq 'ivanov'} -Server $DomainGC
1
 Аватар для mutaborio
1 / 1 / 0
Регистрация: 06.10.2017
Сообщений: 39
30.05.2018, 17:13  [ТС]
Я издалека начал, т.к. перепробовал несколько комбинация и решил пошагово разобраться. Ваш код тоже дает нулевой результат.
Видимо, я не все описал. В оснастке AD пользователь внешнего предприятия находится, класс объекта "Контакт", УЗ в полях "Эл.почта" и "Каноническое имя", ФИО в поле "Выводимое имя".
Пробовал фильтры УЗ и ФИО -like по полям: EmailAddress, CanonicalName, DisplayName и на всякий случай mail, mailNickname, UserPrincipalName, targetAddress, SamAccountName, Name, CN.
0
 Аватар для KDE777
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
30.05.2018, 17:33
Цитата Сообщение от mutaborio Посмотреть сообщение
класс объекта "Контакт"
Тогда с чего вы взяли, что нужно искать с помощью Get-ADUser???

Добавлено через 4 минуты
PowerShell
1
Get-ADObject -filter {DisplayName -eq 'Иван Иванов' -and ObjectClass -eq 'Contact'} -Server $DomainGC
Добавлено через 48 секунд
Или используйте Exchange командлет - Get-Contact

Добавлено через 3 минуты
Для поиска сразу пользователей или контактов:

PowerShell
1
Get-ADObject -filter {DisplayName -eq 'Иван Иванов' -and ObjectClass -eq 'Person'} -Server $DomainGC
или Exchange командлет - Get-Recipient
1
 Аватар для mutaborio
1 / 1 / 0
Регистрация: 06.10.2017
Сообщений: 39
30.05.2018, 17:48  [ТС]
У меня эти командлеты отсутствуют. Попробую directoryservices.directorysearcher

Добавлено через 9 минут
Пардон за невнимательность, с этим можно работать дальше:
Цитата Сообщение от KDE777 Посмотреть сообщение
PowerShell
1
Get-ADObject -filter {DisplayName -eq 'Иван Иванов' -and ObjectClass -eq 'Contact'} -Server $DomainGC
Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.05.2018, 17:48
Помогаю со студенческими работами здесь

Заставка на экране выборе пользователя в домене
Доброго времени суток. Появилась у меня необходимость отключить заставку (скринсэйвер) на экране выбора пользователя на вин XP в...

Windows 7 в домене - нет доступа к изменению разрешений пользователя
Нужна помошь win7 в домене нет доступа к изменению разрешений пользователя После переустановки windows (Win2003) на servere и создание AD...

Управление сервером Hyper-v в домене, из клиента, находящего в другом домене
Доброго времени суток. Ситуация такая. Сама архитектура глупой может быть получилась но так надо, перегуглил уже все что можно но...

поиск пользователя в домене
как реализовать такой поиск? у меня есть фио пользователя на кириллице, буду его переводить в латиницу и искать Имя (RDN) пользователя в...

Поиск остовного леса методом Соллина
Доброго времени суток. Передо мной встала задача найти остовной лес минимальной стоимости методом Соллина. Интернет предложил единственный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru