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

01.06.2010

Получение списка членов локальной группы на всех компьютерах доменной сети.


function Seach-LocalGroupMemberDomenNetwork(){
param(
$Domen,
$GroupSID

)

function Ping ($Name){
$ping = new-object System.Net.NetworkInformation.Ping
if ($ping.send($Name).Status -eq "Success") {$True}
else {$False}
trap {Write-Verbose "Error Ping"; $False; continue}
}


[string[]]$Info
[string[]]$Computers


# Получам список компьютеров доменной сети
$Computers = Get-QADComputer -Service $Domen -OSName '*XP*','*Vista*','*7*' -SizeLimit 0 -ErrorAction SilentlyContinue |
Select-Object name -ExpandProperty name

foreach ($Computer in $Computers){
# Проверяем доступен компьютер или нет
$Alive = Ping $Computer
if ($Alive -eq "True"){Write-Host "Seach $Computer" -BackgroundColor Blue

# Получаем имя группы
Trap {Write-Host "Error WMI $Computer";Continue}
$GroupName = Get-WmiObject win32_group -ComputerName $Computer |
Where-Object {$_.SID -eq '$GroupSID'} |
Select-Object name -ExpandProperty name

if ($GroupName){
# Получаем список членов локальной группы
Trap {Write-Host "Error ADSI $Computer";Continue}
$Users = ([ADSI]"WinNT://$Computer/$GroupName").psbase.invoke("Members") |
% {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}

# Записываем результаты
$Info += $Users | % {$_ | Select-Object @{e={$Computer};n='Computer'},@{e={$_};n='Login'}}
}
}
}
# Вывод результатов
$Info

}

Для переменой $GroupSID данные можно найти в документе Well-known security identifiers in Windows operating systems.

Пример:

Seach-LocalGroupMemberDomenNetwork -Domen Mydomen -GroupSID S-1-5-32-544
Получаем список пользователей локальной группы администраторов на всех компьютерах домена.

Создайте бесплатный сайт или блог на WordPress.com.