Показать полную графическую версию : [решено] Сопоставление сотрудников из 1С учетным записям в AD
Прошу помочь по возможности в решении задачи:
Есть csv-выгрузка из 1С такого вида:
Фамилия;Имя;Отчество;ТН;ДР;СНИЛС;Организация;Подразделение;Должность;Дата приема;Дата увольнения
Пупкин;Василий;Алибабаевич;0009876543;19.02.1966;888-777-666 55;ООО "Рога и копыта";Бухгалтерия;шредерщик;08.07.2000
и есть учетные записи в AD с displayname вида "Василий А. Пупкин".
Учитывая, что в домене отчество обозначено только первым символом, а в выгрузке полностью, то возможны совпадения при сравнении, т.к. в выгрузке есть еще , например, сотрудник "Пупкин Василий Алексеевич".
Необходимо очистить выгрузку от неуникальных в этом отношении записей, т.е. в данном случае удалить обоих Пупкиных, и дополнить очищенную выгрузку графой "samaccountname", заполнив ее соответствующими данными из AD (если есть).
Все учетные записи в AD находятся в OU Domain\Сотрудники. CSV в win-кодировке.
Учитывая, что в домене отчество обозначено только первым символом, »
Просто при создании пользователей администратор был ленив, чтобы вводить составляющую «О» (из ФИО) в «Выводимое имя» полностью.
Просто при создании пользователей администратор был ленив, чтобы вводить составляющую «О» (из ФИО) в «Выводимое имя» полностью. »
История умалчивает, почему админы в учетных записях не забивали отчество полностью, однако учетных записей уже более 2000, а порядок навести надо бы.
IvanXXL, рано или поздно отчество придётся вносить полностью.
рано или поздно отчество придётся вносить полностью. »
Так ведь поэтому и попросил помощи, если хотя бы половину удастся сопоставить, то я кучу времени сэкономлю.
А если по существу, то вы лично можете мне помочь в решении сформулированной задачи?
ТН;ДР;СНИЛС;Организация;Подразделение;Должность;Дата приема;Дата увольнения - Атрибуты в AD требуется угадать, если есть дублирующие записи?
Подразделение;Должность - Присутствуют в AD?
Текущая структура в AD - это свалка, которую еще мне предстоит разгрести. Там привязаться не к чему. Выводимое имя - это единственное, чему можно сейчас доверять. Поэтому дубли имен из выгрузки надо отбрасывать. Их надо будет вручную выверять. Поля выгрузки, кроме имени, отчества и фамилии, в решении текущей задачи использовать не предполагалось, они потребуются впоследствии для актуализации информации в AD после сопоставления сотрудников с учетными записями.
$result = Import-Csv users.csv -Delimiter ";" |
Group {"{0} {1} {2}" -f $_.Имя,$_.Отчество[0],$_.Фамилия} | Where {$_.Count -eq 1} | Foreach {
$name = $_.Name
$sam = (Get-ADUser -Filter "DisplayName -eq '$name'").SamAccountName
if(Get-ADUser -Filter "DisplayName -eq '$name'") {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue $sam -PassThru
}
else {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue "" -PassThru
}
}
Kazun, если не сложно, то прошу прокомментировать работу кода, в частности мне непонятна строка "$name = $_.Name".
1) Import-Csv users.csv -Delimiter ";" - Импортируем данные из CSV
2) Далее передаем по конвейеру командлету Group-Object, для поиска объектов, которые получаются одинаковые при приведении к виду Василий А Пупкин(если требуется Василий А. Пупкин - то изменить на "{0} {1}. {2}").
PS > Import-Csv users.csv -Delimiter ";" | Group {"{0} {1}. {2}" -f $_.Имя,$_.Отчество[0],$_.Фамилия}
Count Name Group
----- ---- -----
2 Василий А. Пупкин {@{Фамилия=Пупкин; Имя=Василий; Отчество=Алибабаевич; ТН=0009876543; ДР=19.02.1966
1 Адексааа А. Бульба {@{Фамилия=Бульба; Имя=Адексааа; Отчество=Алибабаевич; ТН=0009876543; ДР=19.02.1966
3) Далее передаем по конвейеру и фильтруем уникальные элементы.
PS Import-Csv 1.csv -Delimiter ";" | Group {"{0} {1}. {2}" -f $_.Имя,$_.Отчество[0],$_.Фамилия} | Where{ $_.Count -eq 1}
Count Name Group
----- ---- -----
1 Адексааа А. Бульба {@{Фамилия=Бульба; Имя=Адексааа; Отчество=Алибабаевич; ТН=0009876543; ДР=19.02.1966;...
4) $name = $_.Name - Будет содержать Адексааа А. Бульба(текущий элемент в конвейере)
5) $sam = (Get-ADUser -Filter "DisplayName -eq '$name'").SamAccountName - Производим поиск в AD и пробуем получить свойство SamAccountName
6) Дальше, случайно , добавил лишнюю проверку. if(Get-ADUser -Filter "DisplayName -eq '$name'") - Достаточно if($sam)
7) $_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue $sam -PassThru - Добавляем новое свойство к объекту
$result = Import-Csv users.csv -Delimiter ";" |
Group {"{0} {1}. {2}" -f $_.Имя,$_.Отчество[0],$_.Фамилия} | Where {$_.Count -eq 1} | Foreach {
$name = $_.Name
$sam = (Get-ADUser -Filter "DisplayName -eq '$name'").SamAccountName
if($sam) {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue $sam -PassThru
}
else {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue "" -PassThru
}
}
PS > $result
Фамилия : Иванов
Имя : Иван
Отчество : Иванович
ТН : 0009876543
ДР : 19.02.1966
СНИЛС : 888-777-666 55
Организация : ООО "Рога и копыта"
Подразделение : Бухгалтерия
Должность : шредерщик
Дата приема : 08.07.2000
Дата увольнения :
SamAccountName : iivanov
Kazun, спасибо за подробные комментарии.
Но возникла одна проблема: на контроллере домена не установлены веб-службы AD. Возможно заменить командлет Get-ADUser на Get-QADUser?
Конечно возможно:
(Get-QADUser -DisplayName $name).SamAccountName
Kazun, спасибо за подсказку.
Я отказался от русских имен в заголовках:
было
Фамилия;Имя;Отчество;ТН;ДР;СНИЛС;Организация;Подразделение;Должность;Дата приема;Дата увольнения
стало
LastName;Name1;Name2;ID;Birthday;SNILS;Organization;Department;Role;Employment;Dismissal
Выполняю вот такой скрипт:
cls
$path="d:\_ps\1s-AD"
$result = Import-Csv $path\users.csv -Delimiter ";" |
Group {"{0} {1} {2}" -f $_.Name1,$_.Name2[0],$_.LastName} | Where {$_.Count -eq 1} | Foreach {
$name = $_.Name
$sam = (Get-QADUser -DisplayName $name).SamAccountName
if($sam) {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue $sam -PassThru
}
else {
$_.Group | Add-Member -NotePropertyName SamAccountName -NotePropertyValue "" -PassThru
}
}
$result|export-csv $path\filtered-users.csv -Delimiter ";" -Encoding Default
Получаю такие сообщения об ошибках:
Add-Member : Не удается найти параметр, соответствующий имени параметра "NotePropertyName".
D:\_ps\1s-AD\0.ps1:11 знак:43
+ $_.Group | Add-Member -NotePropertyName <<<< SamAccountName -NotePropertyValue "" -PassThru
+ CategoryInfo : InvalidArgument: (:) [Add-Member], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.AddMemberCommand
Export-Csv : Не удается привязать аргумента к параметру "InputObject", так как он имеет значение NULL.
D:\_ps\1s-AD\0.ps1:14 знак:19
+ $result|export-csv <<<< $path\filtered-users.csv -Delimiter ";" -Encoding Default
+ CategoryInfo : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportCsvCommand
Что не так?
Использовал версию V3,для V2:
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value $sam -PassThru
Kazun,
Не успеваю за прогрессом! :)
А по существу: огромное спасибо за помощь! Небольшое дополнение: для корректного поиска нужна была точка после инициала отчества тут:
Group {"{0} {1}. {2}" -f $_.Name1,$_.Name2[0],$_.LastName} | Where {$_.Count -eq 1} | Foreach {Вопрос решен - тему можно считать закрытой.
Итоговый скрипт:
cls
$path="d:\_ps\1s-AD"
$result = Import-Csv $path\users.csv -Delimiter ";" |
Group {"{0} {1}. {2}" -f $_.Name1,$_.Name2[0],$_.LastName} | Where {$_.Count -eq 1} | Foreach {
$name = $_.Name
$sam = (Get-QADUser -DisplayName $name).SamAccountName
if($sam) {
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value $sam -PassThru
}
else {
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value "" -PassThru
}
}
$result|export-csv $path\filtered-users.csv -Delimiter ";" -Encoding Default
Kazun, еще раз спасибо за помощь в решении.
Но если не сложно, то, так сказать "для расширения кругозора" подскажи, как выглядел бы скрипт, если бы не требовалось очищать выгрузку от неуникальных записей "Имя О. Фамилия", но поиск в AD осуществлялся бы только для уникальных записей "Имя О. Фамилия"?
Group {"{0} {1}. {2}" -f $_.Name1,$_.Name2[0],$_.LastName} | Foreach {
if($_.Count -eq 1) {
$name = $_.Name
$sam = (Get-QADUser -DisplayName $name).SamAccountName
if($sam) {
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value $sam -PassThru
}
else {
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value "" -PassThru
}
}
else {
$_.Group | Add-Member -MemberType NoteProperty -Name SamAccountName -Value "неуникальный" -PassThru
}
}
Kazun, ну и последний гипотетический вопрос: как можно организовать поэтапную работу скрипта, на каждом этапе обрабатывая записи с фамилиями только на одну букву (А, Б, В...) из единого файл-источника?
Делайте двойное группирование.
$data = Import-Csv $path\users.csv -Delimiter ";"
$al = $data | Group {$_.LastName[0]} | Sort Name
Kazun, Делайте двойное группирование. »
Можно немного поподробнее? Я не понял, как это реализуется.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.