Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


четверг, 17 августа 2017 г.

Adtool и встроенная убунта в win10

В феврале 2017 я коротко рассказал о найденных мной утилитах для работы с AD и WMI из линукса.
Там же есть вполне реальный пример, где я ищу владельцев компьютеров. С тех пор прошло около полугода, мой боевой потрёпанный винсервер-2003 (на рабочем месте) заставили сменить на win10. Не скажу, что оно меня сильно радует, но после апгрейда до 1703 интерфейс выглядит достаточно удобным (я сказал "достаточно удобным", а не просто "удобным" - это значит, что в нем уже можно работать, матерясь не через каждую минуту, а не чаще чем раз в полчаса-час), и появилась отличная штука - "Подсистема Linux для Windows":

sergei@cnt300022:~/bin$ uname -a
Linux cnt300022 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux

sergei@cnt300022:~/bin$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial

Не буду подробно останавливаться на этой подсистеме, скажу лишь, что она доступна только для 64-битных версий, и что на нее без особых проблем можно ставить и обновлять софт из убунтийско-дебиановых репозиториев. При наличии работающего икс-сервера можно запускать и графические задачи (все 4 видимых приложения запущены из "встроенной" убунты для демонстрационных целей):


Однако, лично мне эта возможность пока без особой надобности, а вот возможность писать и отлаживать скрипты в баше - очень полезна. Чем я и занялся, решая свои повседневные задачи. В данном случае я снова решил довести до ума скрипт, выдергивающий из AD связи между компами и пользователями.

Возможно, кому-нибудь пригодятся и использованные приемы работы со строками, которые я применил в этом скрипте, но о которых не догадался в феврале.

#!/bin/bash
# Выгребаем из AD имена компов и находим их владельцев

# Для элегантности используем переменные и константы вместо длинных выражений.
COMPS_FILE=/tmp/comps-list.txt
OUT_COMPS_FILE=/tmp/comps_out.csv

# В моем домене все компы имеют вид cnt30xxxx, где cnt30 - постоянная часть, а

# xxx ::= [0-9]{3}[0-9a-z]{1} для рабочих станций и typ[0-9]{3} для других типов железа
# Однако, разные типы компов могут жить в разных OU, поэтому вместо "list" использую "search"

# Для удобства дальнейшей обработки найденное приводим к верхнему регистру
adtool search name cnt30*|grep -iE ^cn=cnt30[0-9]{3}[0-9a-z],|tr [:lower:] [:upper:]|sort>$COMPS_FILE


# Поскольку вывожу я всё это в подобие CSV, то сначала пишем строку заголовка
echo \"Comp DN\"\;\"Comp CN
\"\;\"UAC\"\;\"Managed by\"\;\"Description\">$OUT_COMPS_FILE

# А дальше стандартный скучный цикл построчного чтения из созданного чуть выше списка
while read COMP_NAME; do

# Поскольку attributeget работает по CN, а не по DN, но при этом search возвращает именно DN,

# то надо из DN как-то выделить CN. 
# Так можно и работает - так же я делал и в феврале, выкусывая слева "cn=", а справа всё
# после первой запятой
#    PURE_NAME=$(echo ${COMP_NAME/CN\=/}|sed "s/\,.*//")
# Но можно и так (берем 9 знаков, начиная с третьего, нумерация с нуля):
# cn=cnt300000
# 0123456789AB
    PURE_NAME=${COMP_NAME:3:9}

# Не уверен, может ли attributeget получать сразу несколько атрибутов, вероятно - нет,

# так что работаем по старинке: 1 переменная хранит 1 атрибут
    COMP_DESC=$(adtool attributeget $PURE_NAME description)

# Здесь тоже надо выделить чистое CN из прочитанного DN, но имя пользователя имеет неизвестную
# длину, поэтому выбираем его универсальным, хотя и более медленным способом
    COMP_MGBY=$(adtool attributeget $PURE_NAME managedby|sed "s/CN=//;s/\,.*//")

# Меня не очень волнует, есть ли атрибут managedBy у заблокированных компов, но раз в списке
# будут они все, то добавим столбец, показывающий состояние учётки.
# За признак enabled/disabled отвечает бит со значением 0b10 или 0d2, сделаем с ним AND
# и точно будем знать: если 0, значит учетка активна, если 2 - заблокирована
    COMP_UAC=$(( $(adtool attributeget $PURE_NAME UserAccountControl) & 2 ))

# Осталось только всё это красиво вывести
    echo \"$COMP_NAME\"\;\"$PURE_NAME\"\;\"$COMP_UAC\"\;\"$COMP_MGBY\"\;\"$COMP_DESC\"
done <$COMPS_FILE >>$OUT_COMPS_FILE

exit

Во время работы скрипта будут, скорее всего, появляться сообщения типа "error: Error in ldap_get_values for ad_get_attribute:no values found for attribute managedby in object CN=CNT306552,OU=330,OU=Comps,OU=Domain Root Entry,DC=CONTOSO,DC=MS,DC=ru", это нормально - они выводятся на stderr, а наш вывод через stdout падает сразу в файл, так что чистить выходной файл от мусора не понадобится.

На выходе получим вполне приятный CSV вроде:

"Comp DN";"CompCN";"UAC";"Managed by";"Description"
...
"CN=CNT30002A,OU=330,OU=COMPS,OU=DOMAIN ROOT ENTRY,DC=CONTOSO,DC=MS,DC=RU";"CNT30002A";"2";"Сергей Павлович";"убитый комп"
"CN=CNT30002B,OU=330,OU=COMPS,OU=DOMAIN ROOT ENTRY,DC=CONTOSO,DC=MS,DC=RU";"CNT30002B";"0";"Сергей Павлович";"тестовая Win10"

Комментариев нет:

Отправить комментарий

Пожалуйста, воздержитесь от грубостей и персональных нападок.
Я не против матерщины, но она должна быть уместной и использоваться для выражения эмоций, а не в качестве основного средства выражения мыслей.