Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Присвоить каждому компьютеру инвентарный номер на основе сайта и порядка (http://forum.oszone.net/showthread.php?t=336428)

c4uran 28-08-2018 09:26 2828890

Присвоить каждому компьютеру инвентарный номер на основе сайта и порядка
 
Есть множество сайтов: MSK, SPB, NSK (около 20)

На каждом сайте есть около сотни компьютеров в AD

Необходимо каждому компьютеру присвоить инвентарный номер формата: (001,002,003...), при этом на каждом сайте номера начинаются заново с 001

У каждого компьютера есть свойство в AD - @{extensionAttribute1 = MSK}(или spb или nsk) а @{extensionAttribute2 = 001}

Нужно, чтобы скрипт каждому компьютеру выдал порядковый номер на основании атрибута1 и самое сложное: если компьютер в атрибуте2 уже содержит порядковый номер то он не выдавал этот номер другому компьютеру


Например:
Имя Атрибут1 Атрибут2
Comp1, MSK, ea2=004
Comp2, MSK, ea2=<пусто>
Comp3, MSK, ea2=001
Comp4, MSK, ea2=<Непонятная строка>
Comp5, SPB, ea2=<пусто>
Comp6, SPB, ea2=001
...

После прохождения скрипта:

Имя Атрибут1 Атрибут2
Comp1, MSK, ea2=004
Comp2, MSK, ea2=002
Comp3, MSK, ea2=001
Comp4, MSK, ea2=003
Comp5, SPB, ea2=002
Comp6, SPB, ea2=001

Kazun 28-08-2018 09:43 2828892

Код:

Get-ADComputer -Filter "extensionAttribute1 -like '*'" -Properties extensionAttribute1,extensionAttribute2 | Group-Object extensionAttribute1 | Foreach {
        $ex2 = $_.Group | Where {$_.extensionAttribute2 -match "^\d{3}$"} | Foreach-Object {$_.extensionAttribute2}
        $start = 0
        $id = "$start".PadLeft(3,'0')
        $_.Group | Where {$_.extensionAttribute2 -notmatch "^\d{3}$"} | Foreach-Object {
                do {
                    $start++
                    $id = "$start".PadLeft(3,'0')
                } while($ex2 -contains $id)
                Set-ADComputer $_ -Replace @{extensionAttribute2=$id}
        }
}


c4uran 28-08-2018 10:11 2828896

Сижу уже минут пять туплю в код, словно повершел впервой вижу

а что значит эта строка:

$ex2 = $_.Group | Where {$_.extensionAttribute2 -match "^\d{3}$"} | Foreach-Object {$_.extensionAttribute2}

Как оно потом заходит в while не могу понять

Kazun 28-08-2018 10:18 2828899

Код:

$ex2 = $_.Group | Where {$_.extensionAttribute2 -match "^\d{3}$"} | Foreach-Object {$_.extensionAttribute2}
  1. Where {$_.extensionAttribute2 -match "^\d{3}$"} - Только строки удовлетворяющие шаблону 000..999
  2. Foreach-Object {$_.extensionAttribute2} - получить значение атрибута extensionAttribute2
  3. $ex2 - содержит все текущие используемые значения extensionAttribute2 из сайта, в while идет проверка, есть значение в $ex2,уже используется, добавить единичку

c4uran 28-08-2018 10:46 2828902

Оставил в выборке 7 тестовых компьютеров,
в результате скрипт перезаписывает атрибуты поверх уже имеющихся, нужно чтобы он не менял те что есть

Первый атрибут везде SPB

было
name attrib2
SPB-COMP-003 <не задано>
SPB-COMP-004 <не задано>
SPB-COMP-005 <не задано>
SPB-COMP-006 005
SPB-COMP-007 001
SPB-COMP-008 <не задано>
SPB-COMP-010 <не задано>

Первый запуск:
SPB-COMP-003 002
SPB-COMP-004 003
SPB-COMP-005 004
SPB-COMP-006 006
SPB-COMP-007 007
SPB-COMP-008 008
SPB-COMP-010 009

На второе выполнение:
SPB-COMP-003 001
SPB-COMP-004 005
SPB-COMP-005 010
SPB-COMP-006 011
SPB-COMP-007 012
SPB-COMP-008 013
SPB-COMP-010 014

Третье
SPB-COMP-003 002
SPB-COMP-004 003
SPB-COMP-005 004
SPB-COMP-006 006
SPB-COMP-007 007
SPB-COMP-008 008
SPB-COMP-010 009

Kazun 28-08-2018 10:50 2828903

$_.Group | Foreach-Object заменить строку на :
Код:

$_.Group | Where {$_.extensionAttribute2 -notmatch "^\d{3}$"} | Foreach-Object

Busla 28-08-2018 11:13 2828911

Kazun, нумерация будет дублироваться

c4uran 28-08-2018 11:15 2828912

Спасибо, работает, это круто...

c4uran 29-08-2018 10:08 2829092

Kazun, Можешь помочь адаптировать этот скрипт чтобы он выполняясь на локальной машине выдавал свободный инвентарный номер основываясь на Атрибуте1(берется из переменной(ее получает другой скрипт)) и основываясь на уже имеющихся Атрибуте2 в AD

Например уже есть в AD компьютеры:
Код:

Имя        Атрибут2 Атрибут1
SPB-COMP-003 002        SPB
SPB-COMP-004 003        SPB
SPB-COMP-005            SPB
MSK-COMP-006            MSK
SPB-COMP-007 007        SPB
SPB-COMP-008            SPB
SPB-COMP-010 009        SPB

Когда я выполняю скрипт на компьютере SPB-COMP-005, то скрипт возвращает значение 001
Когда я выполняю скрипт на компьютере MSK-COMP-006, то скрипт возвращает значение 001
Когда я выполняю скрипт на компьютере SPB-COMP-008, то скрипт возвращает значение 004

Это нужно для автоматизации получения имени компьютера перед вводом в домен

Kazun 29-08-2018 10:22 2829100

Заранее создать учетную запись компьютера с уже заданными Атрибут1 и Атрибут2, а не городить подобные решения.

c4uran 29-08-2018 10:47 2829107

Kazun, Так мы же про автоматизацию, имена компьютеров сложные и содержат инфу из компьютера, там серийники, типы итп, чтобы ручками ничего не нужно было делать, помоги пожалуйста...

Kazun 29-08-2018 11:29 2829121

Т.к. локальный комптьютер не в домене, то требуется указать $DomainDN,$Site для которого осуществляется поиск и учетную запись,которая имееет доступ к Active Directory.

Код:

# Атрибуте1(берется из переменной(ее получает другой скрипт))
$site = "...."

#Учетные данные для подключения к Active Directory
$Credential = New-Object System.Management.Automation.PSCredential('UserName', (ConvertTo-SecureString 'Password' -Force -AsPlainText))

# Создаем ADSI Search   
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PropertiesToLoad.Add('extensionAttribute2')
# Только данные из текущего сайта
$Searcher.Filter = "(extensionAttribute1=$site)"

# Домен для подключения
$DomainDN = "LDAP://corp.contoso.com/DC=corp,DC=contoso,DC=ru"

# Подключение
$Domain = New-Object System.DirectoryServices.DirectoryEntry($DomainDN ,$Credential.UserName,$Credential.GetNetworkCredential().Password)

# Устанавливаем текущие данные подключения
$Searcher.SearchRoot = $Domain

# Делаем поиск
$All = $Searcher.FindAll()
$ex2 = $All | Where {$_.Properties["extensionAttribute2"][0] -match "^\d{3}$"} | Foreach {$_.Properties["extensionAttribute2"][0]}

# Получаем свободный ID
$Start = 0
do {
        $Start++
        $FreeId = "$Start".PadLeft(3,'0')
} while($ex2 -contains $FreeId)

$FreeID


c4uran 29-08-2018 11:44 2829124

Вываливает такое:

Код:

строка:12 знак:67
+ $Searcher = New-Object System.DirectoryServices.DirectorySearcher()
+                                                                  ~
После ''('' ожидалось выражение.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedExpression


c4uran 29-08-2018 12:51 2829147

Вложений: 1
Так ведь будет работать?:
$site = "SPB"
$server = "dc1"

а учетные данные подтягиваются из unattened файла

$All = Get-ADComputer -Filter * -Properties extensionAttribute1,extensionAttribute2 -server $server | where {$_.extensionAttribute1 -eq $site}

# Делаем поиск
#$All = $Searcher.FindAll()
$ex2 = $All | Where {$_.extensionAttribute2 -match "^\d{3}$"} | Foreach {$_.extensionAttribute2}

# Получаем свободный ID
$Start = 0
do {
$Start++
$FreeId = "$Start".PadLeft(3,'0')
} while($ex2 -contains $FreeId)

$FreeID

c4uran 10-09-2018 17:25 2830771

Разобрался со всем, осталось только строку:

Код:

Set-ADComputer $env:computername -Replace @{extensionAttribute2=$id}
Перевести в ADSI запрос

(это нужно чтобы при создании компьютера в AD скрипт сразу добавлял себе в св-ва информацию о себе)

Help?)


Время: 10:21.

Время: 10:21.
© OSzone.net 2001-