Powershell for Windows

18.01.2011

Определяем логин пользователя по его SID средствами MS SQL.

У администратора БД (Microsoft Dynamics NAV), возникла задача выдавать/проверять наличие роли SQL db_datareader для некоторых работников. Но в таблице список пользователей хранился в виде SID windows: S-1-5-21-3879… и записи постоянно добавлялись, т.е.  необходимо было конвертировать из S-1-5-21-38… → aapetrov.
Серверов было около 70-ти и хотелось все сделать стандартными средствами. Как и положено начал с гугла — ничего полезного не нашел. Обратился за помощью на форум sql.ru. Было предложено множество вариантов, за что огромное спасибо добрым людям, но увы, решение так и не было найдено. И вот на грани нервного срыва, проблему все-таки удалось разрешить.

Для начала немного теории. Разберем SID (S-1-5-21-3879291865-2298129343-1096376209-3741) по частям:

  • S — говорит нам о том, что это именно SID;
  • 1 — уровень контроля;
  • 5 — полномочие идентификатора;
  • 21 — первое подчиненное полномочие идентификатора;
  • 3879291865, 2298129343 и 1096376209 — остальные подчиненные полномочия идентификатора, все вместе они обозначают домен или компьютер, который издал идентификатор SID;
  • 3741 — относительный идентификатор.

Более подробно о можно почитать тут.

Теперь сам скрипт. Лучше всего создать функцию, а потом просто вызывать ее с параметром:

--Проверяем существует ли функция, если да то удаляем и создаем.

IF OBJECT_ID (N'dbo.StringSIDToLogin', N'FN') IS NOT NULL
DROP FUNCTION dbo.StringSIDToLogin
GO
CREATE FUNCTION dbo.StringSIDToLogin (@MYSID AS VARCHAR(255))
RETURNS VARCHAR(300)
AS
BEGIN

--получаем бинарное значение

DECLARE @A AS BIGINT ,@B AS BIGINT ,@C AS BIGINT ,@D AS BIGINT
SET @MYSID = REVERSE(@MYSID)
SET @D = REVERSE(SUBSTRING(@MYSID,1,CHARINDEX('-',@MYSID)-1))
SET @MYSID = SUBSTRING(@MYSID,CHARINDEX('-',@MYSID)+1,255)
SET @C = REVERSE(SUBSTRING(@MYSID,1,CHARINDEX('-',@MYSID)-1))
SET @MYSID = SUBSTRING(@MYSID,CHARINDEX('-',@MYSID)+1,255)
SET @B = REVERSE(SUBSTRING(@MYSID,1,CHARINDEX('-',@MYSID)-1))
SET @MYSID = SUBSTRING(@MYSID,CHARINDEX('-',@MYSID)+1,255)
SET @A = REVERSE(SUBSTRING(@MYSID,1,CHARINDEX('-',@MYSID)-1))
declare @sid_sql VARBINARY(100)
DECLARE @StrLogin VARCHAR(100)
set @sid_sql= 0x010500000000000515000000
+ CONVERT(VARBINARY,REVERSE(CONVERT(BINARY(4),@A)))
+ CONVERT(VARBINARY,REVERSE(CONVERT(BINARY(4),@B)))
+ CONVERT(VARBINARY,REVERSE(CONVERT(BINARY(4),@C)))
+ CONVERT(VARBINARY,REVERSE(CONVERT(BINARY(4),@D)))

--теперь с помощью стандартной функции MS SQL находим логин и убираем префикс домена

set @StrLogin=SUSER_SNAME(@sid_sql)
set @StrLogin=REPLACE (@StrLogin,'dom\','')
RETURN (@StrLogin)
END
GO
Осталось только вызвать функцию:

SELECT dbo.StringSIDToLogin('S-1-5-21-1106671424-631848431-2339101832-7032') AS [Login]

Как оказалось всё просто. Саму идею подсказали на форуме.

автор: antonick

25.09.2009

Импорт контактов из другого домена

Filed under: PowerShell, Windows — Метки: , , , , , , , , — Yamshikov Pavel @ 8:01 дп

Когда у вас работает Active Directory и почтовая система Exchange, то пользователи получают глобальную адресную книгу, в которой есть почтовые адреса всех пользователей AD и всех почтовых контактов заведенных в AD. Это очень удобно: достаточно набрать в Outlook-е фамилию и адрес будет найден автоматически или предложены варианты.

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

Для синхронизации лесов (доменов) существуют специальные приложения. Например, Microsoft Identity Lifecycle Manager (ILM) или его предыдущая версия Microsoft Identity Integration Server (MIIS). Это мощние универсальные продукты, которые позволяют синхронизировать учетные записи, их свойства, пароли, сертификаты и все остальные атрибуты, позволяют гибко настраивать списки синхронизируемых объектов и их атрибутов, правила разрешения конфликтов и т.д. С помощью этих продуктов можно решить поставленную задачу. Вот только они платные и сложные. И в простых случаях, как наш, нет необходимости их использовать – можно обойтись досточно простым скриптом.

Вот пример простого скрипта на Powershell, который импортирует учетные записи пользователей как контакты из другого домена. Для выполнения скрипта нужно иметь права на создание контактов в родном домене и права на чтение учетных записей во втором домене. Вы можете легко изменить список атрибутов, которые синхронизируются этим скриптом по аналогии.

Вот сам скрипт:

$base = [ADSI]»LDAP://ou=Contacts, ou=DEP,dc=domain,dc=ru»

$users = (new-object System.DirectoryServices.DirectorySearcher([ADSI]»LDAP://ou=DEP1,dc=domain1,dc=ru»,»(&(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(title=*)))»)).findAll()

$users | ForEach-Object {

$_ = $_.GetDirectoryEntry()
$NewContact = $base.Create(«contact»,»cn=» + $_.cn)

$NewContact.SetInfo()

$NewContact.extensionAttribute15 = $base.distinguishedName

$NewContact.displayname = $_.displayname
$NewContact.givenname = $_.givenname
$NewContact.sn = $_.sn
$NewContact.initials = $_.initials
$NewContact.description = $_.description

$NewContact.department = $_.department
$NewContact.title = $_.title
$NewContact.company = $_.company

$NewContact.telephoneNumber = $_.telephoneNumber
$NewContact.othertelephone = $_.othertelephone

$NewContact.ipPhone = $_.ipPhone
$NewContact.otherIpPhone = $_.otherIpPhone

$NewContact.mobile = $_.mobile
$NewContact.otherMobile = $_.otherMobile

$NewContact.facsimileTelephoneNumber = $_.facsimileTelephoneNumber
$NewContact.otherfacsimileTelephoneNumber = $_.otherfacsimileTelephoneNumber

if ($_.proxyaddresses) {

$NewContact.proxyaddresses = $_.proxyaddresses
$NewContact.targetAddress = $_.proxyaddresses -clike «SMTP:*»
$NewContact.mailNickname = $_.cn

}

$NewContact.SetInfo()

}

Источник

Блог на WordPress.com.