Автоматическое отключение учетных записей пользователей в домене
10 июня 2009 г.ILM 2007 предоставляет массу возможностей. Вот пример как можно отключить учётную запись пользователя в домене если пользователь не регистрировался в домене определенное количество дней.
Время регистрации записуется в атрибут lastLogontimeStamp. Оч хорошая статья в которой описывается этот атрибут в блоге Ask the DS Team.
И так нам нужно сделать две вещи
1. Настроить правило слияния для МА Active Directory:
2. Добавить код в процедуру MapAttributesForImport:
Case "useraccountcontrol"'Отключаем учетную запись если пользователь'не регистрировался в течении 120 днейIf csentry("lastLogonTimestamp").IsPresent ThenDim lastLogon As String = Date.FromFileTime(csentry("lastLogonTimestamp").Value).ToString("dd.MM.yy")Dim lastLogonDate As DateTime = Convert.ToDateTime(lastLogon)If Now.Subtract(lastLogonDate).Days > 120 _AndAlso csentry("userAccountControl").IntegerValue = ADS_UF_NORMAL_ACCOUNT Thenmventry("userAccountControl").Value = "514"Elsemventry("userAccountControl").Value = csentry("userAccountControl").ValueEnd IfElse'Если учетная запись была создана, но пользователь так и не регистрировался,'отключаем его через 15 днейDim CreatedString, year, month, day As StringDim CreateDate As DateTimeCreatedString = csentry("whenCreated").Valueyear = CreatedString.Substring(0, 4)month = CreatedString.Substring(4, 2)day = CreatedString.Substring(6, 2)CreateDate = Convert.ToDateTime(day + "." + month + "." + year)If Now.Subtract(CreateDate).Days > 15 _AndAlso csentry("userAccountControl").IntegerValue = ADS_UF_NORMAL_ACCOUNT Thenmventry("userAccountControl").Value = "514"Elsemventry("userAccountControl").Value = csentry("userAccountControl").ValueEnd IfEnd If
Тоже самое можно проделать и с учетной записью компьютера ;)
Пример внедрения ILM 2007
29 мая 2009 г.В предыдущих постах я описывал как связать разные службы каталогов при помощи ILM 2007. Здесь я объединю все заметки этой теме воедино.
Что из себя представляет ILM (Microsoft Identity Lifecycle Manager)? Состоит он из основных компонентов:
- Connected data source (подключаемые источники данных);
- Management Agents (агенты управления);
- Сonnector Spaces (пространства подключения);
- Metaverse (Метабаза).
и основные функции ILM:
- синхронизация каталогов;
- управление паролями и их синхронизация;
- управление группами;
- инициализация учетных записей;
- публикация сертификатов.
Run management agent ILM 2007
28 мая 2009 г.Мы настроили ILM 2007 для синхронизации AD c eDirectory и Sun ONE Directory. Теперь постала задача регулярно выполнять MA (management agent).
Вариант 1
Создать скрипт для каждого профиля агента.
Получим следующий скрипт:
Const PktPrivacy = 6rem Const wbemAuthenticationLevelPkt = 6Set Locator = CreateObject("WbemScripting.SWbemLocator")remrem Credentials must only be specified when Microsoft Identity Integration Server is on remote system.remrem Locator.Security_.AuthenticationLevel = wbemAuthenticationLevelPktrem Set Service = Locator.ConnectServer("MyServer", "root/MicrosoftIdentityIntegrationServer")rem Set Service = Locator.ConnectServer("MyServer", "root/MicrosoftIdentityIntegrationServer", "Domain\Me", "MyPassword")remSet Service = GetObject("winmgmts:{authenticationLevel=PktPrivacy}!root/MicrosoftIdentityIntegrationServer")Set MASet = Service.ExecQuery("select * from MIIS_ManagementAgent where Guid = '{12B4583D-C2D8-43A1-BF48-28651247DE41}'")for each MA in MASetWScript.Echo "Running " + MA.name + ".Execute(""Full Import-Full Synchronization"")..."WScript.Echo "Run completed with result: " + MA.Execute("Full Import-Full Synchronization")next
Объединив все профили всех МА в один скрипт.
Вариант 2
Воспользоваться утилитой MASequencer.exe из MIIS 2003 Resource Tool Kit, предварительно создав XML конфиг утилитой MAConfigurationViewer.exe
и запускать MASequencer.exe с параметром /F:<имя конфига>
Вариант 3
создать 2-ва скрипта. Сами скрипты взяты с примеров у Microsoft
MA-Runs.cmd:
@echo offremrem Copyright (c) Microsoft Corporation. All rights reserved.remsetlocalset zworkdir=%~dp0pushd %zworkdir%cscript runMA.vbs /m:"MA_Active_Directory" /p:"Full Import-Full Synchronization"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script)cscript runMA.vbs /m:"MA_Sun" /p:"Full Import-Full Synchronization"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script)cscript runMA.vbs /m:"MA_Novell" /p:"Full Import-Full Synchronization"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script)cscript runMA.vbs /m:"MA_Active_Directory" /p:"Export"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script)cscript runMA.vbs /m:"MA_Sun" /p:"Export"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script)cscript runMA.vbs /m:"MA_Novell" /p:"Export"if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) & (goto exit_script):exit_scriptpopdendlocal
runMA.vbs:
option expliciton error resume next'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='SCRIPT: runMA.vbs'DATE: 2003-02-05'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='= Copyright (C) 2003 Microsoft Corporation. All rights reserved.'='******************************************************************************'* Function: DisplayUsage'*'* Purpose: Displays the usage of the script and exits ths script'*'******************************************************************************Sub DisplayUsage()WScript.Echo ""WScript.Echo "Usage: runMa </m:ma-name> </p:profile-name>"WScript.Echo " [/s:mms-server-name]"WScript.Echo " [/u:user-name]"WScript.Echo " [/a:password]"WScript.Echo " [/v] Switch on Verbose mode"WScript.Echo " [/?] Show the Usage of the script"WScript.Echo ""WScript.Echo "Example 1: runMa /m:adma1 /p:fullimport"WScript.Echo "Example 2: runMa /m:adma1 /p:fullimport /u:domain\user /a:mysecret /v"WScript.Quit (-1)End Sub'******************************************************************************' Script Main Execution Starts Here'******************************************************************************'--Used Variables--------------------------dim sdim runResultdim rescodedim managementagentNamedim profiledim verbosemodedim wmiLocatordim wmiServicedim managementagentdim serverdim usernamedim password'-----------------------------------------rescode = ParamExists("/?")if rescode = true then call DisplayUsageverbosemode = ParamExists("/v")managementagentName = ParamValue("/m")if managementagentName = "" then call DisplayUsageprofile = ParamValue("/p")if profile = "" then call DisplayUsageif verbosemode then wscript.echo "%Info: Management Agent and Profile is <"& managementagentName &":"& profile &">"if verbosemode then wscript.Echo "%Info: Getting WMI Locator object"set wmiLocator = CreateObject("WbemScripting.SWbemLocator")if err.number <> 0 thenwscript.echo "%Error: Cannot get WMI Locator object"wscript.quit(-1)end ifserver = ParamValue("/s")password = ParamValue("/a")username = ParamValue("/u")if server = "" then server = "." ' connect to WMI on local machineif verbosemode thenwscript.Echo "%Info: Connecting to MMS WMI Service on <" & server &">"if username <> "" then wscript.Echo "%Info: Accessing MMS WMI Service as <"& username &">"end ifif username = "" thenset wmiService = wmiLocator.ConnectServer(server, "root/MicrosoftIdentityIntegrationServer")elseset wmiService = wmiLocator.ConnectServer(server, "root/MicrosoftIdentityIntegrationServer", username, password)end ifif err.number <> 0 thenwscript.echo "%Error: Cannot connect to MMS WMI Service <" & err.Description & ">"wscript.quit(-1)end ifif verbosemode then wscript.Echo "%Info: Getting MMS Management Agent via WMI"Set managementagent = wmiService.Get( "MIIS_ManagementAgent.Name='" & managementagentName & "'")if err.number <> 0 thenwscript.echo "%Error: Cannot get Management Agent with specified WMI Service <" & err.Description & ">"wscript.quit(-1)end ifwscript.echo "%Info: Starting Management Agent with Profile <"& managementagent.name &":"& profile &">"runResult = managementagent.Execute(profile)if err.number <> 0 thenwscript.Echo "%Error: Running MA <"& err.Description & ">. Make sure the correct profile name is specified."wscript.quit(-1)end ifwscript.Echo "%Info: Finish Running Management Agent"wscript.Echo "%Result: <" & CStr(runResult) & ">"wscript.quit(0)'******************************************************************************'* Function: ParamValue'*'* Purpose: Parses the command line for an argument and'* returns the value of the argument to the caller'* Argument and value must be seperated by a colon'*'* Arguments:'* [in] parametername name of the paramenter'*'* Returns:'* STRING Parameter found in commandline'* "" Parameter NOT found in commandline'*'******************************************************************************Function ParamValue(ParameterName)Dim i '* CounterDim Arguments '* Arguments from the command-line commandDim NumberofArguments '* Number of arguments from the command-line commandDim ArgumentArray '* Array in which to store the arguments from the command-lineDim TemporaryString '* Utility string'* Initialize Return Value to e the Empty StringParamValue = ""'* If no ParameterName is passed into the function exitif ParameterName = "" then exit function'* Check if Parameter is in the Arguments and return the valueSet Arguments = WScript.ArgumentsNumberofArguments = Arguments.Count - 1For i=0 to NumberofArgumentsTemporaryString = Arguments(i)ArgumentArray = Split(TemporaryString,":",-1,vbTextCompare)If ArgumentArray(0) = ParameterName ThenParamValue = ArgumentArray(1)exit functionEnd IfNextend Function'******************************************************************************'* Function: ParamExists'*'* Purpose: Parses the command line for an argument and'* returns the true if argument is present'*'* Arguments:'* [in] parametername name of the paramenter'*'* Returns:'* true Parameter found in commandline'* false Parameter NOT found in commandline'*'******************************************************************************Function ParamExists(ParameterName)Dim i '* CounterDim Arguments '* Arguments from the command-line commandDim NumberofArguments '* Number of arguments from the command-line commandDim ArgumentArray '* Array in which to store the arguments from the command-lineDim TemporaryString '* Utility string'* Initialize Return Value to e the Empty StringParamExists = false'* If no ParameterName is passed into the function exitif ParameterName = "" then exit function'* Check if Parameter is in the Arguments and return the valueSet Arguments = WScript.ArgumentsNumberofArguments = Arguments.Count - 1For i=0 to NumberofArgumentsTemporaryString = Arguments(i)If TemporaryString = ParameterName ThenParamExists = trueexit functionEnd IfNextend Function
И запускаем MA-Runs.cmd
Какой бы вариант мы не выбрали, нужно создать scheduled job и запускать от имени пользователя являющимся членом группы MIISOperators
Clear history MA MISS and ILM 2007
26 мая 2009 г.После настройки ILM 2007, нужно периодически очищать историю выполнения MA (агента управления). Вся история хранятся в базе данных, и логично чем больше записей - больше база ILM.
Мы воспользуемся утилитой miisclearrunhistory.exe из MIIS 2003 Resource Tool Kit для очистки истории.
miisclearrunhistory.exe /pr: <кол-во дней > /y
Создаем пользователя и включаем в группу MIISOperators, от его имени будем запускать scheduled job и пусть выполняется ночью.
Postfix-Dovecot-Sun Direcory Server
21 мая 2009 г.Была поставлена задача создать почтовую систему и связать ее с Active Directory, но если служба каталогов не будет доступна по какой-то причине, пользователям не будет доставляться почта. И мы решили развернуть еще одну службу каталогов. Выбор остановили на SUN ONE Directory Server. Он бесплатный, документация отличная и что немало важно управлять ним можно через WEB или java консоль, а синхронизировать Active Direcory и Sun Direcory мы будем с помощью ILM 2007 (Microsoft Identity Lifecycle Manager).
Microsoft Identity and Access Management Series
18 мая 2009 г.Документы которые признаны помочь лучше разобраться как работает ILM, как правильно настроить ILM и т.д. В общем прежде чем начать настраивать ILM (Microsoft Identity Lifecycle Manager) рекомендую ознакомиться. Все это находится тут
Clear Metavares tables ILM 2007
5 мая 2009 г.Для полной очистки базы ILM выполняем следующие:
1. открываем SQL Query Analyzer и коннектимся к SQL серверу где расположена база MicrosoftIdentityIntegrationServer
2. выполняем следующий скрипт:
TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_connectorspace;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_cs_link;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_csmv_link;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_joiner_log;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_metaverse;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_metaverse_lineagedate;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_metaverse_lineageguid;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_metaverse_multivalue;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_mv_link;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_run_history;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_step_history;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_step_object_details;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_tracking_entries;TRUNCATE TABLE MicrosoftIdentityIntegrationServer.dbo.mms_tracking_entries_history;
3. рестарт службы MIIS Service.
После таких действий очистится вся база включая логи, конфигурация же останется без изменений.
ILM 2007 синхронизация пользователей AD и eDirectory
26 февраля 2009 г.Настраиваем MA (Management Agent) для Active Directory:
- Properties - Тут все понятно….
- Connect to AD Forest - комментарии лишние
- Configure Dir Partitions – В Containers выберем контейнеры с пользователями которые мы собираемся синхронизировать. В Password Synch отмечаем Enable this partition as a password synch. если мы собираемся синхронизировать пароли и в Targets выберем МА NetWare когда его создадим. (о настройке синхронизации паролей можно прочитать на TechNet)
- Select Object Types – Выберем нужные типы объектов
- Select Attributes – Отмечаем нужные атрибуты
- Confugure Connector Filter – нам пока не нужен
- Configure Join and Projection Rules
- Confugure Attribute Flow – Настройка соответствия атрибутов которые мы хотим импортировать и экспортировать из AD в Metaverse
Тут стоит обратить внимание на AD атрибут UserAccountControl, дело в то что он принимает значения, а в eDirectory атрибут loginDisabled, который отвечает за то включена или отключена учетная запись, принимает значения “True” или “False”. Что бы все корректно работало и состояние учетной записи пользователя (откл. или вкл.) синхронизировало между AD и eDir, делаем следующие:
- Создаем атрибут Boolean в Metaverse Desinger например msDS-UserAccountDisabled
- Указываем UserAccountControl импортировать в msDS-UserAccountDisabled, но при этом Mapping Type укажем Advanced и укажем Flow rule name
Эго мы будем использовать в ADExtension.dll которую мы укажем в Configure Extension
Public Sub MapAttributesForImport(ByVal FlowRuleName As String, ByVal csentry As CSEntry, ByVal mventry As MVEntry) Implements IMASynchronization.MapAttributesForImport
' TODO: write your import attribute flow code
Const ADS_UF_ACCOUNTDISABLE As Integer = &H2 'Disable user account
Const ADS_UF_NORMAL_ACCOUNT As Integer = &H200 'Typical user account
Select Case FlowRuleName
Case "msDS-UserAccountDisabled"
mventry("msDS-UserAccountDisabled").BooleanValue = (csentry("userAccountControl").IntegerValue And ADS_UF_ACCOUNTDISABLE) = ADS_UF_ACCOUNTDISABLE
End Select
End Sub
Настройка МА для eDir аналогична AD вот только не нужно в Configure Extension указывать DLL а указать что нужно синхронизировать пароли
и вот мой Confugure Attribute Flow
Только не забываем использовать SSL протокол для подключения к LDAP, о настройке подключения по протоколу SSL в NetWare можно посмотреть тут
И теперь чтобы все это заработало нужно в скомпелить MVExtension.dll и прописать в Options
И сам код MVExtension.dl:
Imports Microsoft.MetadirectoryServices
Imports System
Imports System.Text
Imports System.IO
Imports ActiveDs.ADS_USER_FLAG
Public Class MVExtensionObject
Implements IMVSynchronization
Public Sub Initialize() Implements IMVSynchronization.Initialize
' TODO: Add initialization code here
End Sub
Public Sub Terminate() Implements IMVSynchronization.Terminate
' TODO: Add termination code here
End Sub
Private Sub SetNovellPW(ByRef csentry As CSEntry, ByVal pw As String)
' TODO: Setting an Initial Password in eDirectory
Dim password() As Byte
password = New System.Text.UTF8Encoding(False, False).GetBytes(pw)
ReDim Preserve password(UBound(password) + 2)
csentry("userPassword").Values.Add(password)
End Sub
Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
Dim adMA As ConnectedMA
Dim csentry As CSEntry
Dim dn As ReferenceValue
Dim ExceptionMessage As String
Const eDir_OU = "ou=Account, o=TREE_eDir"
Const eDir_MA = "MA_Novell"
Const AD_MA = "MA_Active_Directory"
Const ACTIVE_OU_AD = "OU=Account,OU=Branch,DC=
Const INACTIVE_OU_AD = "OU=Disabled,OU=Account,OU=Branch, DC=
Const INACTIVE_OU_ED = "ou=Disabled,ou=Account,o=TREE_eDir"
Dim Connectors As Integer
Dim Container As String
If Not mventry("cn").IsPresent ThenExceptionMessage = "The attribute cn was unexpectedly not present on the metaverse object."
Throw New UnexpectedDataException(ExceptionMessage)
Exit Sub
End If
' +++++++++++ eDirectory ++++++++++++++++
adMA = mventry.ConnectedMAs(eDir_MA)
Container = eDir_OU
Connectors = adMA.Connectors.Count
dn = adMA.EscapeDNComponent("cn=" + mventry("cn").Value).Concat(Container)
If 0 = Connectors Then
Select Case mventry.ObjectType.ToLower()
Case "group"
csentry = adMA.Connectors.StartNewConnector("groupOfNames")
csentry.DN = dn
csentry.CommitNewConnector()
Case "person"
csentry = adMA.Connectors.StartNewConnector("inetOrgPerson")
csentry.DN = dn
csentry("groupMembership").Values.Add("cn=Everyone,ou=Account,o=TREE_eDir")
csentry("securityEquals").Values.Add("cn=Everyone,ou=Account,o=TREE_Edir")
SetNovellPW(csentry, "1Q2w3e4r5")
csentry.CommitNewConnector()
End Select
ElseIf 1 = Connectors Then
csentry = adMA.Connectors.ByIndex(0)
If csentry.DN.ToString.ToLower <> dn.ToString.ToLower Then
csentry.DN = dn
End If
Else
Throw New UnexpectedDataException("multiple connectors:" + Connectors.ToString)
End If
' +++++++++++ Active Directory ++++++++++++++++
adMA = mventry.ConnectedMAs(AD_MA)
If (mventry.ObjectType = "person") Then
If mventry("msDS-UserAccountDisabled").BooleanValue Then
Container = INACTIVE_OU_AD
dn = adMA.EscapeDNComponent("cn=" + mventry("displayName").Value).Concat(Container)
If adMA.Connectors.Count = 1 Then
'''Check if rename needed
csentry = adMA.Connectors.ByIndex(0)
If csentry.DN.ToString.ToLower <> dn.ToString.ToLower Then
csentry.DN = dn
End If
End If
End If
End If
End Sub
Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
Throw New EntryPointNotImplementedException()
End Function
End Class