<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>missmiis &#187; AD</title>
	<atom:link href="http://www.wapshere.com/missmiis/category/ad/feed" rel="self" type="application/rss+xml" />
	<link>http://www.wapshere.com/missmiis</link>
	<description>Adventures in identity management</description>
	<lastBuildDate>Fri, 03 Feb 2012 20:41:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Powershell script to generate test users in AD</title>
		<link>http://www.wapshere.com/missmiis/powershell-script-to-generate-test-users-in-ad</link>
		<comments>http://www.wapshere.com/missmiis/powershell-script-to-generate-test-users-in-ad#comments</comments>
		<pubDate>Tue, 03 Jan 2012 00:58:41 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=1823</guid>
		<description><![CDATA[I needed to set up a test AD with realistic looking test users. This script by Alex Tcherniakhovski was the type of thing I wanted as it starts with lists of OUs, first names and last names and then creates accounts across all OUs listed, and using a random selection of names.
However Alex&#8217;s script uses [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to set up a test AD with realistic looking test users. <a href="http://blogs.msdn.com/b/alextch/archive/2006/09/18/adpopulate.aspx">This script</a> by Alex Tcherniakhovski was the type of thing I wanted as it starts with lists of OUs, first names and last names and then creates accounts across all OUs listed, and using a random selection of names.</p>
<p>However Alex&#8217;s script uses Excel which I don&#8217;t have installed in my lab and don&#8217;t really want. So I&#8217;ve taken his source lists and his concept and written a little powershell script to do much the same thing.</p>
<p>You can download it from <a title="adpopulate.ps1.zip" href="http://http://www.wapshere.com/dl/adpopulate.ps1.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/powershell-script-to-generate-test-users-in-ad/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing groups from AD to the FIM Portal using classic flow rules</title>
		<link>http://www.wapshere.com/missmiis/importing-groups-from-ad-to-the-fim-portal-using-classic-flow-rules</link>
		<comments>http://www.wapshere.com/missmiis/importing-groups-from-ad-to-the-fim-portal-using-classic-flow-rules#comments</comments>
		<pubDate>Sat, 13 Nov 2010 18:41:00 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[FIM 2010]]></category>
		<category><![CDATA[Groups]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=1065</guid>
		<description><![CDATA[My general negativity about FIM codeless sync aka &#8220;declarative provisioning&#8221; aka &#8220;Synchronization Rule Provisioning&#8221; is, I think, reasonably well-known by now. While Markus wrote an excellent document about importing AD groups into the FIM Portal using the codeless rules, I think there are still plenty of reasons to go old skool, and here&#8217;s how you&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>My general negativity about FIM codeless sync aka &#8220;declarative provisioning&#8221; aka &#8220;Synchronization Rule Provisioning&#8221; is, I think, reasonably well-known by now. While Markus wrote <a href="http://social.technet.microsoft.com/wiki/contents/articles/how-do-i-synchronize-groups-from-active-directory-domain-services-to-fim.aspx?wa=wsignin1.0">an excellent document</a> about importing AD groups into the FIM Portal using the codeless rules, I think there are still plenty of reasons to go old skool, and here&#8217;s how you&#8217;d do it.</p>
<p><span id="more-1065"></span></p>
<h3>PreReqs</h3>
<p>Custom sync rules do involve .NET coding, so you&#8217;re going to need Visual Studio installed on the Sync server. My example code in is VB.NET so you&#8217;ll need the Visual Basic libraries installed to use them.</p>
<blockquote><p>And it&#8217;s only a minusculey tiny bit of code, okay?</p></blockquote>
<p>I will assume you&#8217;ve already managed to create your AD and FIM management agents, <em>and</em> that you have already sucessfully imported or joined the group members &#8211; ie the users and contacts.</p>
<p>The &#8220;member&#8221; attribute is relational, meaning it effectively points to other objects that it also knows about. To maintain the referential relationship from AD through to the FIM Portal you must satisfy the following requirements:</p>
<ul>
<li>The groups <em>and</em> their member objects must exist within the connector space of the same AD MA. You can&#8217;t import groups from one MA and users from another &#8211; you have to have the groups and users together.</li>
<li>The groups <em>and</em> their members must be joined to their metaverse counterparts, either through Join or Projection rules.</li>
<li>The groups <em>and</em> their members must be exported through the same FIM MA to the FIM Portal (though AFAIK you can only have one FIM MA anyway).</li>
</ul>
<h3>Step 1: Importing the AD Groups into the Metaverse</h3>
<p>&nbsp;</p>
<table border="1">
<tbody>
<tr>
<td>First make sure that the OU(s) containing the groups are within the scope of your MA.</td>
<td><img src="http://www.wapshere.com/images/import_groups/01%20ADMA%20containers.JPG" alt="" /></td>
</tr>
<tr>
<td>Next check the &#8220;group&#8221; object type.Note I also have my potential group member object types selected, and within the scope of the MA &#8211; see the comment above about maintaining references in the prereqs section above.</td>
<td><img src="http://www.wapshere.com/images/import_groups/02%20ADMA%20object%20types.JPG" alt="" /></td>
</tr>
<tr>
<td>And make sure the following attributes are selected: displayName, domain, groupType, member, sAMAccountName, (and for Distrubution Lists) mail, mailNickname.</td>
<td><img src="http://www.wapshere.com/images/import_groups/03%20ADMA%20attribs.JPG" alt="" /></td>
</tr>
<tr>
<td>Create a Projection Rule. This will project AD groups as new group objects in the Metaverse. Note the following points:</p>
<ol>
<li>You should also create a Join Rule so that already-projected groups may be rejoined automatically if they happen to become disconnected,</li>
<li>If you want some groups to be ignored then the simplest way is with a Connector Filter. Otherwise you can use a coded Projection Rule, but I won&#8217;t be going into that here.</li>
</ol>
</td>
<td><img src="http://www.wapshere.com/images/import_groups/04%20ADMA%20project.JPG" alt="" /></td>
</tr>
<tr>
<td>Next create Direct import flow rules for the following attributes:  displayName → displayName<br />
sAMAccountName → accountName<br />
member → member<br />
mail → mail<br />
mailNickname → mailNickname</td>
<td><img src="http://www.wapshere.com/images/import_groups/05%20ADMA%20direct%20IAF.JPG" alt="" /></td>
</tr>
<tr>
<td>At this point you can actually save the MA and go ahead and run an Import-Sync. What you should see is some group objects projected into the Metaverse.If you&#8217;ve already mapped the group object type in the FIM MA you should see objects created there too, but don&#8217;t try to export them yet, we need to add a few more attributes.</td>
<td><img src="http://www.wapshere.com/images/import_groups/06%20ADMA%20test%20projection.JPG" alt="" /></td>
</tr>
<tr>
<td>Now go back into your AD MA and add the following Advanced import flow rules:  Constant: your NETBIOS domain name → domain<br />
Constant: &#8220;Owner Approval&#8221; → membershipAddWorkflow<br />
Constant: &#8220;false&#8221; → membershipLocked<br />
groupType → Rules Extension: &#8220;import_scope&#8221; → scope<br />
groupType → Rules Extension: &#8220;import_type&#8221; → type</td>
<td><img src="http://www.wapshere.com/images/import_groups/07%20ADMA%20adv%20IAF.JPG" alt="" /></td>
</tr>
<tr>
<td>When you try and save the MA now you should get this error:<br />
&#8220;Rules Extension validation error: Please specify a valid rules extension name.&#8221;When you click OK you will be taken to the place where you can specify the name of the dll where those two advanced rules (import_scope and import_type) are to be found. In fact we haven&#8217;t written the dll yet, but that&#8217;s ok, just accept the default name.</td>
<td><img src="http://www.wapshere.com/images/import_groups/08%20extension%20name.JPG" alt="" /></td>
</tr>
<tr>
<td>Now it is time to create the extension project.Select your MA and click <strong>Create Extension Project</strong>. You want to create a project of type &#8220;Rules Extension&#8221;.Check the default name &#8211; it should be the same as already set in the MA in the previous step (if it somehow isn&#8217;t don&#8217;t worry, you can always change the dll referenced in the MA later).</p>
<p>The only thing you might want to change is the folder where the project will be created.</p>
<p>When you&#8217;re ready, click OK and the new project will be created and opened in Visual Studio for you (assuming you installed Visual Studio on the server).</td>
<td><img src="http://www.wapshere.com/images/import_groups/09%20new%20extension.JPG" alt="" /></td>
</tr>
<tr>
<td>Now fill in the MapAttributesForImport section of the project as shown here.Once you&#8217;ve done that you can compile the code. The dll shoud be put straight into the correct folder for you (normally C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\Extensions).</td>
<td>
<pre>Public Sub MapAttributesForImport(ByVal FlowRuleName As String, ByVal csentry As CSEntry,
 ByVal mventry As MVEntry) Implements IMASynchronization.MapAttributesForImport

    Select Case FlowRuleName
        Case "import_type"
            Select Case csentry("groupType").IntegerValue
                Case 2, 4, 8
                    mventry("type").Value = "Distribution"
                Case Else
                    mventry("type").Value = "Security"
            End Select

        Case "import_scope"
            Select Case csentry("groupType").IntegerValue
                Case 2, -2147483646
                    mventry("scope").Value = "Global"
                Case 4, -2147483644
                    mventry("scope").Value = "DomainLocal"
                Case Else
                    mventry("scope").Value = "Universal"
            End Select

        Case Else
            Throw New EntryPointNotImplementedException()

    End Select
End Sub</pre>
<p>&nbsp;</td>
</tr>
<tr>
<td>Now you should be able to Sync the AD MA and check how the group objects look in the Metaverse.</td>
<td><img src="http://www.wapshere.com/images/import_groups/10%20mventry.JPG" alt="" /></td>
</tr>
</tbody>
</table>
<h3>Step 2: Exporting the Groups from the Metaverse to the FIM Portal</h3>
<table border="1">
<tbody>
<tr>
<td>There are a couple of Portal MPRs that must be enabled to allow the Sync Service to create groups in the Portal.</td>
<td><img src="http://www.wapshere.com/images/import_groups/00%20FIM%20MA%20MPR.JPG" alt="" /></td>
</tr>
<tr>
<td>If you haven&#8217;t already done so, select the group object type in your FIM MA.</td>
<td><img src="http://www.wapshere.com/images/import_groups/01%20FIMMA%20object%20types.JPG" alt="" /></td>
</tr>
<tr>
<td>And add the mapping to the Metaverse group type.</td>
<td><img src="http://www.wapshere.com/images/import_groups/02%20FIMMA%20object%20mapping.JPG" alt="" /></td>
</tr>
<tr>
<td>Now all you should need to do is add simple export flow rules for these attributes: accountName, displayName, domain, scope, type, membershipAddWorkflow, membershipLocked, member, (and for Distribution groups) mail, mailNickname .</td>
<td><img src="http://www.wapshere.com/images/import_groups/03%20FIMMA%20eaf.JPG" alt="" /></td>
</tr>
<tr>
<td>Run another Sync on the AD MA and now you should be able to see the group objects in the FIM connector space, ready to export.</td>
<td><img src="http://www.wapshere.com/images/import_groups/04%20FIMMA%20csentry.JPG" alt="" /></td>
</tr>
<tr>
<td>After running an Export from the FIM MA the groups should be in the Portal, and you can start to manage them there.Note there is an error being reported about selecting a manger. If you do happen to have the group manager field populated in AD then by all means go ahead and import it from AD through to the Portal. Otherwise you will have to chose a manager directly in the Portal.</td>
<td><img src="http://www.wapshere.com/images/import_groups/05%20FIMMA%20portal.JPG" alt="" width="600" /></td>
</tr>
</tbody>
</table>
<h3>Troubleshooting FIM MA export errors</h3>
<p>The FIM MA can give you some rather cryptic looking failed-creation-via-web-services messages, but usually if you read them properly you can work out the problem.</p>
<h4>1. Missing Required Attribute</h4>
<p>Here I have forgotten to populate the &#8220;Domain&#8221; attribute</p>
<div><code>Fault Reason: The request message contains errors that prevent processing the request.</code></div>
<div><code>Fault Details: &lt;RepresentationFailures xmlns="http://schemas.microsoft.com/2006/11/ResourceManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;AttributeRepresentationFailure&gt;&lt;AttributeType&gt;<span style="background-color: yellow;">Domain</span>&lt;/AttributeType&gt;</code></div>
<div><code>&lt;AttributeValue&gt;&lt;/AttributeValue&gt;&lt;FailureMessage&gt;<span style="background-color: yellow;">An attribute is required to complete the operation.</span>&lt;/FailureMessage&gt;</code></div>
<div><code>&lt;AttributeFailureCode&gt;RequiredValueIsMissing&lt;/AttributeFailureCode&gt;&lt;/AttributeRepresentationFailure&gt;&lt;/RepresentationFailures&gt;</code></div>
<h4>2. Incorrect Attribute Value</h4>
<p>Some attributes in the Portal Schema have validation strings listing which values are allowed. Here I&#8217;ve tried to export a type of &#8220;Distribution List&#8221; instead of &#8220;Distribution&#8221;, and that has been blocked.</p>
<div><code><br />
Fault Reason: The request message contains errors that prevent processing the request.</code></div>
<p><code>Fault Details: &lt;RepresentationFailures xmlns="http://schemas.microsoft.com/2006/11/ResourceManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;AttributeRepresentationFailure&gt;&lt;AttributeType&gt;<span style="background-color: yellow;">Type</span>&lt;/AttributeType&gt;<br />
&lt;AttributeValue&gt;<span style="background-color: yellow;">Distribution List</span>&lt;/AttributeValue&gt;&lt;FailureMessage&gt;<span style="background-color: yellow;">The specified attribute value does not satisfy the regular expression.</span>&lt;/FailureMessage&gt;&lt;AttributeFailureCode&gt;ValueViolatesRegularExpression&lt;/AttributeFailureCode&gt;&lt;/AttributeRepresentationFailure&gt;&lt;/RepresentationFailures&gt;<br />
</code></p>
<h4>3. Permissions failure</h4>
<p>Your MPRs need to allow the Built-In Synchronization account to create Group objects in the Portal. In this rather long-winded messages there are a few immediate giveaways.</p>
<div><code><br />
There is an error executing a web service object creation request.<br />
Type: Microsoft.ResourceManagement.WebServices.Client.PermissionDeniedException </code></div>
<div><code>Message: Fault Reason: <span style="background-color: yellow;">Policy prohibits the request from completing.</span></code></div>
<div><code>Fault Details:</code></div>
<p>&nbsp;</p>
<div><span style="background-color: yellow;">No policy grants the Requestor permission to complete all changes.</span></div>
<p>Exception: ManagementPolicyRule<br />
Stack Trace: Microsoft.ResourceManagement.WebServices.Exceptions.PermissionDeniedException: ManagementPolicyRule &#8212;&gt; System.Data.SqlClient.SqlException: Reraised Error 50000, Level 16, State 1, Procedure DoEvaluateRequestInner, Line 462, Message: Permission denied.<br />
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)<br />
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)<br />
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)<br />
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()<br />
at System.Data.SqlClient.SqlDataReader.get_MetaData()<br />
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)<br />
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)<br />
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)<br />
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)<br />
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)<br />
at System.Data.SqlClient.SqlCommand.ExecuteReader()<br />
at Microsoft.ResourceManagement.Data.DataAccess.DoRequestCreation(RequestType request, Guid cause, Guid requestMarker, Boolean doEvaluation, Int16 serviceId, Int16 servicePartitionId)<br />
&#8212; End of inner exception stack trace &#8212;<br />
at Microsoft.ResourceManagement.WebServices.RequestDispatcher.CreateRequest(CreateRequestDispatchParameter dispatchParameter)<br />
at Microsoft.ResourceManagement.WebServices.RequestDispatcher.CreateRequest(UniqueIdentifier requestor, UniqueIdentifier targetIdentifier, OperationType operation, String businessJustification, List`1 requestParameters, CultureInfo locale, Boolean isChildRequest, Guid cause, Boolean doEvaluation, Nullable`1 serviceId, Nullable`1 servicePartitionId)<br />
at Microsoft.ResourceManagement.WebServices.RequestDispatcher.CreateRequest(UniqueIdentifier requestor, UniqueIdentifier targetIdentifier, OperationType operation, String businessJustification, List`1 requestParameters, CultureInfo locale, Boolean isChildRequest, Guid cause, Boolean doEvaluation)<br />
at Microsoft.ResourceManagement.WebServices.ResourceManagementService.Create(Message request)ManagementPolicyRule</p>
<p>Stack Trace: at Microsoft.ResourceManagement.WebServices.ResourceFactoryClient.Create(Message request)<br />
at Microsoft.ResourceManagement.WebServices.ResourceFactoryClient.Create(Create createBody)<br />
at Microsoft.ResourceManagement.WebServices.Client.ResourceTemplate.CreateResource()</p>
<p>Inner Exception: <span style="background-color: yellow;">Policy prohibits the request from completing.</span></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/importing-groups-from-ad-to-the-fim-portal-using-classic-flow-rules/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>DFS shares not accessible using domain name from Windows 7</title>
		<link>http://www.wapshere.com/missmiis/dfs-shares-not-accessible-using-domain-name-from-windows-7</link>
		<comments>http://www.wapshere.com/missmiis/dfs-shares-not-accessible-using-domain-name-from-windows-7#comments</comments>
		<pubDate>Thu, 30 Sep 2010 08:49:03 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[Windows Server 2008]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=1010</guid>
		<description><![CDATA[I was asked to have a look at a strange DFS problem today &#8211; and eventually tracked down the cause to the Windows 7 Offline Files feature.
Some users were unable to access DFS via the domain name:  The error was
"\\mydomain.com\dfs is not accessible. You might not have permission to use this network resource"
However there was [...]]]></description>
			<content:encoded><![CDATA[<p>I was asked to have a look at a strange DFS problem today &#8211; and eventually tracked down the cause to the Windows 7 Offline Files feature.<span id="more-1010"></span></p>
<p>Some users were unable to access DFS via the domain name:  The error was</p>
<pre>"\\mydomain.com\dfs is not accessible. You might not have permission to use this network resource"</pre>
<p>However there was clearly no permissions issue. The users could access the DFS shares just fine via &#8220;\\dcname\dfs&#8221;.</p>
<p>Once I tried to net view the namespace the problem became clear:</p>
<pre>net view \\mydomain.com

DFS   Disk   [Offline Share]
NETLOGON  Disk  Logon server share
SYSVOL  Disk  Logon server share</pre>
<p>Windows 7 had become completely convinced that the entire DFS was &#8220;Offline&#8221; and that appeared to be that.</p>
<p>Instead of trying to figure out why this had happened I decided to disable Offline Files. This was the next problem &#8211; I went through the Control Panel and found the message &#8220;Offline Files is currently enabled&#8221; below a greyed out &#8220;Disable offline files&#8221; button.</p>
<p>In the GPO, &#8220;Allow or Disallow the use of Offline Files&#8221; was set to &#8220;Disabled&#8221;. According to the blurb: &#8220;If you disable this setting, Offline Files is disabled and users cannot enable it.&#8221;</p>
<p>However this was patently not the case. The setting was Disabled but Offline Files was enabled on the client. (I ran the Resultant Set of Policy tool on the client to confirm it really was inheriting the GPO setting &#8211; it was.) As far as I can tell, all this setting does is disable the ability to change the state of Offline Files &#8211; without actually disabling Offline Files!</p>
<p>Finally I had to set the GPO option to &#8220;Not configured&#8221;. After that I could disable Offline Files on the client and, finally, DFS is accessible!</p>
<p>But the last irritation is that I had to unconfigure this setting in the global GPO. There is no way to override an &#8220;Enabled&#8221; or &#8220;Disabled&#8221; with a &#8220;Not Configured&#8221; at a sub-OU level.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/dfs-shares-not-accessible-using-domain-name-from-windows-7/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A GALSync powershell script</title>
		<link>http://www.wapshere.com/missmiis/a-galsync-powershell-script</link>
		<comments>http://www.wapshere.com/missmiis/a-galsync-powershell-script#comments</comments>
		<pubDate>Sat, 15 May 2010 09:05:18 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[Exchange 2003]]></category>
		<category><![CDATA[Exchange 2007]]></category>
		<category><![CDATA[Exchange 2010]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=819</guid>
		<description><![CDATA[Here is a script I wrote to do a simple GAL synchronization between two Exchange organizations. The script finds the mail-enabled  users in one domain, and creates contacts for them in the other domain. Existing contacts will also be updated and deleted as needed.

Update
There was a bug in the original script where I had forgotten to populate [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a script I wrote to do a simple GAL synchronization between two Exchange organizations. The script finds the mail-enabled  users in one domain, and creates contacts for them in the other domain. Existing contacts will also be updated and deleted as needed.<br />
<span id="more-819"></span></p>
<h4>Update</h4>
<p>There was a bug in the original script where I had forgotten to populate mailNickname. I have now done so, adding a &#8220;c-&#8221; to the front of it as a completely optional convention to avoid conflicts.</p>
<h4>Update 2</h4>
<p>Several people have commented below about needing to enable the contacts in Exchange after creation. I have used the modifcations posted by Mark in the comments to make a new version that I hope will work better with 2007 and 2010, though I have only tested it with 2010. Both versions are linked below, and please keep adding your comments and modifications.</p>
<h3>The Script</h3>
<p>Now I have two versions the scripts have been moved off to seperate pages. Follow the links below.</p>
<table border="1">
<tbody>
<tr>
<td><a href="http://www.wapshere.com/missmiis/galsync-v2">Version 2</a></td>
<td>Added the Update-Recipient command for Exchange 2007 (through local powershell) and Exchange 2010 (through remote powershell).</td>
</tr>
<tr>
<td><a href="http://www.wapshere.com/missmiis/galsync-ps1">Version 1</a></td>
<td>Original version that uses the ActiveDirectory powershell module to create the contact objects.</td>
</tr>
</tbody>
</table>
<h3>Other people&#8217;s versions</h3>
<p>Modified for Distribution Lists: <a href="http://www.wapshere.com/missmiis/galsync-v2/galsync-ps1-for-distribution-lists">http://www.wapshere.com/missmiis/galsync-v2/galsync-ps1-for-distribution-lists</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/a-galsync-powershell-script/feed</wfw:commentRss>
		<slash:comments>66</slash:comments>
		</item>
		<item>
		<title>Creating user home directories &#8211; Windows version</title>
		<link>http://www.wapshere.com/missmiis/creating-user-home-directories-windows-version</link>
		<comments>http://www.wapshere.com/missmiis/creating-user-home-directories-windows-version#comments</comments>
		<pubDate>Mon, 21 Sep 2009 09:31:19 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[ILM 2007]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=554</guid>
		<description><![CDATA[I last blogged about provisioning home directories such a long time ago that I talked about Netware. I also used a SQL table alongside to keep track of a status field as I was doing some end-of-life management &#8211; zipping up the folder and stowing it in an archive location.
But we don&#8217;t need to be [...]]]></description>
			<content:encoded><![CDATA[<p>I last blogged about provisioning home directories such a long time ago that I talked about <a href="http://www.wapshere.com/missmiis/creating-an-extensible-ma">Netware</a>. I also used a SQL table alongside to keep track of a status field as I was doing some end-of-life management &#8211; zipping up the folder and stowing it in an archive location.</p>
<p>But we don&#8217;t need to be that fancy. If all you want is to create a regular Windows-type home folder, at the same time as you create the AD user account, then here&#8217;s a way to do with an XMA.<br />
<span id="more-554"></span></p>
<h2>Overview</h2>
<p>To summarise the approach:</p>
<ol>
<li>Create the user account in AD,
<ul>
<li>Flow the SID back into the metaverse &#8211; proof the account exists,</li>
</ul>
</li>
<li>Create the home folder using an XMA,
<ul>
<li>Flow the path back into the metaverse,</li>
</ul>
</li>
<li>Flow the path out to the user&#8217;s homeDirectory attribute through the AD MA.</li>
</ol>
<h2>Metaverse Schema</h2>
<p>Add the following two attributes to the &#8220;person&#8221; type (or whatever you are using for your user objects):</p>
<ul>
<li>userSid (Binary)</li>
<li>homeDirectory (String)</li>
</ul>
<h2>Create the XMA</h2>
<p>Create an Extensible MA and call it &#8220;HomeFolders&#8221;. (Note: I don&#8217;t use spaces in my MA names so I have no scripting hassles.)</p>
<h3>Configure Connection Information</h3>
<p>Choose &#8220;Import and Export&#8221; and &#8220;Call based&#8221;.</p>
<p>Connected data source extension: &#8220;HomeFolders_CSExtension.dll&#8221;  (we will create the extension later)</p>
<p>Connection information: If you want to use this you will have to work out how to use the logon details in your CSExtension code to force the Import and Export steps to use this account instead of the ILM service account. I&#8217;m no great programmer, and to this day I&#8217;ve always managed to get away with giving the ILM service account the permissions I need. In this case it needs permission to create home folders and set ACLs.</p>
<h3>Configure Additional Parameters</h3>
<p>None</p>
<h3>Select Template Input File</h3>
<p>I created a text file called homefolders.txt and saved it to the MaData folder. In the file I have the following line:</p>
<p><code>path,folder,server,owner</code></p>
<p>Select the file and choose &#8220;Delimited&#8221; as the file type.</p>
<p>It is useful to keep this template file. Later, if you need to change the schema, you can modify this file and use it in the Refresh Schema operation.</p>
<h3>Delimited Text Format</h3>
<p>Tick &#8220;Use first row for header names&#8221;.</p>
<p>Select &#8220;Comma&#8221; as the delimiter.</p>
<h3>Configure Attributes</h3>
<p>Set Anchor: path</p>
<p>I also click Advanced and change the Fixed object type to &#8220;folder&#8221;.</p>
<h3>Define Object Types</h3>
<p>Leave on the default &#8211; only path is required.</p>
<h3>Connector Filter</h3>
<p>None. Use this if there are certain folder names you want to exclude.</p>
<h3>Join and Projection Rules</h3>
<p>If you&#8217;re lucky the folder names will match the sAMAccoutNames and you can join on that. You could also flow homeDirectory back from the AD MA and join on the path.</p>
<p>Try very hard to avoid manual joins in such an MA as you have no real way to flow an identifier back out to the folder itself (something you should <em>always</em> do if manual joins have been used &#8211; you should always be able to clear and re-import a connector space). If you have to go the manual join way then consider using a SQL table alongside this MA, as in <a href="http://www.wapshere.com/missmiis/creating-an-extensible-ma">this post</a>, to keep track of folder owners.</p>
<h3>Attribute Flow</h3>
<p>One inbound flow only:</p>
<p><code>path --&gt; homeDirectory</code></p>
<h3>Configure Deprovisioning</h3>
<p>&#8220;Make them disconnectors&#8221;</p>
<p>You can delete home folders with an XMA &#8211; you just need to add the appropriate code in your CSExtension to deal with modificationType = delete. But for this example I&#8217;m just creating the folder.</p>
<h3>Configure Extensions</h3>
<p>Click <strong>Finish</strong> to create the MA.</p>
<h2>Write the CSExtension</h2>
<p>With the new MA selected, click on <strong>Create Extension Project</strong>. In Project type choose &#8220;Connected Data Source Extension&#8221; and then enter as the name &#8220;HomeFolders_CSExtension&#8221;. Make sure your Project Location is correct and then click <strong>OK</strong>.</p>
<h3>GenerateImportFile</h3>
<p>The first step is to write the Import step. This should go out and find all the existing home folders and then populate a csv file along the lines of the template you created above. The actual import into the connector space then occurs from the csv file.</p>
<p>Note that my GetOwner function is a fudge &#8211; I actually just return the first domain account that I find with rights to the folder. This is acceptable to me because <em>I am not going to use this MA to modify existing rights</em>. All I really care about is checking that the user was correctly assigned to a newly created home folder. Typically the user will be the only domain account with explicit (as opposed to inherited) rights to the folder, so this should work fine.</p>
<pre>  Dim Servers As String() = {"server1", "server2", "server3"}

    Public Sub GenerateImportFile(ByVal filename As String, ByVal connectTo As String, ByVal user As String, ByVal password As String, ByVal configParameters As ConfigParameterCollection, ByVal fullImport As Boolean, ByVal types As TypeDescriptionCollection, ByRef customData As String) Implements IMAExtensibleFileImport.GenerateImportFile
        Dim server As String
        Dim path As String
        Dim folders As System.Collections.IEnumerator
        Dim fw As StreamWriter

        Try
            'Open the output file specified in the run profile
            fw = New System.IO.StreamWriter(filename, False)
            fw.WriteLine("path,folder,server,owner")
        Catch ex As Exception
            Throw New UnauthorizedAccessException("Unable to open file: " &amp; filename)
        End Try

        For Each server In Servers
            folders = Directory.GetDirectories("\\" &amp; server &amp; "\homedir").GetEnumerator
            While folders.MoveNext
                path = folders.Current.ToString
                'For each folder, write an entry into the import file
                fw.WriteLine(path &amp; "," _
                            &amp; path.Split("\".ToCharArray)(4) &amp; "," _
                            &amp; path.Split("\".ToCharArray)(2) &amp; "," _
                            &amp; GetOwner(path))
            End While
        Next
        fw.Close()
    End Sub

   Function GetOwner(ByVal path As String) As String
        ' This function does not get the actual owner of the folder,
        ' rather it returns the first domain trustee account.
        ' This is not very precise but the purpose is just to check the ACL
        ' for new folders so it will do.
        Dim AccessRules As AuthorizationRuleCollection
        Dim AuthRule As AuthorizationRule = Nothing
        Dim Owner As String = ""
        Dim Fs As FileSecurity

        Try
            Fs = New FileSecurity(path, AccessControlSections.Access)
            AccessRules = Fs.GetAccessRules(True, False, Type.GetType("System.Security.Principal.NTAccount"))
            If Not AccessRules Is Nothing Then
                For Each AuthRule In AccessRules
                    If AuthRule.IdentityReference.ToString.IndexOf("MYDOMAIN\") = 0 Then
                        Owner = AuthRule.IdentityReference.ToString
                        Exit For
                    End If
                Next
            End If
        Catch ex As Exception
        End Try

        If AuthRule Is Nothing Or _
           Owner = "" Or _
           Owner.IndexOf("MYDOMAIN\") &lt; 0 Then
            Return ""
        Else
            Return Owner
        End If

    End Function</pre>
<p>Once this code is in place you should be able to run an Import step on your MA. You will need to specify an import file name &#8211; just something like &#8220;import.csv&#8221; is fine. Once your code is working you will be able to see the file created in the MaData\HomeFolders directory, and populated with information about the folders it has found.</p>
<h3>ExportEntry</h3>
<p>I&#8217;m going to include the code for the ExportEntry sub here, but we won&#8217;t have anything to export until we modify our MVExtension provisioning code to create new folder objects. More on that below.</p>
<pre>    Public Sub ExportEntry(ByVal modificationType As ModificationType, ByVal changedAttributes As String(), ByVal csentry As CSEntry) Implements IMAExtensibleCallExport.ExportEntry

        If modificationType = Microsoft.MetadirectoryServices.ModificationType.Add Then
            Directory.CreateDirectory(csentry("path").StringValue)

            If Directory.Exists(csentry("path").StringValue) Then
                Try
                    ' Get current ACL from the folder
                    Dim security As DirectorySecurity = Directory.GetAccessControl(csentry("path").StringValue)

                    ' Create a new rule granting owner full access
                    Dim rule As New FileSystemAccessRule(New NTAccount(csentry("owner").StringValue.ToLower), FileSystemRights.FullControl, AccessControlType.Allow)

                    ' Add the rule to the existing rules
                    security.AddAccessRule(rule)

                    ' Persist the changes
                    Directory.SetAccessControl(csentry("path").StringValue, security)

                Catch ex As Exception
                    ' If the ACL failed the delete the folder so the operation can be retried later.
                    Directory.Delete(csentry("path").StringValue)
                    Throw New EntryExportException("Failed to set ACL on " &amp; csentry("path").StringValue _
                              &amp; " - deleting folder. " &amp; vbCrLf &amp; ex.Message)
                End Try

            End If
        End If

    End Sub</pre>
<h2>Provisioning</h2>
<p>Now we want to create the home folder.</p>
<p>As I indicated at the top of this post, you need some kind of proof that the user account was created before you create the home folder. The reason is permissions &#8211; you can&#8217;t grant permissions to a user that doesn&#8217;t exist yet. Technically you could provision your user and home folder objects at the same time, so long as you made sure the AD MA was exported first, but fundamentally I don&#8217;t like this. Even though it means running a series of export/import-syncs in a row, I much prefer to wait for the user account before I provision the home folder.</p>
<p>And the way I do this is by checking the Sid. I flow the userSid back into the Metaverse from the AD MA and use this as a test in my provisioning logic for home folders.</p>
<pre>  Sub HomeFolder_Provisioning(ByVal mventry As MVEntry)
        Dim HFMA As ConnectedMA = mventry.ConnectedMAs("HomeFolders")
        Dim path As String = ""
        Dim server As String = ""

        '' Generate the path based on location
        If mventry("location").IsPresent Then
            Select Case mventry("location").StringValue.ToLower
                Case "london"
                    server = "server1"
                Case "zürich"
                    location = "server 2"
                Case Else
                    server = "server3"
            End Select
            path = "\\" &amp; server &amp; "\homedir\" &amp; mventry("uid").StringValue
        End If

        '' Should the folder exist? AD account must be provisioned first.
        '' Note: Folders are NOT deleted. ShouldExist = FALSE just prevents creation.
        If mventry("Sid_AD").IsPresent Then
            ShouldExist = True
        Else
            ShouldExist = False
        End If

        '' Check if the folder already exists
        Select Case HFMA.Connectors.Count
            Case 0
                DoesExist = False
            Case 1
                DoesExist = True
            Case Else
                Throw New UnexpectedDataException("The metaverse person object with employeeID =" _
                 &amp; mventry("employeeID").StringValue &amp; " has more than one connector in MA " &amp; HFMA.Name)
        End Select

        '' Take action based on values of ShouldExist and DoesExist
        If ShouldExist And DoesExist Then
            'Do nothing

        ElseIf ShouldExist And Not DoesExist Then
            'Create folder object in CS
            Dim csentry As CSEntry = HFMA.Connectors.StartNewConnector("folder")
            csentry("path").Value = path
            csentry("server").Value = server
            csentry("folder").Value = mventry("uid").StringValue
            csentry("owner").Value = "MYDOMAIN\" &amp; mventry("uid").StringValue
            csentry.CommitNewConnector()

        ElseIf Not ShouldExist And DoesExist Then
            'Do nothing

        Else 'Should not exist and does not exist
            'Do nothing
        End If

    End Sub</pre>
<p>All going well, you should now be able to Sync your AD MA, and any AD accounts that are missing a home folder should have one provisioned.</p>
<p>Start testing your exports by restricting the Export step to only process one object at a time.</p>
<h2>Update User homeDirectory</h2>
<p>The final step is to flow the path out to the homeDirectory attribute on the user, using the AD MA.</p>
<p><code>homeDirectory --&gt; homeDirectory</code></p>
<p>If you want to map a particulay drive letter at the same time then flow a constant to homeDrive, eg.,</p>
<p><code>"H:" --&gt; homeDrive</code></p>
<h2>Doing more</h2>
<p>You can do more. As I mentioned above you could modify your ExportEntry sub to process a delete, and then delete the home folder &#8211; though you would want to tread very carefully. There are bound to be far more interesting things you can do with the permissions, or with sharing the folder &#8211; but I&#8217;ll leave that for you to work out. Unless I have to do something like that myself &#8211; and then I will no doubt write it up here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/creating-user-home-directories-windows-version/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Renaming a 2003 AD domain that has Exchange 2007</title>
		<link>http://www.wapshere.com/missmiis/renaming-a-2003-ad-domain-that-has-exchange-2007</link>
		<comments>http://www.wapshere.com/missmiis/renaming-a-2003-ad-domain-that-has-exchange-2007#comments</comments>
		<pubDate>Tue, 20 Jan 2009 12:26:33 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[Exchange 2007]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=299</guid>
		<description><![CDATA[Here&#8217;s an unpleasant little fact you only find out if you need to: while you could rename a domain that hosted Exchange 2003, this functionality has been removed with Exchange 2007.
Hmm. So what if you need to? Well a customer is insisting that it must be done, so I&#8217;ve had to do some investigations. 
Note [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an unpleasant little fact you only find out if you need to: while you could rename a domain that hosted Exchange 2003, this functionality has been removed with Exchange 2007.</p>
<p>Hmm. So what if you need to? Well a customer is insisting that it must be done, so I&#8217;ve had to do some investigations. <span id="more-299"></span></p>
<blockquote><p>Note that this article is based on <em>lab work</em> &#8211; I will <a href="http://www.wapshere.com/missmiis/?p=306">post again</a> after the actual rename, assuming I can&#8217;t swing Option 1 below.</p></blockquote>
<p><strong>Option 1: Try to talk people out of it</strong></p>
<p>It&#8217;s not just Exchange that will be affected. If you have a CA Server you will have to reinstall it with the new name, and then recreate all your certs.  Your DNS zone structure will have to be recreated. And of course every computer attached to the network will need to be rebooted &#8211; probably more than once. You will have to track down every script, service and network device that has the domain name hardcoded somewhere&#8230; Basically, it&#8217;s not going to be simple, you may well have to reinstall some services from scratch, and you could have niggly problems going on for weeks.</p>
<p>But if that doesn&#8217;t work&#8230;</p>
<p><strong>Option 2: Migrate to a new forest</strong></p>
<p>This is where you create a new forest with the new name, install a new Exchange 2007 server into it, and then use tools like ADMT, Gpolmig and Move-Mailbox to shift everything over. This approach has several factors in its favour:</p>
<ul>
<li>The new forest will be completely free of the old name,</li>
<li>Migrations are well understood and there&#8217;s plenty of documentation out there,</li>
<li>The old domain and, importantly, the old Exchange server are untouched and available for rollback,</li>
<li>With an inter-forest trust, it should be possible to move services over in stages.</li>
</ul>
<p>Of course you&#8217;re going to need some new hardware, in particular that new Exchange server. Which would be rather annoying if you&#8217;d only recently installed the &#8220;old&#8221; one.</p>
<p><strong>Option 3: Uninstall Exchange 2007 , Rename the domain, Reinstall Exchange and Restore the mailboxes</strong></p>
<p>Now you <em>can</em> use rendom.exe to rename a Windows 2003 domain once you have uninstalled the Exchange 2007 server. There is no need to do anything special with AD or its schema &#8211; just get rid of that Exchange 2007 server and you&#8217;re ready to go.</p>
<p>It&#8217;s all a bit scary though. To uninstall Exchange 2007 you must first run the disable-mailbox cmdlet against all users &#8211; this effectively removes all Exchange-related information from the user objects, including quotas and delegations. You then have to remove your Mail and Public Folder databases. Yikes!</p>
<p>After the rename it is simple enough to reinstall Exchange 2007 (no need to forestprep as the schema changes are still there) and create new mailboxes for all the users&#8230;</p>
<p>But here&#8217;s where it all went pear-shaped in my test environment. It is not possible to restore an Exchange database over the top of an existing one, you have to go via a Recovery Storage Group,  BUT the restore utility would not restore to my new mailboxes because <em>the mailbox GUIDs did not match!</em> Of course &#8211; I&#8217;d created new mailboxes.</p>
<p>It is supposed to be possible to restore a mailbox to a folder inside a different mailbox &#8211; but my tests on this were not exactly promising &#8211; basically, I could not get it to work at all.</p>
<p>So we have a scary, risky uninstall of Exchange 2007, with a messay, potentially unworkable restore procedure. Not great.</p>
<p><strong>Option 3.1: Use PSTs instead of RSGs</strong></p>
<p>So the other idea is to export all the mailboxes to PST using export-PST before uninstalling Exchange 2007. Afterwards you should be able to import into the new mailboxes using import-PST.</p>
<p>But I haven&#8217;t actually tested this, because the whole uninstall-Exchange-from-production-environment thing has just got me too worried, and I have no intention of doing it for real.</p>
<p><strong>Option 4: Like 3, but restore the entire Exchange Server</strong></p>
<p>I haven&#8217;t tested this one because I don&#8217;t see how it would work. A crashed server can be rebuilt using the /RecoverServer switch &#8211; however <em>all the information must still exist in AD</em>. If you have actually uninstalled Exchange (essential prereq for renaming the domain) then the info is gone from AD and this switch won&#8217;t help.</p>
<p>The same goes for trying to restore the entire server image from backup. Exchange is too emeshed into AD, and if you&#8217;ve gone through the uninstall, you can&#8217;t fool it by just popping the server back up.</p>
<p><strong>Option 5: Install Exchange 2003</strong></p>
<p>Now I thought this was a pretty neat idea. You install an Exchange 2003 server, migrate everything to it (including the Public Folders), and then proceed as above with the uninstall-rename-reinstall activities. You could probably actually keep mail live through most of it, nothing gets deleted, and you could use a temporary server (assuming you had enough disk space).</p>
<p>But again it all fell through for me. Turns out you can&#8217;t install Exchange 2003 into a domain <em>that&#8217;s only had Exchange 2007</em>. The forestprep step fails, and then the installation fails because forestprep wasn&#8217;t done.</p>
<p>I know it is possible to run Exchange 2003 and 2007 in the one domain &#8211; but 2003 has to be there first. It may be possible to install an Exchange 2003 server into a domain <em>that had Exchange 2003 before</em>, but I haven&#8217;t had a chance to test that one out &#8211; and as it&#8217;s not relevant to my current problem, I won&#8217;t be pursuing this option any longer.</p>
<p><strong>Conclusion</strong></p>
<p>Failing Option1, I&#8217;ll be going for Option 2.</p>
<p>If you do need to do this, all I can say is: test, test, test, plan, plan, plan.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/renaming-a-2003-ad-domain-that-has-exchange-2007/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Minimum AD permissions needed by ILM</title>
		<link>http://www.wapshere.com/missmiis/minimum-ad-permissions-needed-by-ilm</link>
		<comments>http://www.wapshere.com/missmiis/minimum-ad-permissions-needed-by-ilm#comments</comments>
		<pubDate>Wed, 08 Oct 2008 07:35:04 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[ILM 2007]]></category>
		<category><![CDATA[MIIS 2003]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=203</guid>
		<description><![CDATA[The AD management agent uses an account to connect to AD and, more often than not, this account is a member of Domain Admins. However in some organisations this is not acceptable. So what rights does it actually need?

The one domain-wide right you do need to grant is Replicate Directory Changes &#8211; and you can read all [...]]]></description>
			<content:encoded><![CDATA[<p>The AD management agent uses an account to connect to AD and, more often than not, this account is a member of Domain Admins. However in some organisations this is not acceptable. So what rights does it actually need?</p>
<p><span id="more-203"></span></p>
<p>The one domain-wide right you do need to grant is <strong>Replicate Directory Changes</strong> &#8211; and you can read all about how to set that <a href="http://support.microsoft.com/kb/303972" target="_blank">here</a>. If you don&#8217;t set this permission you will see a stopped-connectivity error, and event 6050 in the application log.</p>
<p>If you haven&#8217;t changed the default rights for the Authenticated Users group then you should not need to add any extra permissions at the Domain level. This group will give the ILM account sufficient rights to map out the directory OU tree and read the schema.</p>
<p>So then it just remains to give the service account rights to the OUs that it will be interested in:</p>
<ul>
<li>Create/Delete specific object types as required,</li>
<li>Read/Write All Properties,</li>
<li>Reset Password (if using password sync).</li>
</ul>
<p>Note that I&#8217;ve suggested read and write to all properties even though, theoretically, you could go through picking out just the particular attributes ILM can change. Personally I would strenuously resist this approach as it would be a right nuisance every time an extra attribute was added to a flow rule. Point out that the attribute selection can also be restricted from the ILM side so, while it may have access to unneeded attributes, it is completely impossible for it to modify values it can&#8217;t even see.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/minimum-ad-permissions-needed-by-ilm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AD Group members</title>
		<link>http://www.wapshere.com/missmiis/group-members-and-other-multivalued-attributes</link>
		<comments>http://www.wapshere.com/missmiis/group-members-and-other-multivalued-attributes#comments</comments>
		<pubDate>Tue, 25 Mar 2008 10:43:17 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[Groups]]></category>
		<category><![CDATA[ILM 2007]]></category>
		<category><![CDATA[MIIS 2003]]></category>
		<category><![CDATA[newbie]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=108</guid>
		<description><![CDATA[This is a repost of an article which was originally about multivalue attributes in general, but with a focus on group members. I realised I had made some generalisations about multivalue attributes which actually specifically apply only to attributes like member, which contain reference DN values. So I am now re-releasing the post, with a [...]]]></description>
			<content:encoded><![CDATA[<p>This is a repost of an article which was originally about multivalue attributes in general, but with a focus on group members. I realised I had made some generalisations about multivalue attributes which actually specifically apply only to attributes like member, which contain <em>reference DN</em> values. So I am now re-releasing the post, with a focus just on member. </p>
<p>Group population is not the simplest thing to automate, however it is often a time-consuming manual task, and something high up on the priority list for an ILM project. Here are a few points which may help you on your way.</p>
<p><span id="more-108"></span></p>
<h4>Members are Reference DN values</h4>
<p>Groups are populated with links to the member objects, not a text list of names. To manage group memberships in ILM <em>all</em> involved objects must be present in ILM.</p>
<p>So, to put this plainly, if you&#8217;re trying to manage a particular group in AD then ILM must know about <em>all</em> its members. It is not possibly to partially manage a group.</p>
<h4>You can only populate member and not memberOf</h4>
<p>You can&#8217;t write to the &#8220;memberOf&#8221; attribute on user objects. It is something called a &#8220;backlinked&#8221; attribute, and AD is in charge of maintaining it.</p>
<p>You can, however, write to the &#8220;member&#8221; attribute of group objects, and this is the way you have to do it.</p>
<p>So it is not possible to manage group memberships by only considering the person (or user or contact) object &#8211; you need to manage the group objects as well.</p>
<h4>You can&#8217;t modify reference DN attributes in extension code</h4>
<p>ILM won&#8217;t let you write advanced flow rules for reference DN attributes &#8211; all you can do is flow them direct from one connector space, via the metaverse, to another.</p>
<p>(Actually I&#8217;ve never quite understood why this is, but there you go, we have to live with it.)</p>
<p>To emphasise the point: you must generate your membership lists <em>outside</em> of ILM, and then sync them directly <em>through</em> ILM.</p>
<h4>When Dynamic Groups are not enough</h4>
<p>Dynamic groups are those ones you want to change based on members&#8217; attributes. Perhaps the group should contain everyone in a particular department, or a building, or with the same manager.</p>
<p>Exchange 2003 brought us dynamic groups &#8211; but only for distribution lists, and not security. Pathetic.</p>
<p>Besides, you&#8217;re most likely going to need some manually populated groups as well &#8211; not everything can be worked out from attribute values. You may also want some groups where most of the members are dynamic, and a couple which are static.</p>
<p>If you&#8217;re using SunOne LDAP you can do all this natively&#8230; but with AD the membership of all security groups are static, and you need something else to help automate things.</p>
<h4>Generate the members in SQL</h4>
<p>Here&#8217;s how you might generate the membership lists in SQL:</p>
<ol>
<li>Generate dynamic group memberships in a view by directly querying the mms_metaverse table (sample queries to follow in another post).</li>
<li>Maintain another table for manually added group memberships (perhaps with a web front-end to manage them; groups can appear in both tables).</li>
<li>Concatenate the table and view together.</li>
<li>Import using the multivalue function of the <a href="http://www.wapshere.com/missmiis/?p=97">SQL MA</a>.</li>
</ol>
<p>For more explanation on how to configure the tables to import group memberships see <a href="http://www.wapshere.com/missmiis/?p=9">this post</a>.</p>
<h4>Use Delta tables</h4>
<p>You may quickly find that full imports from multivalued tables are too slow &#8211; for this reason it is essential that you use delta imports, ie., only import changes.</p>
<p>The basic method is as follows:</p>
<ol>
<li>Snapshot your import table/view;</li>
<li>Do a Full import;</li>
<li>Next time, take a new snapshot and compare it to the last one to make a Delta Table;</li>
<li>Do a Delta Import;</li>
<li>Once the Delta Import has completed successfully, clear out the Delta Table;</li>
<li>Repeat steps 3-5 <em>ad nauseum</em>.</li>
</ol>
<p>There is (naturally) a fair bit more to it when you start bringing multivalued attributes into the mix. I&#8217;ve written a few posts on the subject in the past, and the best place to start is with <a href="http://www.wapshere.com/missmiis/?p=17">this one</a>.</p>
<h4>In Summary</h4>
<p>I once set up a system that had 6,000 groups and 40,000 users. The group memberships changed continuously &#8211; particularly the self-subscriber ones that were updated through the user portal. <a href="http://www.wapshere.com/missmiis/?p=11">For efficiency</a>, I separated the multivalued and single valued attributes into seperate MAs, and the multivalued Full Import still took about 5 hours. But by running regular delta imports (every 15 minutes) the list of changes each time was short, and the imports took only a matter of moments.</p>
<p>So while group population and synchronisation with ILM is fiddly, and does use a number of advanced techniques, it is certainly possible to achieve a result that is both effective and efficient.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/group-members-and-other-multivalued-attributes/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Configuration of the Active Directory MA</title>
		<link>http://www.wapshere.com/missmiis/configuration-of-the-active-directory-ma</link>
		<comments>http://www.wapshere.com/missmiis/configuration-of-the-active-directory-ma#comments</comments>
		<pubDate>Thu, 28 Feb 2008 15:33:14 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[ILM 2007]]></category>
		<category><![CDATA[MIIS 2003]]></category>
		<category><![CDATA[newbie]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=96</guid>
		<description><![CDATA[I&#8217;ve already posted about the configuration options that are common to all MAs, so this post is about the options specific to the Active Directory MA, though much of it will also apply to the other LDAP-types &#8211; Sun and Netscape, Netware, ADAM, IBM Directory Server and openLDAP.

Starting on the Configure Directory Partitions page, select [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve already posted about the <a href="http://www.wapshere.com/missmiis/?p=95">configuration options that are common to all MAs</a>, so this post is about the options specific to the Active Directory MA, though much of it will also apply to the other LDAP-types &#8211; Sun and Netscape, Netware, ADAM, IBM Directory Server and <a href="http://sourceforge.net/projects/openldap-ma" target="_blank">openLDAP</a>.</p>
<p><span id="more-96"></span></p>
<p>Starting on the <strong>Configure Directory Partitions</strong> page, select your preferred directory Patition, Domain Controllers (optional) and Containers (OUs). Just let ILM see what it has to &#8211; there is no need to waste diskspace and time on importing OUs it has no business with.</p>
<p>Next we come to the <strong>Object Types</strong>. Again here you can be selective, but make sure you keep <strong>container </strong>and <strong>organizationalUnit </strong>as ILM will need them when constructing DNs.</p>
<p>Similarly on the<strong> Attributes</strong> page select the bare minimum, remembering that you can always add more later on. The basics for a user object are cn, firstName, sn, displayName, sAMAccountName (this is actually optional &#8211; AD will fill in a random one, but it will be ugly and I prefer to supply my own), userAccountControl, userPwd.</p>
<p>I prefer to be selective about which objects and attributes ILM can see for a couple of reasons &#8211; one is to reduce the scope for accidents, and the other is to reduce the size of the blame target. Call me paranoid if you will, but I have disproved a charge of &#8220;ILM did it&#8221; in the past by simply pointing out that the attributes in question weren&#8217;t even selected!</p>
<p>The final point I will mention is about the <strong>Enable Exchange 2007 provisioning</strong> option that has appeared, in ILM 2007, on the <strong>Extensions</strong> page. I understand this has something to do with Exchange 2007 no longer using the Recipient Update Service &#8211; a rather annoyingly opaque process in 2000/2003, but something we ILM&#8217;ers were relying on to get mailboxes created. There&#8217;s a proper explanation on <a href="http://technet.microsoft.com/en-us/library/aa998597.aspx">this technet page</a>.<a href="http://technet.microsoft.com/en-us/library/aa998597.aspx"><br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/configuration-of-the-active-directory-ma/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updating AD attributes from an Excel spreadsheet</title>
		<link>http://www.wapshere.com/missmiis/updating-ad-attributes-from-an-excel-spreadsheet</link>
		<comments>http://www.wapshere.com/missmiis/updating-ad-attributes-from-an-excel-spreadsheet#comments</comments>
		<pubDate>Wed, 19 Dec 2007 10:22:22 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[AD]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://www.wapshere.com/missmiis/?p=84</guid>
		<description><![CDATA[You don&#8217;t always have access to a proper IdM system. At the moment I&#8217;m at an organisation which still uses the old, manual ways of updating AD. I was asked if I knew an easy way to update the mobile phone numbers of a list of users, the data having been sent to Helpdesk in [...]]]></description>
			<content:encoded><![CDATA[<p>You don&#8217;t always have access to a proper IdM system. At the moment I&#8217;m at an organisation which still uses the old, manual ways of updating AD. I was asked if I knew an easy way to update the mobile phone numbers of a list of users, the data having been sent to Helpdesk in a spreadsheet. I knew that a long list of departments were shortly to be changed as well, so I figured I&#8217;d make a general solution, where you could also specify the attribute name in the spreadsheet.</p>
<p>I actually ended up writing the script twice.</p>
<p><span id="more-84"></span></p>
<ol>
<li>First I used DNs as the search criteria, which makes the script quite simple, and also means it will work with any object type. You can see that script <a href="http://www.wapshere.com/missmiis/?page_id=81" target="_blank">here</a>.</li>
<li>Then, after seeing that the source spreadsheet contained usernames rather than DNs, I modified the script to use the CN instead. The restriction is that now the script only works with user objects (though there&#8217;s actually no reason why you couldn&#8217;t make a column for the object type in the spreadsheet as well). That script is <a href="http://www.wapshere.com/missmiis/?page_id=83" target="_blank">here</a>.</li>
</ol>
<p>It needs to be noted that these scripts should only be used for updating single-valued attributes. I have included <em>no back-out</em> &#8211; so if you have the wrong data in your spreadsheet I accept no responsibility for you putting rubbish in your AD.</p>
<p>You also need to make sure your spreadsheet is tidy, with even column lengths, and no blank row in the middle (the script stops at the first blank cell).</p>
<p>For the CN script your spreadsheet should look something like this:</p>
<table border="1">
<tbody>
<tr>
<td>jbloggs</td>
<td>department</td>
<td>IT Helpdesk</td>
</tr>
<tr>
<td>jbloggs</td>
<td>mobile</td>
<td>0123456789</td>
</tr>
<tr>
<td>hzhen</td>
<td>description</td>
<td>Administrative Assistant</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.wapshere.com/missmiis/updating-ad-attributes-from-an-excel-spreadsheet/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

