tag:blogger.com,1999:blog-40181812973989835932024-03-15T21:12:14.763-04:00The Free LoderSometimes you get more than you pay for.David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.comBlogger49125tag:blogger.com,1999:blog-4018181297398983593.post-86722668432921454112021-05-28T11:30:00.001-04:002021-05-28T11:30:36.248-04:00Mark Wahl tweeted my B2B sync post<p> Aww snap. <a href="https://twitter.com/markwahl/status/1398284618797879296">Microsoft's Identity PM Mark Wahl tweeted</a> about my <a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/multi-tenant-b2b-sync-with-mim-graph-connector/ba-p/2381682">recent B2B post</a>! đȘđ</p>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-20990800789094817022021-05-24T16:56:00.001-04:002021-05-26T10:47:00.027-04:00Multi-Tenant B2B Sync with MIM Graph Connector<p>Cross Post from <a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/multi-tenant-b2b-sync-with-mim-graph-connector/ba-p/2381682">https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/multi-tenant-b2b-sync-with-mim-graph-connector/ba-p/2381682</a></p><p class="MsoNormal">Hello everyone, this is David Loder again, sporting Microsoftâs
new Customer Engineer title, but still a Hybrid Identity engineer from Detroit.
Over the past year Iâve seen an uptick in requests from customers looking to
modernize their GALSync solution. Either theyâre wanting to control use of
SharePoint and Teams B2B capabilities or looking to enable a GALSync with a
cloud-only organization. And theyâre asking for assistance and guidance that I
hope to provide today.</p>
<p class="MsoNormal">Before I get started on how Microsoft Identity Manger (MIM)
2016 can help provide the basis for a supported GALSync solution, I want to
ensure everyone knows that Microsoft provides a managed service SaaS offering
to help with any multi-tenant syncing scenarios. Itâs called Active Directory
Synchronization Service (ADSS) and does all the back-end tenant syncing
automagically. The great benefit with ADSS is that itâs a fully supported solution.<span style="mso-spacerun: yes;"> </span>MIM as a product is fully supported, but as
has always been the case, any customizations put into it are best-effort
support. Reach out to your account team if you want more information about
ADSS. Now on with the MIM discussion.</p>
<p class="MsoNormal">Historically, Microsoft has provided a supported GALSync solution
in our on-premises sync engine, MIM. <a href="https://docs.microsoft.com/en-us/previous-versions/mim/cc720550(v=ws.10)">Documentation
on the GALSync configuration</a> was first provided back in the Microsoft
Identity Integration Server (MIIS) 2003 timeframe. Additional documentation is
available at the <a href="http://aka.ms/GALSyncResources">GALSync Resources
Wiki</a>. Despite its age, that guidance still holds true today. But it is
limited to an Active Directory to Active Directory user to contact sync design.</p>
<p class="MsoNormal">Today, we offer the <a href="https://docs.microsoft.com/en-us/microsoft-identity-manager/microsoft-identity-manager-2016-connector-graph">Microsoft
Graph Connector</a>. It provides the ability to connect to an Azure AD tenant,
and to manage <a href="https://docs.microsoft.com/en-us/azure/active-directory/external-identities/what-is-b2b">B2B</a>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/external-identities/code-samples">invitations</a>.
However, it is not a drop-in replacement for GALSync. We can get there, but we
need to fill in some missing components.</p>
<p class="MsoNormal">There are many scenarios that Graph Connector could satisfy,
and they can get increasingly difficult. For this blog Iâll focus on the simplest
scenario and then discuss what considerations one would have in order to move
to more complex scenarios.</p>
<p class="MsoNormal">In a classic GALSync solution, we sync users from a partner
AD to become contacts in our home AD. For this Azure AD replacement, we want to
sync users from a partner tenant, and make them B2B users in our home tenant. This
assumes that youâve moved past the point where you need identical GALs in both on-premises
Exchange and Exchange Online. Most of the customers I work with have gotten to
that point. Maybe they still have some service account mailboxes left to move,
but all humans who need to view a GAL have been moved to Exchange Online. That
simplifies the requirements as thereâs no longer a need for creating on-premises
objects for Exchange to use.</p>
<p class="MsoNormal">The first component we need is MIM 2016. If you are an Azure
AD Premium customer, <a href="https://docs.microsoft.com/en-us/microsoft-identity-manager/support-update-for-azure-active-directory-premium-customers">MIM
is still fully supported</a> and still <a href="https://aka.ms/MIMforAADP">available
for download</a>. Otherwise, MIM is in <a href="https://docs.microsoft.com/en-us/lifecycle/products/microsoft-identity-manager-2016">extended
support</a> through 2026. To keep our infrastructure footprint small, this
solution will use only a <a href="https://docs.microsoft.com/en-us/microsoft-identity-manager/install-mim-sync">Sync
Service install</a>, and will not use the Portal or any declarative
provisioning.</p>
<p class="MsoNormal">With a base MIM install in place weâre almost ready to make
a Graph connection to our first tenant. But before we do so, we need to have a
discussion of scope, because scope is the major factor in determining the
complexity of solution. When talking about scope, Iâm going to be very exact in
terms of objects and attributes as much of our terminology in this space is
vague and subject to perspective to understand meaning.</p>
<p class="MsoNormal">âWe want users from a partner tenantâŠ.â Starting with this
phrase, we need to break it down to a scoped object and attribute definition. The
Graph Connector exposes user and contact (technically orgContact) object
classes. We will only want to bring in users from the partner tenant. Except the
user object class covers both internal and external (a.k.a. B2B) users. Typically,
we only want to bring in the internal users from the partner tenant. We can
tell the difference between them because external users have a creationType
attribute equal to âInvitationâ, whereas internal users have a null creationType.
The other possible choice one might consider is the userType attribute with
values of either âGuestâ or âMemberâ. But I think that is a poor choice.
Internal users are Member by default and external users are Guest by default,
but userType can be changed for both. Guest vs. Member only controls oneâs
default visibility to certain workloads such as <a href="https://docs.microsoft.com/en-us/microsoft-365/solutions/collaborate-in-site?view=o365-worldwide">SharePoint</a>
or <a href="https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/users-restrict-guest-permissions">Azure
AD</a> itself. Guest is sometimes incorrectly used interchangeably with B2B,
but those two terms are not equivalent.</p>
<p class="MsoNormal">âMake B2B users in our home tenantâŠ.â Given the previous
discussion, this phrase is now rather easy to scope. Weâll be looking at user
objects with creationType=âInvitationâ.</p>
<p class="MsoNormal">With our purposefully simplistic scope defined, letâs build
the first Graph connection to the partner tenant. Install the Graph Connector
on the MIM system. There have been lots of fixes recently so be sure to use the
<a href="https://www.microsoft.com/en-us/download/details.aspx?id=51495">current
version</a>.</p>
<p class="MsoNormal">Start with creating a new Graph (Microsoft) connector.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBEoGxzqxzB5jAAPsdwHfCXQ_PZeIN-ALM3bOZCnJjsuBckr_r_Q3J8uh2kCx9wAaz9A6a7TeW3Q9iPhtaht6-WTVgeCfvwG1CbIBZmbOdkBZdD3ftG9PGhielO28Fkv2Q8Io49NX4VQ9i/s654/PartnerTenantMAW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBEoGxzqxzB5jAAPsdwHfCXQ_PZeIN-ALM3bOZCnJjsuBckr_r_Q3J8uh2kCx9wAaz9A6a7TeW3Q9iPhtaht6-WTVgeCfvwG1CbIBZmbOdkBZdD3ftG9PGhielO28Fkv2Q8Io49NX4VQ9i/s16000/PartnerTenantMAW.png" /></a></div><p class="MsoNormal"><br /></p>
<p class="MsoNormal">Provide <a href="https://docs.microsoft.com/en-us/microsoft-identity-manager/microsoft-identity-manager-2016-connector-graph#authorizing-the-connector-to-retrieve-or-manage-objects-in-your-azure-ad-directory">registered
app credentials</a> to connect to the partner tenant. The app registration
needs at least User.Read.All and Directory.Read.All, with Admin consent. This
is an example from one of my temporary demo tenants.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhVW8aYCzLwMjRmJ-WmQ04hsIo8LcgP5Jf4L1bWEyYyeyKGcYb2pvKJ_mgcKMHgvtdD6MpOGXo9nBV5ehpchIdFj7F23phRa7ZRaAn6S8w2FY03sVwDL0xMqEfoT3O2R5yRkJ3HlVdocOO/s654/PartnerTenantConnectivityW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhVW8aYCzLwMjRmJ-WmQ04hsIo8LcgP5Jf4L1bWEyYyeyKGcYb2pvKJ_mgcKMHgvtdD6MpOGXo9nBV5ehpchIdFj7F23phRa7ZRaAn6S8w2FY03sVwDL0xMqEfoT3O2R5yRkJ3HlVdocOO/s16000/PartnerTenantConnectivityW.png" /></a></div><br /><p class="MsoNormal"><br /></p>
<p>On the Schema 1 page, keep the Add objects filter unchecked.
Unfortunately, we cannot use the filtering capability to return only the
internal users where creationType is null. The Graph API provides more <a href="https://developer.microsoft.com/en-us/identity/blogs/microsoft-graph-advanced-queries-for-directory-objects-are-now-generally-available/" style="text-align: left;">advanced
filtering capabilities</a>, but it requires a Header value to be set, which the
Graph Connector does not currently expose as a configurable setting.</p>
<p class="MsoNormal">On the Select Object Types page check user.</p>
<p class="MsoNormal">On the Select Attributes page, letâs select a minimum number
of attributes to enable decent GAL functionality as part of the B2B sync. Additional
attributes can be added if the GAL needs to be more fully populated. Select creationType,
displayName, givenName, id, mail, showInAddressList, and surname.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZd1aES09kJcfmhooKwz7XejiLK_nj6hIAkJ_Z09bXhCmkdEGKAiwwfdMjUAnV5xCjJD4HP10Ux-CR2WHb4xeJm7IVAOumoQugl4XaybD-d35Pxjy4h-B3FlfB5IuY-tkMWYZZuSyP422H/s654/PartnerTenantAttributesW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZd1aES09kJcfmhooKwz7XejiLK_nj6hIAkJ_Z09bXhCmkdEGKAiwwfdMjUAnV5xCjJD4HP10Ux-CR2WHb4xeJm7IVAOumoQugl4XaybD-d35Pxjy4h-B3FlfB5IuY-tkMWYZZuSyP422H/s16000/PartnerTenantAttributesW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">The anchor attribute on the Configure Anchors page will
automatically be set to id.</p>
<p class="MsoNormal">On the Configure Connector Filter page, I will keep this
example simple by using a declared filter of creationType Is present. This will
filter out any external users that may happen to already exist in the partner
tenant. But this filtering will come at the expense of increased Delta Sync
times due to having to process each filtered disconnector every sync cycle.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCzEJZ37YcnBnZMCOEtfZXm2L928pfabDBHFxBtocDY6y-_4owBcRo_vprrGXhZoLXAXEXH-IqZs9hUIo0eZDwDq-NrEco8I9ZxRddODIBZ-u4__1N_-3y7eh4YZHZTu6_Y1o_I6NndcPv/s654/PartnerTenantFilterW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCzEJZ37YcnBnZMCOEtfZXm2L928pfabDBHFxBtocDY6y-_4owBcRo_vprrGXhZoLXAXEXH-IqZs9hUIo0eZDwDq-NrEco8I9ZxRddODIBZ-u4__1N_-3y7eh4YZHZTu6_Y1o_I6NndcPv/s16000/PartnerTenantFilterW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">For Configure Join and Projection Rules, weâll join on id
first, mail second, otherwise project as a person.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUAVgibssgAiMjz2n2A3OSPLfTVIi1He5l7hVPMZnJOTrRxIYQrpZ7Vqrij0L-kbt5S_-H_6_r1Z_4aj5xyyMsRqOtEcJJ-dB8C8bMza2fFSmDPt5a-XgFBhZyKgAASkkKG3bpoaTGciP0/s654/PartnerTenantJoinAndProjectionW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUAVgibssgAiMjz2n2A3OSPLfTVIi1He5l7hVPMZnJOTrRxIYQrpZ7Vqrij0L-kbt5S_-H_6_r1Z_4aj5xyyMsRqOtEcJJ-dB8C8bMza2fFSmDPt5a-XgFBhZyKgAASkkKG3bpoaTGciP0/s16000/PartnerTenantJoinAndProjectionW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">This is the inbound partner tenant user flow, so provide a
direct inbound flow for each attribute. Several of the selected attributes are
not default metaverse attributes, so the metaverse schema will need to be
extended to account for these attributes.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv04sab9KR5yOq7z8Telah7-U_sHx4qic6HvysKpwgiLfZHlGIDbBKfMx4BvIK3zqmWUhThkWjSUhM56fTkqYg-4k5MX197u2ggbx8rv8-hYgtBIleU9yIoxv8u__q7NPHwGJLzK1aFwCB/s654/PartnerTenantAttributeFlowW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv04sab9KR5yOq7z8Telah7-U_sHx4qic6HvysKpwgiLfZHlGIDbBKfMx4BvIK3zqmWUhThkWjSUhM56fTkqYg-4k5MX197u2ggbx8rv8-hYgtBIleU9yIoxv8u__q7NPHwGJLzK1aFwCB/s16000/PartnerTenantAttributeFlowW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">Leave the Configure Deprovisioning page at the default of âMake
them disconnectorsâ and Configure Extensions page will also be left at its
default of empty.</p>
<p class="MsoNormal">Create the Full Import and Full Sync run profiles. Execute
them to confirm that the partner tenant users are projected into the metaverse.
Also create the Delta Import and Delta Sync run profiles. We wonât use them now,
but will need them later. Iâve gotten spoiled from AADC creating run profiles
by default.</p>
<p class="MsoNormal">Now that the inbound side from the partner tenant is
complete, letâs create the outbound side for the home tenant. The setup will be
similar to the inbound side, but with some minor changes.</p>
<p class="MsoNormal">The App Registration in the home tenant will require the
Directory.Read.All and User.ReadWrite.All permissions. There is a User.Invite.All
permission, but since we need to sync GAL attributes after the invite, that
permission does not provide enough access for this scenario.</p>
<p class="MsoNormal">For the Schema 1 page, weâll need to leave the Add objects
filter checkbox uncheck again. Even though we could technically set a <a href="https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter">graph
filter</a> of creationType eq 'Invitation', using a filter breaks Delta Imports
for the Graph Connector (with a no-start-ma error). We will have to continue to
use MIM filtering the keep the scope correct since Delta Imports are very
important for most of my customers.</p>
<p class="MsoNormal">On the Global Parameters page set the Invite redirect URL to
https://myapps.microsoft.com/?tenantid=GUIDValue. Leave the send mail checkbox unchecked
unless you want to start automatically spamming all your invitees.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheyfESHSJTLDPsmAQM3mb7LGPHnwx8Fc0LeRzfaVNkUmwQ_8BGZDMdwXMZtAne14mbb326D1T4hmnrY7jvqGjSt5nbnGkMg5aniwJZxQqR3X52inkuEkDEQ-HyrQbP1R_676kX22N0cFII/s654/HomeTenantGlobalW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheyfESHSJTLDPsmAQM3mb7LGPHnwx8Fc0LeRzfaVNkUmwQ_8BGZDMdwXMZtAne14mbb326D1T4hmnrY7jvqGjSt5nbnGkMg5aniwJZxQqR3X52inkuEkDEQ-HyrQbP1R_676kX22N0cFII/s16000/HomeTenantGlobalW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">On the Select Attributes page, include userPrincipalName and
userType in addition to the list of attributes from the inbound side. Weâre
selecting UPN just so we can see the full results of the invitation process,
not because weâll be doing any syncing of that attribute.</p>
<p class="MsoNormal">For the Configure Connector Filter page, we reverse it from
the inbound partner tenant setting and use a filter of creationType Is not present.</p>
<p class="MsoNormal">On the Configure Join and Projection Rules page, only add the
Join Rule for mail. There should be no Projection Rule as we want all the
external users to project into the metaverse from the inbound partner tenant.</p>
<p class="MsoNormal">For the Configure Attribute Flow page, add a direct export
(allowing nulls) for displayName, givenName, mail, showInAddressList and
surname. Add a constant export of Guest for userType. While an external user is
typically Guest by default, the Graph Connector defaults to Member, so we need to
override that. Also add a constant export of Invitation for creationType. For
the creationType, weâre flowing that just to satisfy the MA filter, not that it
affects the invitation process.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdp-4NOjyd-jiXXZWwOTDG5kG4Y_8LLoQwD4cLCV_1FfklDZs01Vhf8g-CEbo7eQ3FacsGlSUPa9MqafXlbRU3bzjxHmIcpajf6RC2Xx2deF6Gf7FgCR1bcibFiLQFZWa_dZgEMdNTcv4f/s654/HomeTenantAttributeFlowW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="493" data-original-width="654" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdp-4NOjyd-jiXXZWwOTDG5kG4Y_8LLoQwD4cLCV_1FfklDZs01Vhf8g-CEbo7eQ3FacsGlSUPa9MqafXlbRU3bzjxHmIcpajf6RC2Xx2deF6Gf7FgCR1bcibFiLQFZWa_dZgEMdNTcv4f/s16000/HomeTenantAttributeFlowW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">On the Configure Deprovisioning page, change the selection
to Stage a delete on the object for the next export run.</p>
<p class="MsoNormal">Create and run the Full Import and Full Sync run profiles.
If there are any matching mail values for existing external users those should
join. Otherwise, the existing external users will show up as disconnectors. Also
create the Delta Import, Delta Sync and Export run profiles. We wonât use them
now, but will need them later.</p>
<p class="MsoNormal">Finally, we need a small amount of <a href="https://docs.microsoft.com/en-us/previous-versions/windows/desktop/identity-lifecycle-manager/ms696017(v=vs.85)">provisioning
code</a> to provision the external users from the metaverse into the home
tenant MA. From the Tools > Options⊠menu check the Enable metaverse rules
extension checkbox. Then click the Create Rules Extension Project⊠button. Iâll
provide sample code for Visual C#, so choose that selection and the version of
Visual Studio to use to compile the project.</p>
<p class="MsoNormal">This is a sample implementation for the <a href="https://docs.microsoft.com/en-us/previous-versions/windows/desktop/forefront-2010/ff771493(v=vs.100)">IMVSynchronization.Provision</a>
method.</p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">void</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">
IMVSynchronization.Provision (MVEntry mventry)</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">{</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">string</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> container = </span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"OBJECT=user"</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">; </span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">string</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> rdn = </span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"CN="</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> +
Guid.NewGuid().ToString();</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>ConnectedMA HomeTenantMA = mventry.ConnectedMAs[</span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"HomeTenant"</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">];</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>ReferenceValue dn = HomeTenantMA.EscapeDNComponent(rdn).Concat(container);</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">int</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> numConnectors =
HomeTenantMA.Connectors.Count;</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><o:p> </o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: green; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">// If there is no connector present, create a new
connector.</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">if</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> (numConnectors == 0)</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>{</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span>CSEntry csentry = HomeTenantMA.Connectors.StartNewConnector(</span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"user"</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">);</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span>csentry.DN = dn;</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span>csentry[</span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"id"</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">].StringValue = Guid.NewGuid().ToString();</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span>csentry.CommitNewConnector();</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>}</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">else</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> </span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">if</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> (numConnectors == 1)</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>{</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span></span><span style="color: green; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">//Do nothing,
no rename is needed</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>}</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">else</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>{</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;"> </span></span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">throw</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> (</span><span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">new</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">
UnexpectedDataException(</span><span style="color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">"multiple connectors:"</span><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"> + numConnectors.ToString()));</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;"><span style="mso-spacerun: yes;">
</span>}</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;"><span style="color: black; font-family: Consolas; font-size: 9.5pt; mso-bidi-font-family: Consolas;">}<span style="mso-tab-count: 1;"> </span></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">A few things to note in this code. We need the name of the
home tenant MA as the connected MA we are managing. We also set a random
GUID-based DN and id in order to successfully export the invitation, but those
values will be replaced by the real Azure AD values during the first confirming
import.</p>
<p class="MsoNormal">Build the solution in Visual Studio and make sure the
extension DLL gets copied to the Microsoft Forefront Identity
Manager\2010\Synchronization Service\Extensions folder. Back in the Options dialog,
ensure the DLL that was just created is selected for the Rules extension name,
and check the Enable Provisioning Rules Extension checkbox.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD5Tiwyzaon0jnzZ1rpQCE9SfDihShYPNYh9HNCz41I92jaOie4i6_5AzK6pMl-52W-zLMk9OVXbe2Cu9AdzYYzNOZeh8oJjmb7gzREZV39TsKorsV12u2WQXdWGpWCEY6Bxokn4Gv_VUD/s506/OptionsW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="442" data-original-width="506" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD5Tiwyzaon0jnzZ1rpQCE9SfDihShYPNYh9HNCz41I92jaOie4i6_5AzK6pMl-52W-zLMk9OVXbe2Cu9AdzYYzNOZeh8oJjmb7gzREZV39TsKorsV12u2WQXdWGpWCEY6Bxokn4Gv_VUD/s16000/OptionsW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">To begin with a small test, pick a sample user from the
partner tenant MA and commit a Full Sync Preview against them. That should
generate a pending export in the home tenant MA.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEQleFVm7yOjVAQsJo8coha2BaTZsvHBMpfDi6MtPM2rd69JxbCqjMuBCRZTIBsr57a8UHtuFRw2pNvq2zx_7bLVoOcW1HQRkj-MPeMqWej_rdKWTY5Fw3ik3pafQBlpmqHlwgy2ItAavH/s690/HomeTenantPendingExportW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="541" data-original-width="690" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEQleFVm7yOjVAQsJo8coha2BaTZsvHBMpfDi6MtPM2rd69JxbCqjMuBCRZTIBsr57a8UHtuFRw2pNvq2zx_7bLVoOcW1HQRkj-MPeMqWej_rdKWTY5Fw3ik3pafQBlpmqHlwgy2ItAavH/s16000/HomeTenantPendingExportW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">The small piece of magic with the Graph Connector is that if
a user has a pending add with mail but no UPN, they will go through the
invitation process to make them an external user, rather than being created as
an internal user. We can see the pending export with the temporary DN and id,
the GALSync attributes we wired up, and our constant userType of Guest. This
test user has an OnMicrosoft.com mail address in the partner tenant as I have
not added a custom domain to that tenant. The actual mail value is ultimately
immaterial so long as it doesnât already belong to the destination tenant.</p>
<p class="MsoNormal">Run the Export, followed by a confirming Delta Import.</p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf1YH82srSy7yiawZWbBfpqed0MvkoTU8ukD8fVSOm3_vy3-TJkXOTI0g7zBkqmsSi4g4CjlFgUd6wVLzMnmwba5GbfZoU-gsIxzeURF1bsLGQca3zidr0nq7J_7wbjxsB-d-37_A30jgc/s690/HomeTenantConfirmingImportW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="541" data-original-width="690" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf1YH82srSy7yiawZWbBfpqed0MvkoTU8ukD8fVSOm3_vy3-TJkXOTI0g7zBkqmsSi4g4CjlFgUd6wVLzMnmwba5GbfZoU-gsIxzeURF1bsLGQca3zidr0nq7J_7wbjxsB-d-37_A30jgc/s16000/HomeTenantConfirmingImportW.png" /></a></div><br /><p class="MsoNormal"><br /></p><p class="MsoNormal">We see that the user got successfully invited, got its real
DN and id and has all the attributes we set. Notice the UPN got automatically
set by AAD in the expected format of mail#EXT#@tenant. It also was given a
default setting of showInAddressList = false. By default, invited external
users are hidden from the GAL.</p><p class="MsoNormal">Complete
a second delta sync cycle (Delta Import, Delta Sync, Export) and showInAddressList
should get set to its synced value. For this example user, that would be a null
value.</p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyFvewuBqQ-Cdcr-HyNVRE4Mzj860oSH3RU0nHXLY4aIEoxNh_8mLC-hOS-mRuNkGH_ZjDca550DmtJO1d09_vIcpgP1RquCewieBvoLvAAecYa10AVi6nct-LD3WVf7bg46vQxAwaPWT1/s690/HomeTenantPendingExport2W.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="541" data-original-width="690" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyFvewuBqQ-Cdcr-HyNVRE4Mzj860oSH3RU0nHXLY4aIEoxNh_8mLC-hOS-mRuNkGH_ZjDca550DmtJO1d09_vIcpgP1RquCewieBvoLvAAecYa10AVi6nct-LD3WVf7bg46vQxAwaPWT1/s16000/HomeTenantPendingExport2W.png" /></a></div><br /><p></p><p class="MsoNormal">After exporting the updated showInAddressList value, we can confirm that our GALSync is functional. Log in to Outlook on the web in the home tenant, open the People app and select the All Users GAL. We should see our newly synced user present in the GAL.</p><p class="MsoNormal"></p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2neAx49XH7V-Clu0SKnXkuReEOoEU2oAQeFb77XuI2aTlvTscYDfNKaV7tIs2z3kdlCAcMRF0FZhqvIS4zWU1lg6D5j0hr68Gd5-lCZ87NmCL6vIQvFd-iMmO74uwvfvDexFryeQyOvNX/s1024/HomeTenantGALW.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="302" data-original-width="1024" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2neAx49XH7V-Clu0SKnXkuReEOoEU2oAQeFb77XuI2aTlvTscYDfNKaV7tIs2z3kdlCAcMRF0FZhqvIS4zWU1lg6D5j0hr68Gd5-lCZ87NmCL6vIQvFd-iMmO74uwvfvDexFryeQyOvNX/s16000/HomeTenantGALW.png" /></a></div><br /><p></p><p class="MsoNormal">Finally, to complete the deprovisioning aspect of the GALSync, configure the Object Deletion Rule for the person object class to delete the metaverse object when the partner tenant connector is disconnected, and set the MA's Deprovisioning action to Stage a delete. This way, a deletion of the user from the partner tenant will cascade a delete of the external B2B user to our home tenant.</p>
<p class="MsoNormal">Thatâs the end of the setup for GALSync from a single source
to a single destination tenant.</p>
<p class="MsoNormal">As I alluded to at the beginning, more complex setups are
possible. Consider a bi-directional GALSync where the partner tenant also needs
the users from our home tenant. One way to keep the architecture simple is to
maintain one MIM instance per tenant; we simply duplicate this setup in the
opposite direction. This is identical to the AADC architecture where one AADC
is needed for each tenant. It allows the provisioning code to know the tenant for
which it is responsible, cleanly separates inbound from outbound flows and causes
no precedence problems. It also allows the partner to control the app
registration which possesses write access into their tenant.</p>
<p class="MsoNormal">Or consider a full-mesh setup where the tenants are all
peers in one org that decided to segment their tenants for some reason. We
could design a single MIM solution that manages every tenant. We could do two
connectors to each tenant to allow us to separate internal user from external and
continue to manage the flows separately. Weâd only have to prevent same-tenant
provisioning in the provisioning code. I could also see a solution that uses
only one connector to each tenant. We could come up with a mechanism to track
authority of address spaces, so we know which source tenant is responsible for
each user and use that knowledge to then create the external B2B users in the
other tenants.</p>
<p class="MsoNormal">For larger deployments where we might have concern about the
number of disconnectors and corresponding delta sync times, there are a few
advanced techniques we could implement to alleviate that concern. We could project
and terminate objects in the metaverse instead of keeping them as
disconnectors. Or we could replace the Graph Connector with a PowerShell
Connector and take care of all the Graph logic ourselves, avoiding the
scenarios where the Graph Connector has limitations.</p>
<p class="MsoNormal">Hopefully, this has shed some light on considerations for a modern
GALSync solution.</p>
<p class="MsoNormal">Thanks for spending a little bit of your time with me.</p>
<p class="MsoNormal">-Dave</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Disclaimer: The sample scripts are not supported under any
Microsoft standard support program or service. The sample scripts are provided
AS IS without warranty of any kind. Microsoft further disclaims all implied
warranties including, without limitation, any implied warranties of
merchantability or of fitness for a particular purpose. The entire risk arising
out of the use or performance of the sample scripts and documentation remains
with you. In no event shall Microsoft, its authors, or anyone else involved in
the creation, production, or delivery of the scripts be liable for any damages
whatsoever (including, without limitation, damages for loss of business
profits, business interruption, loss of business information, or other
pecuniary loss) arising out of the use of or inability to use the sample
scripts or documentation, even if Microsoft has been advised of the possibility
of such damages.</p><br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-66690322456134447152021-02-16T16:18:00.001-05:002021-02-16T16:18:20.750-05:00MIM account deprovisioning déjà vu<p>I was doing some research for one of my customers that was having an AD account provisioning problem with MIM. I wanted to make sure that I wasn't introducing a potential deprovisioning problem with my change for them, so I was revisiting the deprovisioning scenarios in my lab. I hit on this support forum article: <a href="https://social.technet.microsoft.com/Forums/en-US/bc2c4c96-dd88-4acd-8b79-a3696832bf28/fim-2010-r2-deprovisioning-with-outbound-system-scoping-filters">FIM 2010 R2 Deprovisioning with Outbound System Scoping Filters (microsoft.com)</a>. Reading through that and get to the bottom and see that it was asked and summarized by <i>me</i>. About a decade ago. Totally forgot about that work. No deprovisioning improvements ever came to FIM/MIM. At least AADConnect does a nice job of declarative deprovisioning when falling out of scope of a provisioning rule.</p>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-60240516983935312952020-04-13T09:52:00.003-04:002020-04-13T09:52:47.753-04:00Getting Reports from Long Running Performance Monitor Data Collector Sets Cross Post<span style="background-color: #f6f6f6; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px;">My </span><a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/getting-reports-from-long-running-performance-monitor-data/ba-p/1302545" style="background-color: #f6f6f6; color: #de7008; font-family: "Trebuchet MS", Trebuchet, Verdana, sans-serif; font-size: 13px;" target="_blank">Getting Reports from Long Running Performance Monitor Data Collector Sets</a><span style="background-color: #f6f6f6; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px;"> post is now up on the </span><a href="https://techcommunity.microsoft.com/t5/Core-Infrastructure-and-Security/bg-p/CoreInfrastructureandSecurityBlog" style="background-color: #f6f6f6; color: #de7008; font-family: "Trebuchet MS", Trebuchet, Verdana, sans-serif; font-size: 13px;" target="_blank">Core Infrastructure and Security</a><span style="background-color: #f6f6f6; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px;"> Tech Community site.</span>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-22616645690556844372020-04-03T10:56:00.004-04:002020-04-03T11:21:45.767-04:00Migrated Code/Scripts From Technet Script Gallery To GitHubIf you did not know already Microsoft will be retiring Technet Script Gallery. More information here: <a href="https://docs.microsoft.com/en-us/teamblog/technet-gallery-retirement">https://docs.microsoft.com/en-us/teamblog/technet-gallery-retirement</a><br />
<br />
â<br />
<br />
Currently it is in read-only mode, which means you can edit existing contributions as an owner, but you will not be able to add new contributions. In June 2020 Microsoft will shut it down. Therefore if you have your code stored there, make sure to get it and migrate it to GitHub. If you need scripts from it, go and get those scripts before the shutdown.<br />
<br />
â<br />
<br />
My scripts are still available in Technet Script Gallery, but I also already migrated them to my new GitHub public repository at <a href="https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts">https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts</a><br />
<br />
<br />
<br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-47681752139009673842020-01-24T08:59:00.001-05:002020-04-23T12:58:23.862-04:00Getting Reports from Long Running Performance Monitor Data Collector Sets<br />
When trying to track down an elusive Active Directory performance problem, gathering stats using the <a href="https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc749249(v=ws.11)">Active Directory Diagnostics Data Collector Set</a> is the best method for insight as to what the Domain Controller is doing. However, having super busy DCs and not knowing exactly when the problem is going to occur can make capturing the data and generating a useful report harder. There are also limitations with the Data Collector Sets that we have to take into consideration to come up with a solution that really works.<br />
<br />
Let me start with explaining how, and more importantly when, the various features of the Data Collector Sets work.<br />
<br />
The first thing to know is that you cannot change the properties of the built-in System Data Collector Sets. You must create a custom User Defined Data Collector Set to be able to change its behavior. Create a new Data Collector Set by right-clicking the User Defined node and select New > Data Collector Set. Give it a name, create it from an existing template. Use the Active Directory Diagnostics as the template. Finish the wizard.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyyCxvy4b1s8eN7BGYg5Rr9fWuJa0Bt-OITlfe8EC3YNrq4SrOKbw1jNSnqTz-MpToqZc4sKUk8q8EfABDToL4FSWKrV52bplCzXE_3y-vZqsV3fwI05JVF3ZUSpiGDoKt7c64DnRwFPDQ/s1600/NewDataCollectorSetW.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="262" data-original-width="557" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyyCxvy4b1s8eN7BGYg5Rr9fWuJa0Bt-OITlfe8EC3YNrq4SrOKbw1jNSnqTz-MpToqZc4sKUk8q8EfABDToL4FSWKrV52bplCzXE_3y-vZqsV3fwI05JVF3ZUSpiGDoKt7c64DnRwFPDQ/s1600/NewDataCollectorSetW.png" /></a>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
The DCS has settings that can be used to keep the collection from consuming too much disk capacity. Right-click the new DCS and select Data Manager Settings. The Resource Policy of Delete Oldest causes older folders to be deleted to keep from growing too large. You can adjust the size or folder count as needed. However, two things have to occur to have the data purging trigger. First, the âEnable data management and report generationâ property has to be selected. It should be selected by default. But second, these Data Manager rules donât trigger until the DCS stops. Thatâs an important distinction for the next set of DCS properties.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfK-Nz4aKCZqtMZ_OzZpWn9c-KkcPtM236yBdiO3QQ2NKEqK7UZA9m_ah7W5_SwUDoi6LgeLdwJlICxMokVKD3jn_6KgcoTC2xPEUrYz6OIRFktmf9lwE5gsO_-F_HtDpdAmubi2NkhuoE/s1600/DCSSizeW.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="461" data-original-width="413" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfK-Nz4aKCZqtMZ_OzZpWn9c-KkcPtM236yBdiO3QQ2NKEqK7UZA9m_ah7W5_SwUDoi6LgeLdwJlICxMokVKD3jn_6KgcoTC2xPEUrYz6OIRFktmf9lwE5gsO_-F_HtDpdAmubi2NkhuoE/s1600/DCSSizeW.png" /></a>
<br />
<br />
Now right-click the DCS, select Properties and switch to the Stop Condition tab. The Overall duration, which defaults to 5 minutes, controls when the DCS will automatically stop. Overall duration is the <strong><u>only</u></strong> setting that causes the DCS to stop on its own. The Limits section can be used to force the DCS to start using a new folder with new files for its collection, but setting a limit does not stop the DCS and therefore does not trigger the data purging configuration that is set in the Data Manager section. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKP5my2pNJjdHV1qIFLcnXSmCkRXE3WCcTzXW1KzZ9uZohEYXVaFZYFiRdQY3e5fpqARuyy2AmDQCguBXWP9Zk9i7S7KnqZknhQ0z-fl1VCNaaFr3I2_YRmY6NLqAZkp1eJSIJZrhmbhF/s1600/DCSStopNoRestartW.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="464" data-original-width="416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKP5my2pNJjdHV1qIFLcnXSmCkRXE3WCcTzXW1KzZ9uZohEYXVaFZYFiRdQY3e5fpqARuyy2AmDQCguBXWP9Zk9i7S7KnqZknhQ0z-fl1VCNaaFr3I2_YRmY6NLqAZkp1eJSIJZrhmbhF/s1600/DCSStopNoRestartW.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
The final feature of a DCS to explain is the report feature. Like data purging, report generation also only occurs when the DCS stops. Only the collection folder that was active when the DCS was stopped is used as the input source for the report. If you configure a limit and end up with multiple source folders for a single execution, only the last folder is used. Also, the size of the collected data in the collection folder determines how long the report generation will take. Larger source data results in longer report generation times. While the report is being generated, all data collection has stopped and that same DCS cannot be restarted. Other than the report name in the Data Manager section, there is no GUI for managing report definitions.<br />
<br />
With this explanation for how a DCS works complete, I have a problem I had been trying to solve for a customer of mine. They had an elusive Active Directory performance problem that they couldnât predict when it would happen, couldnât cause it to happen on demand and it could be many days before it reoccurred. But they could tell when it had happened and wanted more diagnostic data for what the Domain Controller was doing at that time.<br />
<br />
So we needed our DCS to behave with the following characteristics:<br />
<ul>
<li>Continuously capture data over several days without gaps</li>
<li>Do not save more data than the DC capacity</li>
<li>Generate a report against an identified collection</li>
</ul>
The first problem to solve is how to collect data without gaps yet still allow purging to run. The solution is to allow the DCS to stop, so purging can happen, but not run a report when it does stop so we donât waste capture time running a report against a time period that likely didnât include the event we were trying to capture. Thereâs no GUI for the report definition. Itâs located in the XML of the DCS itself. Right-click your custom DCS and select Save Template. Open the XML in notepad and find the ReportSchema node. Youâll see there are nine report definitions that are included. Delete all the Imports except one and change the file to a non-existent filename. Having one invalid Import for the report causes the smallest possible report to be generated, which finishes in a fraction of a second, minimizing the amount of time weâre not collecting data. Having zero Report Imports causes a default set of reports to run, which we want to avoid since they take time to finish. Save the edited content to a new XML file.<br />
<br />
That section of XML should now look something like this:<br />
<blockquote>
<ReportSchema><br />
<Report name="wpdcAdvisor" version="1" threshold="9999"><br />
<Import file="%systemroot%\pla\reports\NoReport.xml"><br />
</Import><br />
</Report><br />
</ReportSchema></blockquote>
With this change to the XML complete, create a new DCS from a template, but this time browse to the edited XML file instead of selecting from the list.<br />
<br />
For this new DCS, set the Data Manager purging rules as needed and clear the Overall duration checkbox for the Stop Condition. Now we have a DCS that we can start and when we stop it, it quickly stops, creates a very small, useless report and purges the oldest data. By clearing the Overall duration checkbox, this DCS will run until stopped by another method (manual or scripted). It will not stop on its own.<br />
<br />
On my customerâs busy DCs we canât let the collection run too long, otherwise thereâs a chance a report can never be generated so our plan is to stop and start the DCS once an hour. The built in scheduler on the DCS properties isnât that great so weâll use Task Manager instead. We created a small batch file with these commands:<br />
<blockquote>
logman.exe stop AD_DCS_NoReport<br />
logman.exe start AD_DCS_NoReport</blockquote>
Then we created a task that ran under the SYSTEM account that ran that batch file once an hour.<br />
<br />
After the event reoccurred, we knew what collection set the data should be in, so we needed to generate a report for that particular 1 hour block, which we have to do manually. In each DCS collection folder, you should see four files: Active Directory.etl,
AD Registry.xml,
NtKernel.etl and Performance Counter.blg. There is a fifth file that we need to generate the report. We will manually create it. Create a new text file in the folder called reportdefinition.txt. In that text file, add the following XML and save it.<br />
<blockquote>
<Report name="wpdcAdvisor" version="1" threshold="9999"><Import file="%systemroot%\pla\reports\Report.System.Common.xml"/><Import file="%systemroot%\pla\reports\Report.System.Summary.xml"/><Import file="%systemroot%\pla\reports\Report.System.Performance.xml"/><Import file="%systemroot%\pla\reports\Report.System.CPU.xml"/><Import file="%systemroot%\pla\reports\Report.System.Network.xml"/><Import file="%systemroot%\pla\reports\Report.System.Disk.xml"/><Import file="%systemroot%\pla\reports\Report.System.Memory.xml"/><Import file="%systemroot%\pla\reports\Report.System.Configuration.xml"/><Import file="%systemroot%\pla\Reports\Report.AD.xml"/></Report></blockquote>
You may recognize that these are the same files that show up in the XML that we edited.<br />
<br />
Finally, execute the following command line from within the capture directory you want to use for the report.<br />
<blockquote>
tracerpt.exe *.blg *.etl -df reportdefinition.txt -report report.html -f html</blockquote>
If everything went right, you should end up with a normal DCS diagnostic report that you can review which covers the time period from when the event occurred.<br />
<br />
As a neat trick, if you need to see more than the top 25 items that the report defaults to, you can run the following command to get full XML output:<br />
<blockquote>
tracerpt.exe âlr "Active Directory.etl"</blockquote>
For additional reading on similar issues that led me to this solution, I offer up the Canberry PFE team blog <a href="https://docs.microsoft.com/en-us/archive/blogs/canberrapfe/issues-with-perfmon-reporting-turning-etl-into-html">Issues with Perfmon reporting - Turning ETL into HTML</a>, the Directory Services Team blog <a href="https://docs.microsoft.com/en-us/archive/blogs/askds/are-your-dcs-too-busy-to-be-monitored-ad-data-collector-set-solutions-for-long-report-compile-times-or-report-data-deletion">Are your DCs too busy to be monitored?: AD Data Collector Set solutions for long report compile times or report data deletion</a> and the Core Infrastructure and Security blog <a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/taming-perfmon-data-collector-sets/ba-p/255521">Taming Perfmon: Data Collector Sets</a>.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-24734512512819945952019-11-12T13:38:00.000-05:002020-01-24T14:42:45.072-05:00Disconnecting Objects with AADConnect Default Filtering<br />
If you're familiar with MIM, you know there exists the capability to disconnect an object from the metaverse to force it to go through the join/provision process again. This is useful when the object was joined to the wrong metaverse object for some reason (like a bad join ruleset or incorrect data at the time of joining) and you want to have it be reassessed like it was a new object. In AADConnect, the disconnect function has been removed.<br />
<br />
If you have the ability to change (or get changed) the original AD data, you can leverage the default filtering rules to temporarily disconnect an object. This is the main topic for this blog post. If you canât get the original AD data changed, you can follow the process in my original <a href="https://dloder.blogspot.com/2018/11/disconnecting-objects-with-aadconnect.html">Disconnecting Objects with AADConnect</a> post that shows an AADC-only method.<br />
<br />
This feature is kind of hidden, not well documented, and not obvious when you see it.<br />
<br />
If you look at the default filtering rules for the In from AD - User Join or In from AD - User Common rules, youâll see these default scoping filters:<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyfpbOHS3aDqaYzaMHwqwY3hb8EmqL-kRufs7vLI75UIux5hSU7o_LKlTknsQJqf8MW2LWMYdgRsXt0vfdh_3Rj28-ZLb9WemWvqBK0zFmVRmJw8GpKvFk5JUlj9nb8jVaO3x-MHkIYPwv/s1600/defaultfilter.png"><img alt="defaultfilter" border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyfpbOHS3aDqaYzaMHwqwY3hb8EmqL-kRufs7vLI75UIux5hSU7o_LKlTknsQJqf8MW2LWMYdgRsXt0vfdh_3Rj28-ZLb9WemWvqBK0zFmVRmJw8GpKvFk5JUlj9nb8jVaO3x-MHkIYPwv/s1600/defaultfilter.png" style="background-image: none; display: inline;" title="defaultfilter" width="823" /></a><br />
<br />
The filter weâre concerned with is<br />
<blockquote>
adminDescription NOTSTARTSWITH User_</blockquote>
For a source object to attach to an inbound rule it must satisfy the conditions in the scoping filter. In this case, so long as adminDescription does not start with âUser_â it will pass the filter and attach to the rule. AdminDescription is blank on all objects by default so the normal projections and data flows happen.<br />
<br />
So if you put a value of âUser_<something>â on a user object, it will no longer attach to this rule. And because In from AD - User Join is our sole default provisioning rule, once an object loses that rule, it is no longer allowed to project into the MetaVerse and becomes a disconnector!<br />
<something><br /></something>
Once disconnected, you can make any other data changes that are needed to retry a join or re-provision. When ready, clear the adminDescription and the disconnector object will be reevaluated at the next delta sync run like any other new object.<br />
<br />
Groups have a similar default filter of adminDescription NOTSTARTSWITH Group_ that can be used to disconnect groups.<br />
<br />
I have a customer with a few scenarios where users need to be disconnected, so they enacted workflows to stamp User_Transfer or User_Disable on objects at specific points in their lifecycle.<br />
<br />
Now you can easily disconnect objects and reevalute and hopefully not miss the lack of a disconnect button anymore.<br />
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-48634365060558855712019-09-19T11:13:00.003-04:002019-09-19T11:13:43.839-04:00Azure AD Connect Resilient Operations Cross PostMy <a href="https://techcommunity.microsoft.com/t5/Core-Infrastructure-and-Security/Azure-Active-Directory-Connect-Resilient-Operations/ba-p/863316" target="_blank">Azure AD Connect Resilient Operations</a> post is now up on the new <a href="https://techcommunity.microsoft.com/t5/Core-Infrastructure-and-Security/bg-p/CoreInfrastructureandSecurityBlog" target="_blank">Core Infrastructure and Security</a> Tech Community site.David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-85904326620292350482019-04-18T09:16:00.001-04:002022-09-01T11:43:41.178-04:00Changes to Ticket-Granting Ticket (TGT) Delegation Across Trusts in Windows Server (PFE edition) I helped with some content referencing the upcoming May and July 2019 patches that change the default behavior for cross-forest unconstrained delegation. The full post is available at the new TechCommunity home of the <strike><span style="color: #cccccc;">AskPFE</span></strike> Core Infrastructure and Security blog.<br />
<br />
<a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/changes-to-ticket-granting-ticket-tgt-delegation-across-trusts/ba-p/440261">https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/changes-to-ticket-granting-ticket-tgt-delegation-across-trusts/ba-p/440261</a>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-22926792787657940792018-11-12T13:07:00.002-05:002021-03-01T13:08:50.128-05:00AADConnect Resilient Operations<div><b><span style="font-size: large;">Content Update Notice</span></b>: This blog was written before the introduction of the <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-import-export-config">Config Import feature</a>. Follow that process to easily copy over the custom rules and OU selections from an existing AADC installation.</div><div><br /></div>In my job as an Identity-focused Premier Field Engineer, I get to help many companies on their journey from being solely on-premise to becoming a cloud-first enterprise. But the one thing all of them have in common is that they will be in a hybrid setup for the foreseeable future. Hybrid is the new IT reality. For most Microsoft customers that means <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect">Azure AD Connect</a> is your Identity Bridge between on-premise and the Azure Cloud. I have found that not all the customers with which I work have a full understanding of how AADConnect is designed to function or how to ensure their AADConnect infrastructure is running smooth and is resilient to failure.<br />
Resilient operations for AADConnect involves three main topics that I wanted to cover today: Health, High Availability (HA) and Upgrades.<br />
<h2>
Synchronization Health</h2>
The ideal operational state for AADConnect has two characteristics for which we look. The first is that no errors occur during any stage of the sync process. This snapshot from my lab shows entire sync cycles running without error. All the import, delta syncs and exports have a status of success.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ9xl-XLS5tp3-4-D0okoryxiImRo9VdDrm1CNBz6JzsfTHqPxi_GJbXFmyPpvJA64mKGOYJDpdAfzgPPaqqtSR50m5PphbYqpcYVlJ7l6PCimQaeDalQnYjO7vCG5LB17ofmK1lOCxYQy/s1600-h/clip_image0026"><img alt="clip_image002" border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiduQkhXc8YNwP-8Hzfx0a_RzU0x6Su2ayHO2uCfNrv5oxiD5kwDJN0nOCvsvLxGmmJzAZK6p7k-CaDh3Mou7t5K319Y3wFe6L_uJmIdTDLA3WZcQZz_u3KrIbBEayioCmDdkIQJhNMdorL/?imgmax=800" style="background-image: none; display: inline;" title="clip_image002" width="628" /></a><br />
Any current version of AADConnect will have the <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-health-sync">health agent</a> installed. The health agent will report into your Azure AD portal any data sync issues that are occurring. Itâs more likely that you are working in the portal than looking at the Sync Manager, so surfacing the errors in the portal should give more visibility to any errors that exist. You need to work on clearing out any errors that exist. Iâve seen too many environments where errors are allowed to persist, and the companies wonder why they have account problems in Azure AD. Having zero errors will also make future upgrades and changes easier. Weâll see why later.<br />
The second characteristic we want to see is AADConnect having zero disconnectors in each of the connectors. Those of you not familiar with how the sync engine works in AADConnect (or in MIM) may not know what a disconnector is. The simple answer is that a disconnector is an object in the connected directory that is in scope, yet not being managed by the sync engine. The more complete answer is described in the <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/concept-azure-ad-connect-sync-architecture">architecture document</a>.<br />
Having zero disconnectors on your Azure AD connector means that every object in Azure AD is being actively managed by the sync engine.<br />
Disconnectors are reported during the Delta Sync phase for the connector.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKUAho2Dxx66aCkzskaiRAu3yyuaW-NYdgViBZMkOmH2kieOYThdjQXTJ6oMSn3Yxxty0VInl0jWRBpzQdcbir3g5ob3Uq-vr13oxZurRDb5hlAOvcK90dJSWfVAXSoZ9okXG4vQkpuKXX/s1600-h/clip_image0046"><img alt="clip_image004" border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7IRjo2juKA8BniybefOTItRg07H6cu0Zh1AEu91G9OmXjggRJw3GpWe-RDXJk8BLaLvbiKCCL09XK8TfYSieVdNFiwGJY9Lhs5eDllx8_MWYvGbCxaWDDIlhMXSKne4JLx-R1z6zL_sMe/?imgmax=800" style="background-image: none; display: inline;" title="clip_image004" width="628" /></a><br />
This shows that I currently have one disconnector in Azure AD. Disconnectors in Azure AD are especially troublesome as it means nothing is managing that object in Azure AD. It will never get changed or deleted by AADConnect.<br />
To figure out what the disconnector is we need to run the command line tool CSExport to export the disconnectors.<br />
The syntax to use for exporting disconnectors is csexport.exe MAName ExportFileName /f:s /o:d<br />
As an example in my lab, to get the disconnectors for the Azure AD connector I run<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: "andale mono", "lucida console", monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;"><code>C:\>"C:\Program Files\Microsoft Azure AD Sync\Bin\csexport.exe" "loderdom.onmicrosoft.com - AAD" c:\temp\aaddisconnectors.xml /f:s /o:d
Microsoft Identity Integration Server Connector Space Export Utility v1.1.882.0
c 2015 Microsoft Corporation. All rights reserved
[1/1]
Successfully exported connector space to file 'c:\temp\aaddisconnectors.xml'.
</code></pre>
This will output an XML file with the details of every disconnector. In my case, I had a leftover device from testing <a href="https://docs.microsoft.com/en-us/azure/active-directory/devices/hybrid-azuread-join-plan">hybrid Azure AD join</a>. After deleting the device from Azure AD, my disconnector count returned to zero.<br />
You need to work your way through the XML document and figure out why each object is disconnected. Should it have been connected to something in Active Directory and isnât? Is it an orphaned object in Azure AD that needs to be deleted? The goal is to have zero disconnectors for the Azure AD connector.<br />
For any Active Directory connectors you have, the goal is also to have zero disconnectors, but itâs more difficult to achieve a value that is absolutely zero. This is because any container-type objects (such as the OUs that contain the users) get reported as disconnectors. So realistically, weâre looking to achieve a count of disconnectors that is low and static so that we can tell if the number of disconnectors has changed.<br />
To minimize the number of disconnectors that occur because of the OUs, you can run through the configuration wizard and only select the OUs with users and computers that you care about, unchecking the OUs that arenât needed.<br />
A word of caution here. Donât just unselect random OUs without being absolutely certain they arenât needed. If an OU is deselected and it contained objects that were being synched into Azure AD, those objects will be deprovisioned from Azure AD. You can mitigate this risk by using a staging server to test a new configuration change before the change goes live. Weâll talk more about staging mode later.<br />
If your AD setup is such that you have a small and static number of OUs selected, you can ideally end up with a disconnector count around 10 or so. Know what that number is for your environment, so that if it changes that means you have a new disconnector that should be reviewed and remediated. If your AD setup has lots of OUs that need to be included, and the number of OUs keeps changing (maybe you have an OU per site or department and those change frequently), you can create a custom inbound rule that will project the OUs into the metaverse. This changes the OUs into connectors and returns you to a state where the number of disconnectors should be almost zero. See Appendix A for how to create the necessary rule for connecting OUs. <br />
In summary for this section, an AADConnect server with zero errors and zero disconnectors means we are running a well-managed environment that has no data problems affecting the sync operations of AADConnect.<br />
<h2>
High Availability: Using a Staging Server</h2>
The good news for AADConnect is that the sync engine itself is not involved with any run-time workloads for your users, reducing our HA requirements. You could shut off the AADConnect sync service and your users would still have access to all their Azure and Office 365 resources. Changes to user data (adds, deletes, changes) wonât happen, but that doesnât affect availability in the short-term. However, depending on which <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect-user-signin">sign-on option</a> you are using, there may be additional considerations. If you are performing <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnectsync-implement-password-synchronization">Password Hash Sync</a>, that sync process runs on its own every two minutes. Users could be impacted if they change their AD password and AADConnect isnât running; there will be a mismatch between their cloud password and their on-premise AD password. If you are performing <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect-pass-through-authentication">Pass-through Authentication</a> the first agent is installed on the AADConnect server; you need to install additional agents on other servers to provide HA for that feature. If you have configured <a href="https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-sspr-writeback">Password Writeback</a> then the AADConnect service needs to be running for the Service Bus channel to be open. Finally, if you use ADFS, HA designs for federated sign-on are out-of-scope for this AADConnect discussion.<br />
Accordingly, we need some measure of HA to keep the Azure AD data from becoming too stale. âToo staleâ is a relative term. For a small environment with few changes that may mean you can run for weeks without AADConnect running and not experience any issues. For larger environments, you may not want to have AADConnect be down for more than a few hours.<br />
The major HA design model for AADConnect is to have a second, fully independent installation of AADConnect that runs in <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnectsync-operations">staging mode</a>. This server will see all the same data changes that happen in AD, is configured with the same rule sets as the active server and validates that the changes it expects to see in Azure AD were actually made in Azure AD by the active server. The general concept is that if both servers see the same input, and have the same rules, they will both independently arrive at the same output result. The <a href="https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnectsync-operations">Operation tasks</a> topic goes into detail as to how to set up the staging server, but it neglects to cover how to realistically get the same input, the same rules and the same output on both sides. All three are problems Iâve seen in the field for implementations that have some measure of customization in the rules and, shall we say, less than pristine data sources.<br />
Letâs start with making sure we have the same rules on both the active and staging server. To get your customizations on the staging server, you can either create them all by hand via the GUI or leverage the export capability from the active server. When you select one or more rules in the Rules Editor and select Export, youâll get a PowerShell script generated that can almost be used to create the same rule on the staging server. The main problem with the generated PowerShell script is that it uses GUIDs to represent the connectors, and those GUIDs are unique to the AADConnect server on which they were created. The same connector will have a different GUID between the active and staging servers. But if you manually adjust the Connector GUID youâll be able to run the script to recreate the custom rule. The PowerShell script is designed to create a new rule, not apply customizations to an existing rule. This means itâs a good reason to follow the GUI guidance when customizing a built-in rule to disable the built-in rule and create a new one to hold the customizations.<br />
Now that weâve attempted to configure the same rules on both sides, how do we confirm that we successfully accomplished that task? I have a <a href="https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts/wiki/Reformat-AADConnect-Sync-Rule-Export-for-Easy-Comparisons">PowerShell script in GitHub called Reformat AADConnect Sync Rule Export for Easy Comparisons</a> that will use the exported PowerShell scripts and an export of the connector configuration to generate a version of the creation scripts that is designed for comparison using WinDiff or similar comparison tool. Each rule is rewritten into its own file, making it much easier to perform a rule-by-rule comparison without needing to export each rule one at a time.<br />
When looking at the results of the comparison, you will generally find two categories of differences even when all the rules appear to have been duplicated appropriately. The first category is made up of the internal Identifier GUIDs of the rules themselves. Like the Connector GUIDs, each rule has an internal GUID that is unique per server. This difference can be ignored. The second category youâre likely to find is due to newer versions of AADConnect having different default rules than earlier versions. Newer rules usually add in new attribute flows, change calculations or introduce entirely new rules. When this occurs the precedence number for each rule can also change, resulting in more differences showing up when comparing the two different rule sets. But, after youâve looked at a few of the difference details, youâll notice the pattern and can quickly complete the validation that no other unexpected differences show up in the report.<br />
Hereâs an example WinDiff comparison between an active server and a staging server that was upgraded with a more recent build. Weâre looking specifically at the In from AD â Group Common rule.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaenKUeaNdLovx7lAC1uf5mXeDKfOzfeHvceCy7VfjkFXG7Nclz-JOl-EiZmjdRiwtGSBpCOq3BDduOxfil7t8xgL4XI6Vqf04ocJiiuW7R8Vkd1gzZSYDI51CtnSST4LYyUsA6_2VfW01/s1600-h/clip_image0066"><img alt="clip_image006" border="0" height="637" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3pqfX6PbyKrXSE_N1qhh0zQ2mlxb0Kn6O5XYqN46ShCV90_-gRvrj5CAqJRcXMygaHR5Xbu0vQMXrb0VoHYcLKoAmzXdjL8Eks6HXEtO2SZi2m8bZNQ9x7_0VxfgyDbarGnqr1tk54DYi/?imgmax=800" style="background-image: none; display: inline;" title="clip_image006" width="628" /></a><br />
You can see the differences in the GUIDs (lines 3 and 11). Because this upgrade also has a new data flow, you can see additional changes to the ImmutableTag (line 14) and the new data flows (new section starting at line 170).<br />
Please keep in mind that this comparison task is really designed to help make sure your own customizations were successfully duplicated. If there has been a change to one of the default rules in a newer version of AADConnect, like in this example, do not attempt to revert the rule back to a prior version. The newest default rules are almost always correct and represent the best default data flow for Azure AD that is currently available. But knowing that a default rule has changed is important for the following steps of getting a new staging server ready.<br />
Next, we will want to confirm that the input data on the staging server is the same as on the active server. Going through the configuration wizard you can manually validate that the same OUs have been selected on both sides. Or you can use an export of the Connector configurations and compare the saved-ma-configuration/ma-data/ma-partition-data/partition/filter/containers sections of the XML documents. To export a Connector configuration, open the Synchronization Service GUI on the AADConnect server, navigate to the Connectors tab, highlight a connector and select Export Connector from the Actions menu. Provide a File name and click Save.<br />
Finally, and most importantly, is to validate that the same output results are occurring on both the active and staging servers. This is done by examining the export queues on the staging server. When in staging mode the one and only difference from active mode is that no export steps are executed.<br />
Letâs have a quick discussion on how export data is created. In AADConnect, when a synchronization step is executed, the inbound rules from that specific connector and all outbound rules for all connectors are executed against each object being synced. The results of the sync task are compared to AADConnectâs current view of the connected data source (from the last time the object was imported) and any differences in data flows due to changed input values or different rules are computed and stored in the export queue. When the export step happens, the pending exports are written to the connected data source. However, because weâre in staging mode, the export step doesnât happen and all the changes that AADConnect wants to make are nicely kept in the export queue for us to review.<br />
Now that we know how the exports are constructed, we can see what happens in the ideal case. In the ideal case, the staging server has all the same input data from AD as the active server; it has the exact same rules; and it calculated the exact same final state of the objects as they already exist in Azure AD. Therefore, it has no changes that it wants to apply to Azure AD, so the export queue is empty. When the export queue is empty, the staging server is ideally situated to take over for the active server as it will immediately pick up from where the active server left off.<br />
Unfortunately, the production systems I usually see are far from ideal. They have errors that are present, they have disconnectors that are present, and they have high volumes of changes being processed through them. This means the export queue on the staging server is almost never empty. Therefore, we need to analyze the export report to figure out why the staging server thinks that it has data that it wants to change.<br />
To improve our analysis ability, we need to make sure weâve accomplished the health status items we talked about earlier. We need to eliminate errors and minimize the disconnectors in the active server. Then we can go about trying to remove the noise that is due to transient data changes that are flowing though the active server and eventually seen by the staging server. To do this we can compare the pending exports between the active server and the staging server at two different points in time. By putting a delay in the comparison, we can ensure that the staging server has seen the changes that the active server was in process of making. The first pass generates a list of potential changes that we care about. If those same changes are still present a few hours later, after several sync cycles have run, then we can be sure the changes are not in the queue simply due to an in-process change.<br />
We end up needing a total of four exports for each Connector to run this comparison. Thatâs one each from the active and staging servers to start with, then a second set of exports from both a few hours later after some sync cycles have run. Generating an export file is a two-step process. We first look at the pending exports by returning to csexport.exe with syntax of csexport.exe MAName ExportFileName /f:x. After generating the XML document of the pending exports, we convert that to CSV using the CSExportAnalyzer with syntax like CSExportAnalyzer ExportFileName.xml > %temp%\export.csv<br />
In my lab, one instance of those commands looks like this:<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: "andale mono", "lucida console", monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;"><code>C:\Program Files\Microsoft Azure AD Sync\Bin>csexport.exe "loderdom.onmicrosoft.com - AAD" c:\temp\aadexport.xml /f:x
Microsoft Identity Integration Server Connector Space Export Utility v1.2.65.0
c 2015 Microsoft Corporation. All rights reserved
[1/1]
Successfully exported connector space to file 'c:\temp\aadexport.xml'.
C:\Program Files\Microsoft Azure AD Sync\Bin>CSExportAnalyzer.exe c:\temp\aadexport.xml > c:\temp\aadexport.csv
</code></pre>
Then I have a second <a href="https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts/wiki/Compare-AADConnect-Pending-Exports-Between-Active-and-Staging-Servers">script in GitHub called Compare AADConnect Pending Exports Between Active and Staging Servers</a> that compares these pending export CSV files looking for entries that never successfully get exported. On the active server, exports that never complete are usually due to errors that should be showing up in the error conditions we previously discussed. On the staging server, exports that are present in both sets of reports show the final set of data that the staging server will change when it is reconfigured to become the active server.<br />
From this final report, if there are unexpected exports sitting in the export queue of the staging server, we know they are due to one of the two things already discussed. Changes to the rules can result in a significant amount of new data being staged for export to Azure AD, especially when the updated rule is flowing new default data that wasnât being exported in previous versions of AADConnect. Changes to the input data can result in different sets of objects being prepared for export.<br />
While the report will tell us what is different, it doesnât directly tell us why. Fully analyzing the system to understand why the data is different is beyond the scope of this blog post. But hopefully weâve produced enough useful artifacts to help you discover the source.<br />
In summary for this section, a staging server is used to provide HA capabilities to AADConnect but building a staging server and getting it properly configured can be difficult. Iâve highlighted the main data elements we need to be managing to ensure the staging server has good data on which to operate. And Iâve laid out a methodology for comparing a staging server to an active server, so we can be aware of where differences occur. Finally, we have a way to validate the changes the staging server wants to make to the connected systems before cutting over and before any changes are made.<br />
<h2>
Upgrades</h2>
There are two ways to manage AADConnect upgrades. The first is to simply perform an <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-upgrade-previous-version">in-place upgrade</a> on the existing active server by running the new installer. It will make whatever changes it wants to make to the rules and will export the results to Azure AD. You can even automate the upgrade process by enabling the <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-install-automatic-upgrade">Automatic Upgrade</a> feature. My recommendation for automatic upgrades is to use this method only if youâve done no customizations to the rules.<br />
The second way is to make use of the staging server for a <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-upgrade-previous-version">swing migration</a>. Operationally, it will be identical to the process we already went through to build out the staging server in the first place. Run the upgrade first on the staging server. Perform the comparisons to ensure no unexpected changes were introduced in the upgrade process. If youâre comfortable with the data sitting in the export queue, proceed with putting the current active server into <a href="https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-sync-operations">staging mode</a>, then put the new staging server into active mode and it will start exporting the changes it was holding in its export queue. If all the changes processed without causing any errors, then you can upgrade the first server to bring it up to the same level as the newly active server. Now youâve fully swapped between the active and staging servers.<br />
I hope youâve found this discussion useful and have a better understanding of how to manage your AADConnect infrastructure to provide the best possible foundation for your hybrid Azure experience.<br />
<h2>
Appendix A: Connecting OUs</h2>
First, we need an object type in the metaverse to represent OUs. In the Sync Manager, go to the Metaverse Designer, create a new object and call it organizationalUnit. For the attributes, include displayName and sourceAnchorBinary.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZYw3RXpwJR7dijFDu3lSLmIfASQJa7hfofI4tyzgPHneX0IOaOFn5qKd7y4uu8Lxlwuyq9VmFCfpWSKaEP_JxXyoXyyvZZY2dlfaK6YNB0BWSIm5wDg8cEVMF3o1Xv_-QTFnTxexLY2Cf/s1600-h/clip_image0088"><img alt="clip_image008" border="0" height="327" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLOQ0Qa9TtHMa8J7emy0P94nIs_5vTlZDVrAidkT6hrTyOTxySggEWcOoye_T_5qowBgR96Z8DAiL2eJVlZXouYUGrXC0jFT0coqxUNf5KYeBGD09CXk2YwnJQmBQ_aVi0vinZVJKQRZc1/?imgmax=800" style="background-image: none; display: inline;" title="clip_image008" width="628" /></a><br />
In the Rules Editor, create a new Inbound rule. The connector is your AD forest, the precedent must be a unique, non-zero number (I picked 90). The object type is organizationalUnit. The Link Type is Provision. For the Join rules, include objectGUID = sourceAnchorBinary. For the transformations, include direct objectGUID to sourceAnchorBinary and direct dn to displayName.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXS6p32nHeMc17kbdgrIELM7LfEkt-GPaANYChM4Kre4N98NKm4iMeEHuXg7kwoPV68wzI7_oJcDuFbonDiqOfDpLaa2vvQ1q2Ado63sXjnQkyjrcWp5yFrr21OMqrQ41y1GXWHhmcLXEs/s1600-h/clip_image0106"><img alt="clip_image010" border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4oySdPckdY-y4HQt71D5xAIsAYHrVZ6XLn57Xz6xXsxyug9DRH-SmIpJSKjp4Nzy9nXTbhYts6cZKsFwvadBf8IU4myfqRJtYPKhSYwNYyEUwP4Hqxz40XDUYiH-QQpzD71iiylDXh5mC/?imgmax=800" style="background-image: none; display: inline;" title="clip_image010" width="628" /></a><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1OL3ZRqstu_b6T4u_Gr0p9-dCgWDra_vFgD3ywPKU6tQqFnUg0OO1DKJPMPYVOdMy0j5rvKjEp9DSmz9tUNVK0P3LRff0TufvOJOzXR3k5FMD1HH7DBxuA2T8ffOB2mvx9FvfWTbm3Gj9/s1600-h/clip_image0126"><img alt="clip_image012" border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8gCtxndeRvxGz6qUBEY7la58cznLlrKuEI6YBdMgcQD21fGYF4dJEiLiCBrXKfekaNqyCpxADVvzdejMahdALmAW9Qkz6_DmPE2HSuNFbeLXFR0arKGJSE6jljxBQZqa3aHmHsGmLaZz0/?imgmax=800" style="background-image: none; display: inline;" title="clip_image012" width="628" /></a><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUdeoDCunLfXwGK_TrA8sWB0MvtxQ5g9zAWZtGc-LXKumdLHamHoaigEIjkIdHnRlHGCxpCErJ3H3lMRleimKhJx10pLRfvH28QxOWTmc92K90DqbCpQTuNuTO45RRx_DwyWxV_-NsS9vx/s1600-h/clip_image0146"><img alt="clip_image014" border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyGx_Qk3iFuF19Bd7wk_NWfq_izxCeZVG-ftIbp0qBuu3NCLHIQsK6v8lTl5UtPSxAwvrh_ZP2oDGm2i5SCyRfs58z9RTmsbmsUcHMiS0CL2udHw1Q7nZRWdpBzgStgudr1yxnCVQawrdR/?imgmax=800" style="background-image: none; display: inline;" title="clip_image014" width="628" /></a><br />
<br />
<span face=""trebuchet ms" , "trebuchet" , "verdana" , sans-serif" style="background-color: #f6f6f6; font-size: 13px;">Updated 2020.04.03 </span><span face=""trebuchet ms" , "trebuchet" , "verdana" , sans-serif" style="background-color: #f6f6f6; font-size: 13px;">moved links to the GitHub Repository</span>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-13514646459019607912018-11-07T14:42:00.002-05:002019-11-12T13:54:14.968-05:00Disconnecting Objects with AADConnect<!-- http://formatmysourcecode.blogspot.com/ --> <br />
<div>
If you're familiar with MIM, you know there exists the capability to disconnect an object from the metaverse to force it to go through the join/provision process again. This is useful when the object was joined to the wrong metaverse object for some reason (like a bad join ruleset or incorrect data at the time of joining) and you want to have it be reassessed like it was a new object. In AADConnect, the disconnect function has been removed. The only supported way to cause an object to be reevaluated is to delete all objects from the connector space, and run a Full Import and Full Sync against all objects. That's a bit heavy handed when you have a large connector space and only want to reevaluate a single object.<br />
<br />
Update 2019.11.12: If you can edit the source AD object you can <a href="https://dloder.blogspot.com/2019/11/disconnecting-objects-with-aadconnect_12.html" target="_blank">leverage the default filtering rules to disconnect the object.</a><br />
<br /></div>
<div>
</div>
<div>
Fortunately, there's a round-about way, that clearly says it is for testing only, to disconnect an object in AADConnect.<br />
<br /></div>
<div>
</div>
<div>
<span style="background-color: red;">Note:</span> performing this procedure incorrectly can introduce incorrect data into AADConnect, which may require deleting all the connector space objects and running a Full Import and Full Sync to correct. Make sure you understand how this works before you make changes to a production system.<br />
<br /></div>
<div>
</div>
<div>
First, we need to save the connector space view of the object as we'll need it later. The syntax is csexport.exe ma_name filename.xml /f:d="DN" /o:b<br />
<br /></div>
<div>
</div>
As an example from my lab: <br />
<br />
<pre style="background-color: rgb(238 , 238 , 238); border: 1px dashed rgb(153 , 153 , 153); color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;">C:\Program Files\Microsoft Azure AD Sync\Bin>csexport.exe "logon.loderdom.com" c:\temp\contact001.xml /f:d="CN=Contact001,OU=userids,DC=logon,DC=loderdom,DC=com" /o:b
Microsoft Identity Integration Server Connector Space Export Utility v1.2.65.0
c 2015 Microsoft Corporation. All rights reserved
[1/1]
Successfully exported connector space to file 'c:\temp\contact001.xml'.
</pre>
<br />
Second, we delete the single object from the connector space. The syntax is csdelete.exe ConnectorName ObjectDN<br />
<br />
<div>
</div>
<div>
As an example from my lab:<br />
<br /></div>
<div>
</div>
<pre style="background-color: rgb(238 , 238 , 238); border: 1px dashed rgb(153 , 153 , 153); color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;">C:\Program Files\Microsoft Azure AD Sync\Bin>csdelete.exe "logon.loderdom.com" "CN=Contact001,OU=userids,DC=logon,DC=loderdom,DC=com"
</pre>
<div>
</div>
<br />
Next, we need some template data for how to structure the import. You can create the template yourself by creating a new delta import Run Profile. Use the Set Log File Options to select the Create a log file setting and provide a filename. Make a small change to an in-scope AD object, and run the new delta import step. This should cause an XML file to be created in the C:\Program Files\Microsoft Azure AD Sync\MaData\MAName folder. This log file is the basis for the template to import data. It should look something like this:
<br />
<br />
<pre style="background-color: rgb(238 , 238 , 238); border: 1px dashed rgb(153 , 153 , 153); color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;"><span style="background-color: yellow;"><?xml version="1.0" encoding="UTF-16"?></span>
<span style="background-color: yellow;"><mmsml xmlns="http://www.microsoft.com/mms/mmsml/v2" step-type="delta-import"></span>
<span style="background-color: yellow;"> <directory-entries></span>
<span style="background-color: yellow;"><delta operation="replace" </span><span style="background-color: lime;">dn="CN=Contact001,OU=userids,DC=logon,DC=loderdom,DC=com"></span>
<span style="background-color: lime;"> <anchor encoding="base64">NhtjCw4HbUuNLrUso4zsyw==</anchor></span>
<span style="background-color: lime;"> <parent-anchor encoding="base64">NH+Z2J4tEkuLRC42kBckew==</parent-anchor></span>
<span style="background-color: lime;"> <primary-objectclass>contact</primary-objectclass></span>
<span style="background-color: lime;"> <objectclass></span>
<span style="background-color: lime;"> <oc-value>top</oc-value></span>
<span style="background-color: lime;"> <oc-value>person</oc-value></span>
<span style="background-color: lime;"> <oc-value>organizationalPerson</oc-value></span>
<span style="background-color: lime;"> <oc-value>contact</oc-value></span>
<span style="background-color: lime;"> </objectclass></span>
<span style="background-color: lime;"> <attr name="cn" type="string" multivalued="false"></span>
<span style="background-color: lime;"> <value>Contact001</value></span>
<span style="background-color: lime;"> </attr></span>
<span style="background-color: lime;"> <attr name="displayName" type="string" multivalued="false"></span>
<span style="background-color: lime;"> <value>Contact001</value></span>
<span style="background-color: lime;"> </attr></span>
<span style="background-color: lime;"> <attr name="givenName" type="string" multivalued="false"></span>
<span style="background-color: lime;"> <value>Contact</value></span>
<span style="background-color: lime;"> </attr></span>
<span style="background-color: lime;"> <attr name="objectGUID" type="binary" multivalued="false"></span>
<span style="background-color: lime;"> <value encoding="base64">NhtjCw4HbUuNLrUso4zsyw==</value></span>
<span style="background-color: lime;"> </attr></span>
<span style="background-color: lime;"> <attr name="sn" type="string" multivalued="false"></span>
<span style="background-color: lime;"> <value>001</value></span>
<span style="background-color: lime;"> </attr></span>
<span style="background-color: yellow;"></delta></span>
<span style="background-color: yellow;"> </directory-entries></span>
<span style="background-color: yellow;"></mmsml></span>
<span style="background-color: yellow;">
</span></pre>
<div>
<span style="background-color: yellow;"></span><span style="background-color: yellow;"></span>
</div>
<div>
I've highlighted the template portion in yellow, and the replaceable object-specific content in green.
<br />
<br />
Take the XML data from the cs-objects/cs-object/synchronized-hologram/entry section of the export file from the first step of this procedure and use it to replace the data from the import template. Take care to make sure the XML is still structured properly. The DN is part of the entry element, with the other data being children.
<br />
<br />
The structure should be identical to the import template from above, just containing data from the object you exported.
<br />
<br />
When saving the template XML file with notepad, be sure to use Unicode, not ANSI. Copy the input file to the C:\Program Files\Microsoft Azure AD Sync\MaData\MAName folder.
<br />
<br />
Finally, we can import this object into the connector space. Edit the custom delta import Run Profile (or create a new one if you just used the XML from above). Use the Set Log File Options to select the Resume run from existing log file and stage to connector space (test only) setting and provide the filename.</div>
<div>
</div>
<div>
</div>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB3grzGoPwipviP6y8HP4Yd9J6jRVl7_iICL0S596XMzYRMwvXhtRyVkOJzCJZTN-Q3qfxu_nYND0_Z2w_-KHSPOvSXDOdiO_Ygzvqi0sM1Amb6z1C6aBOLzx0TdNaAhmFxkm3-4LiOH84/s1600-h/runprofile%255B5%255D"><img alt="runprofile" border="0" height="482" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJW6zcbephpZWIlgFoijY9Wfbr2BifIneQ60UDJehffGu6WZupk6hOcMltMO4AKX7VwUsxblmbcKJjA72xwyJNGF204n3lyVvRSztRvnnQWpwjtccnIQ8SKj1myaLGwsCvOCSVe85Gq-Sf/?imgmax=800" style="background-image: none; display: inline;" title="runprofile" width="656" /></a></div>
<div>
<br />
If you get a parsing error, validate that the XML structure matches the template example and that the file is encoded with Unicode.
<br />
<br /></div>
David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-57697562732682933722018-10-11T13:52:00.002-04:002020-04-03T10:45:12.491-04:00Compare AADConnect Pending Exports Between Active and Staging Servers<span style="background-color: transparent; color: black; display: inline; float: none; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13.33px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; word-wrap: break-word;">On </span><span style="background-color: transparent; color: black; display: inline; float: none; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13.33px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; overflow-wrap: break-word; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><strike>the TechNet Gallery</strike></span><span style="background-color: transparent; color: black; display: inline; float: none; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13.33px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; word-wrap: break-word;"> GitHub I posted a script for comparing the export queues between an active AADConnect server and a staging server so you can verify the staging server is not planning on exporting unexpected or unwanted data. The script helps remove unnecessary noise from the standard export CSV by making use of exports at two different points in time. This removes any transient data from the report so that only data present in the export queue both times we looked is in the final report.</span><br />
<br />
<a href="https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts/wiki/Compare-AADConnect-Pending-Exports-Between-Active-and-Staging-Servers" target="_blank">Compare AADConnect Pending Exports Between Active and Staging Servers</a><br />
<br />
Updated 2020.04.03 <span style="background-color: #f6f6f6; font-family: "Trebuchet MS", Trebuchet, Verdana, sans-serif; font-size: 13px;">moved link to the GitHub Repository</span>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-39919698492361342972017-09-19T09:06:00.001-04:002021-04-20T11:54:39.363-04:00AdminSDHolder in the news againThe Enterprise Mobility blog just published a post on <a href="https://techcommunity.microsoft.com/t5/security-compliance-identity/active-directory-access-control-list-8211-attacks-and-defense/ba-p/250315" target="_blank">Active Directory Access Control List â Attacks and Defense</a>.<br />
<br />
One of the concerns they call out is modifying AdminSDHolder, with a reference to Exchange.<br />
<br />
Long time readers might remember that I am the one that first brought this <a href="http://dloder.blogspot.com/2009/08/exchange-2010-rc1-and-adminsdholder.html" target="_blank">concern with a Release Candidate of Exchange</a> to the forefront.<br />
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-61806284003636156402017-09-19T08:57:00.000-04:002020-03-06T13:05:12.333-05:00Securing Privileged Access for the AD Admin â Part 2Cross Post from <a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/securing-privileged-access-for-the-ad-admin-part-2/ba-p/259167">https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/securing-privileged-access-for-the-ad-admin-part-2/ba-p/259167</a><br />
<br />
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Hello everyone, my name is still <a href="https://social.technet.microsoft.com/profile/david%20%20loder/"><span style="color: #0563c1;">David
Loder</span></a>, and Iâm still PFE out of Detroit, Michigan.<span style="margin: 0px;"> </span>Hopefully youâve read <a href="https://blogs.technet.microsoft.com/askpfeplat/2017/09/11/securing-privileged-access-for-the-ad-admin-part-1/"><span style="color: #0563c1;">Securing
Privileged Access for the AD Admin â Part 1</span></a>.<span style="margin: 0px;"> </span>If not, go ahead.<span style="margin: 0px;"> </span>Weâll wait for you.<span style="margin: 0px;"> </span>Now that youâve started implementing the
roadmap, and youâre reading this with your normal user account (which no longer
has Domain Admin rights), weâll continue the journey to a more secure
environment.<span style="margin: 0px;"> </span>Recall the overarching goal
is to create an environment that minimizes tier-0 and in doing so establishes a
clear tier-0 boundary.<span style="margin: 0px;"> </span>This requires
understanding the tier-0 equivalencies that currently exist in the environment
and either planning to keep them in tier-0 or move them out to a different tier.</span></div>
<br />
<h2 style="margin: 16px 0px 0px;">
Privileged Access Workstations (PAWs) for AD Admins</h2>
<br />
<div style="margin: 0px 0px 11px;">
Youâve (hopefully) gone through the small effort to have a
credential whose only purpose is to manage AD.
Letâs assume you now need to go do some actual administering. The only implementation that prevents
expansion of your tier-0 equivalencies would be to physically enter your data
center and directly log on to the console of a Domain Controller. But thatâs not very practical for any number
of obvious reasons and I think everyone would agree that an AD Admin being able
to perform their admin tasks remotely from a DC console is a huge productivity
gain. Therefore, you now need a
workstation.</div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Iâm going to guess that most of you use the one workstation
that was handed out by your IT department.<span style="margin: 0px;">
</span>That workstation which uses the same base image for every employee in
the organization.<span style="margin: 0px;"> </span>That workstation which
is designed to be managed by your IT department for ease of support.<span style="margin: 0px;"> </span>Yes, that workstation.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Recall last time we spent almost all our time talking about
tier-0 equivalencies.<span style="margin: 0px;"> </span>Guess what?<span style="margin: 0px;"> </span>Iâm going to sound like a broken record.<span style="margin: 0px;"> </span>Item #3 from our elevator speech in part one
stated â<span lang="EN" style="margin: 0px;">Anywhere that tier-0
credentials are used is a tier-0 system</span>.â What is the new system we just
added to tier-0?<span style="margin: 0px;"> </span>That workstation.<span style="margin: 0px;"> </span>Now, any process that has administrative
control over that workstation is a tier-0 equivalency.<span style="margin: 0px;"> </span>Consider patching, anti-virus, inventory and
event log consolidation.<span style="margin: 0px;"> </span>Is each of
those running as local system on your workstation and managed by a service
external to the laptop?<span style="margin: 0px;"> </span>Check, check,
check and check.<span style="margin: 0px;"> </span>Does it have Helpdesk
personnel as local admins? Check. Iâll ask again how big is your tier-0?</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">I hear some of you starting to argue âI donât actually log
on to my workstation with my AD admin credential, I use [X].â<span style="margin: 0px;"> </span>What if you use RunAs?<span style="margin: 0px;"> </span>That workstation is still a tier-0
system.<span style="margin: 0px;"> </span>What if you use it to RDP into a
jump-box?<span style="margin: 0px;"> </span>That workstation is still a tier-0
system.<span style="margin: 0px;"> </span>What if you have smartcard
logons?<span style="margin: 0px;"> </span>Still a tier-0 system.<span style="margin: 0px;"> </span>Some of the <a href="https://technet.microsoft.com/en-us/windows-server-docs/security/securing-privileged-access/securing-privileged-access-reference-material#ATLT_BM"><span style="color: #0563c1;">supplemental
material</span></a> goes into the details of the various logon types, but the simple
concept is âsecure the keyboard.â<span style="margin: 0px;">
</span>Whatever keyboard youâre using to perform tier-0 administration is a
tier-0 system.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Now that weâve established that your workstation really is a
tier-0 system, letâs treat it as such.<span style="margin: 0px;">
</span>Start acting like your workstation is a portable Domain Controller.<span style="margin: 0px;"> </span>Think of all those plans, procedures and
systems you have in place to manage the DCs.<span style="margin: 0px;">
</span>You need to start using them to manage your workstation.<span style="margin: 0px;"> </span>My fellow PFE Jerry Devore has <a href="https://blogs.technet.microsoft.com/askpfeplat/2016/03/14/secure-administrative-workstations/"><span style="color: #0563c1;">an
in-depth look at creating a PAW</span></a> to be your admin workstation.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Should your PAW be a separate piece of hardware?<span style="margin: 0px;"> </span>Preferably, yes.<span style="margin: 0px;"> </span>That way it is only online when it needs to be
used, helping to reduce the expansion of tier-0 to the minimum necessary.<span style="margin: 0px;"> </span>If your organization canât afford separate
hardware you can virtualize on one piece of hardware.<span style="margin: 0px;"> </span>But the virtualization needs to occur in the
opposite direction than you might ordinarily expect.<span style="margin: 0px;"> </span>The PAW image will still need to run as the
host image, and your corporate desktop would be virtualized inside.<span style="margin: 0px;"> </span>This keeps any compromise of your
unprivileged desktop from elevating access into your PAW.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">This is another big step/small step decision.<span style="margin: 0px;"> </span>PAWs will be a change for your
organization.<span style="margin: 0px;"> </span>If you can start small by
implementing it for a few AD Admins, you can show your enterprise that using
PAWs can be a sustainable model.<span style="margin: 0px;"> </span>At
later phases in the roadmap you can expand PAWs to more users.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">With a PAW in place you now have a tier-0 workstation for
your tier-0 credential to manage your tier-0 asset.<span style="margin: 0px;"> </span>Congratulations, by implementing the first
two steps down the SPA roadmap, you now have the beginnings of a true tier-0
boundary.</span></div>
<br />
<h2 style="margin: 16px 0px 0px;">
Unique Local Admin Passwords for Workstations</h2>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">So far, weâve been talking about protecting your personal AD
Admin accounts.<span style="margin: 0px;"> </span>But everyone knows AD
has its own built-in Administrator account that is shared across all DCs.<span style="margin: 0px;"> </span>Ensure you have some process in place to
manage that specific âbreak in case of fireâ account.<span style="margin: 0px;"> </span>Maybe two Domain Admins each manage half of
the password, and those halves are securely stored.<span style="margin: 0px;"> </span>The point is: have a procedure for managing
this one account.<span style="margin: 0px;"> </span>Be careful if you
decide to implement an external system to manage that password.<span style="margin: 0px;"> </span>Do you want that external system to become
tier-0 just to manage one AD Admin account?<span style="margin: 0px;">
</span>I canât answer that question for you, but I can point out that it is a
tier-0 boundary decision.<span style="margin: 0px;"> </span>Your new PAWs,
on the other hand, will have one built-in Administrator account per PAW.<span style="margin: 0px;"> </span>How do we practically secure those multiple
Administrator accounts without increasing the size of tier-0?</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">The answer is to implement Microsoftâs <a href="http://aka.ms/LAPS"><span style="color: #0563c1;">Local Administrator Password Solution (LAPS)</span></a>.<span style="margin: 0px;"> </span>Simply put, LAPS is a new Group Policy Client
Side Extension (CSE), available for you to deploy at no additional cost.<span style="margin: 0px;"> </span>It will automatically randomize the local
Administrator account on your tier-0 PAWs on an ongoing basis, store that
password in AD and allow you to securely manage its release to authorized
personnel (which should only be the tier-0 admins).<span style="margin: 0px;"> </span>Since the PAW and AD are both already tier-0
systems, using one to manage the other does not increase the size of tier-0.<span style="margin: 0px;"> </span>That fits our goal of minimizing the size of
tier-0.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">These new PAWs that you just introduced into the environment
also become the perfect place to begin a pilot deployment of LAPS.<span style="margin: 0px;"> </span>Install the CSE on the PAWs, create a
separate OU to hold the PAW computer objects, create the LAPS GPO and link it
to the PAW OU.<span style="margin: 0px;"> </span>Youâll never have to
worry about the local admin password on your PAW again.<span style="margin: 0px;"> </span>As another big step/small step decision,
using LAPS to manage the new PAWs should be an easier step than starting out
using LAPS for all your workstations.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If youâre interested in how LAPS allows us to help combat
Pass the Hash attacks, here are a few <a href="https://channel9.msdn.com/Blogs/Taste-of-Premier/Taste-of-Premier-How-to-Mitigate-Pass-the-Hash-and-Other-Forms-of-Credential-Theft"><span style="color: #0563c1;">additional</span></a>
<a href="https://technet.microsoft.com/en-us/dn785092.aspx"><span style="color: #0563c1;">resources</span></a> you
can review.</span></div>
<br />
<h2 style="margin: 16px 0px 0px;">
Unique Local Admin Password for Servers</h2>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Building on your previous work of where you want your tier-0
boundary to be, start running LAPS on those member servers that are going to
remain part of tier-0.<span style="margin: 0px;"> </span>Again, a smaller
step than LAPS everywhere, and not much else to say on the subject.<span style="margin: 0px;"> </span>By this point you should be familiar with
LAPS and are just expanding its usage.</span></div>
<br />
<h2 style="margin: 16px 0px 0px;">
End of the Stage 1 and the Roads Ahead</h2>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If you expand LAPS to cover all workstations and all servers,
congratulations, you have now followed the <a href="http://aka.ms/SPARoadmap"><span style="color: #0563c1;">roadmap</span></a>
to the end of Stage 1.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";"><a href="http://aka.ms/SPARoadmap"><span style="color: #0563c1;">Stage 2 and Stage 3 of
the roadmap</span></a> involves expanding the use of the PAWs to all administrators,
implementing advanced credential management that begins to move you away from
password-only credentials, minimizing the amount of standing, always-on, admin
access, implementing the tier-0 boundary you already decided upon, and
increasing your ability to detect attacks against AD.<span style="margin: 0px;"> </span>You can also start looking at implementing
Windows Server 2016 and taking advantage of some of our newest security
features.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">In these stages, weâre looking at implementing new
capabilities that defend against more persistent attackers.<span style="margin: 0px;"> </span>As such, these will take longer to implement
than Stage 1.<span style="margin: 0px;"> </span>But if youâve already
gotten people familiar with the tiering model and talking about your tier-0
boundary youâll have an easier time implementing this guidance, with less
resistance, as all the implementations are aligned to the singular goal of
minimizing your tier-0 surface area.</span></div>
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.1. PAW Phases 2 and 3: all
admins and additional hardening</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Get a PAW into the hands of
everyone with admin rights to separate their Internet-using personal
productivity end user account from their admin credentials.<span style="margin: 0px;"> </span>Even if theyâre still crossing tiers at this point
in time, there is now some separation from the most common compromise channel.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.2. Time-bound privileges (no
permanent administrators)</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">If an account has no admin
rights, is it still an admin credential?<span style="margin: 0px;">
</span>The least vulnerable administrators are those with admin access to
nothing.<span style="margin: 0px;"> </span>We provide tooling in current
versions of both AD and Microsoft Identity Manager to deliver this functionality.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.3. Multi-factor for
time-bound elevation</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Passwords are no longer a
sufficient authentication mechanism for administrative access.<span style="margin: 0px;"> </span>Having to breach a secondary channel significantly
increases the attackersâ costs.</span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Also have a look at some of our
current </span><a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/06/Microsoft_Password_Guidance-1.pdf"><span lang="EN" style="font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"><span style="color: #0563c1;">password guidance</span></span></a><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.4. Just Enough Admin (JEA)
for DC Maintenance</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Allowing junior or delegated Admins
to perform approved tasks, instead of having to make them full admins, further
reduces the tier-0 surface area.<span style="margin: 0px;"> </span>You can
even consider delegating access to yourself for common actions you perform all
the time, fully eliminating work tasks that require the use of a tier-0
credential.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.5. Lower attack surface of
Domain and DCs</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">This is where all the up-front
work of understanding and defining your tier boundaries pays off in
spades.<span style="margin: 0px;"> </span>When you reach this step, no one
should be surprised about what you intend to do.<span style="margin: 0px;"> </span>If youâve decided to keep tier-0 small and
are isolating the security infrastructure management from the general
Enterprise management, everyone has already agreed to that.<span style="margin: 0px;"> </span>If youâve decided that you must keep some of
those systems as tier-0, youâve hardened them like they are DCs and have
elevated the maturity of those admins to treat their credentials like the
tier-0 assets they are.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">2.6. Attack Detection</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Seeing </span><a href="https://www.microsoft.com/ata"><span lang="EN" style="font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"><span style="color: #0563c1;">Advanced
Threat Analytics (ATA)</span></span></a><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"> in action, and providing visibility into exactly what your DCs are doing,
will likely be an eye-opening revelation for most environments.<span style="margin: 0px;"> </span>Consider this your purpose-built Identity
SIEM instead of simply being a dumping ground for events in general.</span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">And, while not officially on
the roadmap at this time, if you have SCOM, take a look at the great work some
of our engineers have put into the </span><a href="https://blogs.technet.microsoft.com/nathangau/2017/05/01/introducing-the-security-monitoring-management-pack-for-scom/"><span lang="EN" style="font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"><span style="color: #0563c1;">Security Monitoring Management Pack</span></span></a><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">3.1. Modernize Roles and
Delegation Model</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">This goes together with
lowering the attack surface of the Domain and DCs.<span style="margin: 0px;"> </span>You canât accomplish that reduction without
providing alternate roles and delegations that donât require tier-0
credentials.<span style="margin: 0px;"> </span>You should be trying to
scope tier-0 AD admin activity to actions like patching the OS and promoting
new DCs.<span style="margin: 0px;"> </span>If someone isnât performing a
task along those lines, they likely are not tier-0 admins and should instead be
delegated rights to perform the activity and not be Domain Admin.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">3.2. Smartcard or Passport
Authentication for all admins</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">More of the same advice that
you need to start eliminating passwords from your admins.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">3.3. Admin Forest for Active
Directory administrators</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Iâm sure your AD environment is
perfectly managed.<span style="margin: 0px;"> </span>All the legacy
protocols have been disabled, you have control over every account (human or
service) that has admin rights on any DC.<span style="margin: 0px;">
</span>In essence, youâve already been doing everything is the roadmap.</span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">No?</span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Your environment doesnât look
like that?</span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Sometimes itâs easier to admit
that itâs going to be too difficult to regain administrative control over the
current Enterprise forest.<span style="margin: 0px;"> </span>Instead, you
can implement a new, pristine environment right out of the box and shift your
administrative control to this forest.<span style="margin: 0px;">
</span>Your current Enterprise forest is left mostly alone due to all the
app-compat concerns that go along with everything thatâs been tied to AD. <span style="margin: 0px;"> </span>We have lots of guidance and implementation
services to help make sure you build this new forest right and ensure itâs only
used for administration purposes.<span style="margin: 0px;"> </span>That
way you can turn on all the new security features to protect your admins without
fear of breaking the old app running in some forgotten closet.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">3.4. Code Integrity Policy for
DCs (Server 2016)</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">Your DCs should be your most
controlled, purpose-built servers in your environment.<span style="margin: 0px;"> </span>Creating a policy that locks them down to
exactly what you intended helps keep tier-0 from expanding as your DCs canât
just start running new code that isnât already part of their manifest.</span><br />
<br />
<br />
<br />
<strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">3.5. Shielded VMs for virtual
DCs (Server 2016 Hyper-V Fabric)</span></strong><span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;"></span><br />
<br />
<span lang="EN" style="color: #333333; font-family: "calibri" , sans-serif; font-size: 11pt; margin: 0px;">I remember the first time I saw
a VM POST and realized what a game-changer virtualization was going to be.<span style="margin: 0px;"> </span>Unfortunately, it also made walking out the
door with a fully running DC as easy as copy/paste.<span style="margin: 0px;"> </span>With Shielded VMs you can now enforce
boundaries between your Virtualization Admins and your AD Admins.<span style="margin: 0px;"> </span>You can allow your virtualization services to
operate at tier-1 while being able to security host tier-0 assets without
violating the integrity of the tier boundary.<span style="margin: 0px;">
</span>Can you say âGame changerâ?</span><br />
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<h2 style="margin: 16px 0px 0px;">
Donât Neglect the Other Tiers</h2>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">While this series focused on tier-0, the methodology of
tackling the problem extends to the other tiers as well.<span style="margin: 0px;"> </span>This exercise was fundamentally about
segmentation of administrative control.<span style="margin: 0px;">
</span>What weâve seen, is that over the years, unintentional administrative
control gets granted and then becomes an avenue for attack.<span style="margin: 0px;"> </span>Be especially on the lookout for service accounts
that are local admin on lots of systems and understand how those credentials
are used and if they are present on those endpoints in a manner that allows
them to be <a href="https://docs.microsoft.com/en-us/windows-server/identity/securing-privileged-access/securing-privileged-access-reference-material#ATLT_BM"><span style="color: #0563c1;">reused
for lateral movement</span></a>.<span style="margin: 0px;"> </span>If youâve gone
through the effort to secure tier-0 but you have vulnerable credentials with
standing admin access to all of tier-1, where your business-critical data is
stored, you probably havenât moved the needle as much as you need to.<span style="margin: 0px;"> </span>Ideally you get to the point where the compromise
of a single workstation or a single server is contained to that system and
doesnât escalate into a compromise of most of the environment.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">I know this has been a lot of guidance over these two posts.<span style="margin: 0px;"> </span>Even if you canât do everything, I know you
can do something to improve your environment.<span style="margin: 0px;">
</span>Hopefully I provided some new insight into how you can make your
environment more secure than it is currently and exposed you to the volumes of
guidance in the <a href="http://aka.ms/sparoadmap"><span style="color: #0563c1;">SPA roadmap</span></a>.<span style="margin: 0px;"> </span>Now get out there and start figuring out
where your tier-0 boundary is and where you want it to be!</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Thanks for spending a little bit of your time with me.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">-Dave</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">#proudmicrosoftemployee</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><span style="font-family: "calibri";"></span>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com3tag:blogger.com,1999:blog-4018181297398983593.post-91838857621619634362017-09-12T08:13:00.000-04:002020-03-06T13:04:55.406-05:00Securing Privileged Access for the AD Admin â Part 1Cross Post from <a href="https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/securing-privileged-access-for-the-ad-admin-part-1/ba-p/259166">https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/securing-privileged-access-for-the-ad-admin-part-1/ba-p/259166</a><br />
<br />
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Hello again, my name is still <a href="https://social.technet.microsoft.com/profile/david%20%20loder/"><span style="color: #0563c1;">David
Loder</span></a>, and Iâm still a PFE out of Detroit, Michigan. <span style="margin: 0px;"> </span>I have a new confession to make.<span style="margin: 0px;"> </span>I like cat videos.<span style="margin: 0px;"> </span>Your end users like cat videos.<span style="margin: 0px;"> </span>You may like cat videos yourself.<span style="margin: 0px;"> </span>Microsoft will even <a href="https://www.bing.com/videos/search?q=cat%20videos"><span style="color: #0563c1;">help you find cat
videos</span></a>.<span style="margin: 0px;"> </span>Unfortunately, cat videos
may have it out for you and your environment.<span style="margin: 0px;">
</span>How do you keep your environment secure when malicious cat videos are
out there, waiting to pounce?</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Microsoft has a significant amount of published guidance
around <a href="http://aka.ms/privsec"><span style="color: #0563c1;">Securing Privileged Access</span></a> (SPA), <a href="http://aka.ms/cyberpaw"><span style="color: #0563c1;">Privileged Access Workstations</span></a> and the <a href="http://aka.ms/tiermodel"><span style="color: #0563c1;">Administrative Tier Model</span></a>.<span style="margin: 0px;"> </span>My fellow PFEs have also contributed their
own great thoughts around these topics.<span style="margin: 0px;">
</span>Go browse through our <a href="https://blogs.technet.microsoft.com/askpfeplat/tag/security"><span style="color: #0563c1;">Security
tagged posts</span></a> to get easy access to them.<span style="margin: 0px;">
</span>As for myself, I was staff IT in the security department for a large,
global corporation, prior to joining Microsoft, where we operated in a tiered
administrative model and had implemented many, though not all, of the defenses
highlighted in the SPA roadmap.<span style="margin: 0px;"> </span>So Iâd
like to share my perspective on the items in the roadmap and the practical
implications from an Active Directory Administrator point of view.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">But first a caveat for this series of articles.<span style="margin: 0px;"> </span>I love the SPA roadmap.<span style="margin: 0px;"> </span>I espouse its virtues to all my customers and
anyone else who will listen.<span style="margin: 0px;"> </span>But there
are times where the SPA roadmap takes a big step, and I know it can sometimes
be difficult to get the people in charge to agree to a big step.<span style="margin: 0px;"> </span>In all the cases where I point this out it is
possible to take a smaller step by limiting the scope by focusing solely on
AD.<span style="margin: 0px;"> </span>I have a different purpose for this
series of articles than the SPA roadmap itself.<span style="margin: 0px;">
</span>I want you to actually implement the guidance.<span style="margin: 0px;"> </span>Thatâs a shocking statement, I know.<span style="margin: 0px;"> </span>Despite all the guidance, I still walk into
environments that havenât implemented a single piece of this guidance.<span style="margin: 0px;"> </span>Maybe they donât know this guidance
exists.<span style="margin: 0px;"> </span>Maybe they think they arenât a
target.<span style="margin: 0px;"> </span>Maybe they think the guidance
doesnât apply to them.<span style="margin: 0px;"> </span>My hope with this
series is that a few more people know about the guidance, understand why they
should care and have an easier time convincing others in their organization
that the roadmap guidance should be implemented.<span style="margin: 0px;"> </span>Security is a journey.<span style="margin: 0px;"> </span>Through no fault of your own, the rules have
changed.<span style="margin: 0px;"> </span>What you did to secure your
environment yesterday is no longer sufficient for todayâs reality.<span style="margin: 0px;"> </span>So, letâs get started.</span></div>
<div style="margin: 0px 0px 11px;">
<br /></div>
<h2 style="margin: 0px 0px 11px;">
Separate Admin Account for Admin Tasks</h2>
<div style="margin: 0px 0px 11px;">
<br /></div>
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">T<span style="font-family: "calibri";">his is an easy one, right?<span style="margin: 0px;">
</span>Nothing about this guidance is new.<span style="margin: 0px;">
</span>It ranks right up there with not browsing the Internet from a
server.<span style="margin: 0px;"> </span>But I am constantly seeing environments
where normal user accounts, which have a mailbox and browse the Internet for
cat videos, are also in the Domain Admins group.<span style="margin: 0px;"> </span>Stop this.<span style="margin: 0px;">
</span>Stop this now.<span style="margin: 0px;"> </span>You need a
separate credential for administrative tasks.<span style="margin: 0px;">
</span>Come up with a naming convention and a process to get an admin account
for anyone who does admin work.</span></span></div>
<span style="font-family: "calibri";"></span><br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">I know some of you are smiling and thinking to yourself âof
course we do this; the admins get their ADM_username accounts for performing
admin workâ (or their $username or their username.admin or whatever convention
you use).<span style="margin: 0px;"> </span>But, have you made the
correlation between <a href="http://aka.ms/tiermodel"><span style="color: #0563c1;">tiering</span></a> and admin
accounts?<span style="margin: 0px;"> </span>To fully implement the
guidance, a user with admin rights must have a <b style="mso-bidi-font-weight: normal;">separate admin account per tier</b>!</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Let that sink in for a minute. In a three-tier model, the AD
Admins may require four separate credentials: user (non-privileged), tier-2
(workstation) admin, tier-1 (server) admin and tier-0 (security infrastructure)
admin. This guidance is designed to avoid having a credential that has admin
rights in multiple tiers. This helps prevent a <a href="https://blogs.technet.microsoft.com/askpfeplat/tag/pass-the-hash"><span style="color: #0563c1;">pass-the-hash</span></a>
attack from elevating from a lower tier to a higher tier.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Now for the practical part.<span style="margin: 0px;">
</span>Yes, this gets hard to do.<span style="margin: 0px;"> </span>You
may have processes in place that will get a second credential to admin users,
but it wasnât designed to get them four.<span style="margin: 0px;">
</span>Maybe you have clear separation between server admins and workstation
admins, so no one will need all four.<span style="margin: 0px;"> </span>We
want the guidance to be actionable and most importantly to protect tier-0.<span style="margin: 0px;"> </span>Guidance that isnât followed because it is
too burdensome isnât valuable. At a minimum, your AD Admins should have three
accounts: user, admin, tier-0 admin.<span style="margin: 0px;"> </span>And
your goal is to minimize the scope of tier-0.<span style="margin: 0px;">
</span>Tier-0 admin accounts should only be managed by other tier-0 admin
accounts and not by a tier-1 system.<span style="margin: 0px;">
</span>Please donât have your normal <span lang="EN" style="margin: 0px;">Identity Management (IdM) system try to manage AD Admin accounts.<span style="margin: 0px;"> </span>Because youâll either fight with </span><a href="http://www.bing.com/search?q=adminsdholder"><span lang="EN" style="margin: 0px;"><span style="color: #0563c1;">AdminSDHolder</span></span></a><span lang="EN" style="margin: 0px;"> or youâll have to grant your IdM system Domain
Admin rights and neither of those is a good choice.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Letâs discuss the tiers for a moment.<span style="margin: 0px;"> </span>What does tier-0 really mean?<span style="margin: 0px;"> </span>The definition from the <a href="http://aka.ms/tiermodel"><span style="color: #0563c1;">Administrative Tier Model</span></a> is:</span></div>
<br />
<div style="margin: 0px 0px 11px 48px;">
<strong><span lang="EN" style="font-family: "calibri" , sans-serif; margin: 0px;">Tier 0</span></strong><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";"> â Direct Control of enterprise identities
in the environment. Tier 0 includes accounts, groups, and other assets that
have direct or indirect administrative control of the Active Directory forest,
domains, or domain controllers, and all the assets in it. The security
sensitivity of all tier 0 assets is equivalent as they are all effectively in
control of each other.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Control of a
tier-0 system means control of the entire environment.<span style="margin: 0px;"> </span>The very nature of Active Directory means
there should be at least two tiers in the environment: AD itself, and
everything else.<span style="margin: 0px;"> </span>Splitting between tiers
isnât a hard and fast line.<span style="margin: 0px;"> </span>The tiering
is there to provide a security boundary that is supposed to be difficult to
cross.<span style="margin: 0px;"> </span>You can certainly have user
workstations that might need to be treated more like a tier-1 system because of
the value they hold.<span style="margin: 0px;"> </span>The point is that
your organization must decide which security boundaries should exist that
define the tiers and the systems contained within those tiers.<span style="margin: 0px;"> </span>This is especially true of tier-0.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">At a minimum
tier-0 will contain Active Directory; specifically, the writeable Domain
Controllers and the AD Admin credentials.<span style="margin: 0px;">
</span>Those credentials are any account that is a member of Domain Admins,
Enterprise Admins, Builtin Administrators, etc.<span style="margin: 0px;">
</span>These groups are all equivalent.<span style="margin: 0px;">
</span>Donât think being Builtin Administrator is somehow more secure or
different than being Domain Admin.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">What else is tier-0? Look in your AD Admin groups.<span style="margin: 0px;"> </span>Every account in them is a tier-0
credential.<span style="margin: 0px;"> </span>Ideally, they are
credentials only for people and they are unique to the management of AD
infrastructure, following a naming convention that distinguishes them from your
normal tier-1 admin accounts.<span style="margin: 0px;"> </span>In other
words, the tier-0 credentials that are members of the AD Admin groups must be
used for the sole purpose of managing AD infrastructure and for nothing else.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If you have service accounts in your AD Admin groups, those
service accounts are tier-0 credentials.<span style="margin: 0px;">
</span>The servers where those service accounts are used are tier-0
systems.<span style="margin: 0px;"> </span>Anyone who is administrator on
those servers has access to tier-0 credentials.<span style="margin: 0px;">
</span>Do you see how quickly this grows?<span style="margin: 0px;">
</span>While you may normally think of just AD as being tier-0, your <a href="https://technet.microsoft.com/en-US/library/mt631193.aspx#T0E_BM"><span style="color: #0563c1;">tier-0
equivalency</span></a> may be immense.<span style="margin: 0px;"> </span>In fact,
you may not have a tier-1 or tier-2 layer at all.<span style="margin: 0px;"> </span>It is possible that you are operating an
environment where everything is tier-0.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">I will state again; the goal is to minimize tier-0.<span style="margin: 0px;"> </span>Your AD Admin groups should only have people
in them, not service accounts.<span style="margin: 0px;"> </span>Use the
delegation abilities within AD to grant those service accounts only the rights
they need.<span style="margin: 0px;"> </span>Yes, it may be hard work to
figure out what and where those rights are needed, but itâs the job that needs
to be done to keep things that should be tier-1 from being tier-0.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">What else is tier-0? Are your DCs virtualized? If so your VM
admins are tier-0 admins.<span style="margin: 0px;"> </span>Your VM
platform is a tier-0 system. Your VM storage is a tier-0 system. Your storage
admins are tier-0 admins. Do you see how quickly this grows? Hyper-V in Windows
Server 2016 offers <a href="https://blogs.technet.microsoft.com/datacentersecurity/2016/03/14/windows-server-2016-shielded-vms-protecting-tenant-secrets"><span style="color: #0563c1;">Shielded
VMs</span></a> to mitigate this risk.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">What else is tier-0? What additional services run on your
DCs? Which of those services are listening on the network and running as Local
System? Which of them report into some kind of management console to receive
instructions on what to do? Does that describe your SIEM agent, your anti-virus
agent, your asset management agent, your configuration management agent? Your SIEM
team has control over a tier-0 system.<span style="margin: 0px;"> </span>Your
SIEM is a tier-0 system.<span style="margin: 0px;"> </span>Your AV
platform is a tier-0 system. Your configuration platform is a tier-0 system. Do
you have a standard corporate image that you use for all servers, including the
servers that you will promote to become Domain Controllers? Everything added to
that image has the possibility of being a tier-0 system. Do you see how quickly
this grows?</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">What else is
tier-0?<span style="margin: 0px;"> </span>Is your IdM system tier-0?
Maybe. By our definition it should be since it has direct control of the
enterprise identities.<span style="margin: 0px;"> </span>What if it is
only delegated rights to a specific set of OUs and it doesnât use an AD Admin
account to manage the users?<span style="margin: 0px;"> </span>If that
system is compromised is tier-0 compromised?<span style="margin: 0px;">
</span>The integrity of the AD infrastructure is still intact.<span style="margin: 0px;"> </span>It may no longer contain the user data you
wanted it to contain but you still have administrative control over AD and can more
easily recover.<span style="margin: 0px;"> </span>It that a bad day? Absolutely.
But you can still point to a security boundary that wasnât crossed.<span style="margin: 0px;"> </span>A defense in-depth mindset would have more
boundaries to cross when possible.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Control over your tier-0 equivalencies is likely the hardest
part of the roadmap; which is why it practically shows up later in the
roadmap.<span style="margin: 0px;"> </span>But I wanted to discuss it up
front, as understanding the true nature of your own tier-0 definition is
paramount to being able to have successfully implemented the roadmap at the end
of the journey.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Now that we all
understand the impact of tier-0 equivalencies, how many credentials in your
enterprise (from both humans and service accounts) are tier-0 admins?<span style="margin: 0px;"> </span>Is it 5 or 100?<span style="margin: 0px;"> </span>How many do you want at that tier?<span style="margin: 0px;"> </span>5 or 100?<span style="margin: 0px;">
</span>Personally, Iâd vote for 5.<span style="margin: 0px;"> </span>Keep
in mind that weâre focusing on credentials.<span style="margin: 0px;">
</span>This shouldnât be a discussion that we trust, for example, the VM Admin
team less than the AD one.<span style="margin: 0px;"> </span>Itâs that the
more credentials and systems that exist at tier-0, the more surface area we
have to consider in an assumed-compromised state.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">As a personal
story from my previous life many years ago, the first time we had to integrate
a non-AD workload into tier-0, we thought the sky was falling and it was the
destruction of our security posture because a different team was suddenly
involved.<span style="margin: 0px;"> </span>It took me a while to
recognize that tier-0 doesnât exclusively mean AD.<span style="margin: 0px;"> </span>Every organization will have a unique
combination of workloads and roles that will be their tier-0, and thatâs
OK.<span style="margin: 0px;"> </span>Whatâs important is define the
boundary then make every workload and every person in tier-0 operate to the
same standard.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Once you and your
organization have made your decision about defining your intended tier-0
boundary, go make totally separate admin accounts for those that you want to
end up operating at tier-0.<span style="margin: 0px;"> </span>Yes,
managing three or four credentials is more difficult than one.<span style="margin: 0px;"> </span>But youâre the AD admin for your enterprise
and if you arenât taking the lead in enabling this change, <b style="mso-bidi-font-weight: normal;">no one else will do so</b>.<span style="margin: 0px;"> </span>If
you already have a separate admin account, but itâs crossing tier boundaries
(existing or planned), go get your third credential.<span style="margin: 0px;"> </span>Making use of the third is almost no
additional effort beyond a second credential.<span style="margin: 0px;">
</span>Hereâs where you have one of those big step/small step decisions to
make.<span style="margin: 0px;"> </span>If having separate admin accounts
for everyone who does administration in your organization is too big of a
change to make all at once, start small with only those admins who manage
AD.<span style="margin: 0px;"> </span>Show everyone that the world doesnât
end if you have to manage separate credentials for AD Admin purposes.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Ensure you have
proper procedures for creating and managing the new tier-0 admin
credentials.<span style="margin: 0px;"> </span>My first preference is to
manage them manually, outside of the scope of any IdM platform you have in
place, with proper, proactive scheduled reviews. Hopefully youâve caught on to
the hints that managing tier-0 will be easier when itâs small.<span style="margin: 0px;"> </span>That allows manual management of tier-0
credentials to be successful.<span style="margin: 0px;"> </span>If youâre
in a more mature organization, then you can look to a dedicated tier-0 IdM
system that can manage these credentials.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">To summarize this
post into a 30 second elevator speech: </span></span></div>
<br />
<div style="margin: 0px 0px 0px 48px; text-indent: -0.25in;">
<span lang="EN" style="margin: 0px;"><span style="margin: 0px;"><span style="font-family: "calibri";">1.</span><span style="font-size-adjust: none; font-stretch: normal; font: 7pt "Times New Roman"; margin: 0px;">
</span></span></span><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Active
Directory Domain Controllers are tier-0 systems.</span></span></div>
<br />
<div style="margin: 0px 0px 0px 48px; text-indent: -0.25in;">
<span lang="EN" style="margin: 0px;"><span style="margin: 0px;"><span style="font-family: "calibri";">2.</span><span style="font-size-adjust: none; font-stretch: normal; font: 7pt "Times New Roman"; margin: 0px;">
</span></span></span><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">AD
Admin credentials are a tier-0 credentials.</span></span></div>
<br />
<div style="margin: 0px 0px 0px 48px; text-indent: -0.25in;">
<span lang="EN" style="margin: 0px;"><span style="margin: 0px;"><span style="font-family: "calibri";">3.</span><span style="font-size-adjust: none; font-stretch: normal; font: 7pt "Times New Roman"; margin: 0px;">
</span></span></span><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Anywhere
that tier-0 credentials are used is a tier-0 system.</span></span></div>
<br />
<div style="margin: 0px 0px 0px 48px; text-indent: -0.25in;">
<span lang="EN" style="margin: 0px;"><span style="margin: 0px;"><span style="font-family: "calibri";">4.</span><span style="font-size-adjust: none; font-stretch: normal; font: 7pt "Times New Roman"; margin: 0px;">
</span></span></span><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Anything
or anyone that has administrative control over any part of 1, 2 or 3 is also a
tier-0 credential/system.</span></span></div>
<br />
<div style="margin: 0px 0px 11px 48px; text-indent: -0.25in;">
<span lang="EN" style="margin: 0px;"><span style="margin: 0px;"><span style="font-family: "calibri";">5.</span><span style="font-size-adjust: none; font-stretch: normal; font: 7pt "Times New Roman"; margin: 0px;">
</span></span></span><span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Keeping
1, 2, 3 and 4 small makes tier-0 easier to manage and more secure.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span lang="EN" style="margin: 0px;"><span style="font-family: "calibri";">Thatâs it for
now.<span style="margin: 0px;"> </span>The first step down the roadmap is
both incredibly simple and incredibly hard at the same time.<span style="margin: 0px;"> </span>I want to give you a break to allow the full
impact of the guidance to soak in.<span style="margin: 0px;"> </span>Check
back in next week, where weâll continue our discussion of the roadmap.<span style="margin: 0px;"> </span>But please, go create your separate AD Admin
account right now.<span style="margin: 0px;"> </span>I shudder to think
youâve been reading this with a browser running under AD Admin credentials, with
your cat videos playing in another tab.</span></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">-Dave</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">#proudmicrosoftemployee</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><span style="font-family: "calibri";"></span>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-81506387071410434452017-09-01T13:36:00.000-04:002020-04-03T10:43:40.935-04:00Reformat AADConnect Sync Rule Export for Easy Comparisons with PowerShellOn <strike>the TechNet Gallery</strike> GitHub I posted a script for reformatting the AADConnect Synchronization Rule Export file. WinDiff has a hard time showing the differences between two export files due to the similarity of the structure and the lack of rule sorting within the file. This script exports each rule into a separate file to allow one to perform a folder comparison.<br />
<br />
<a href="https://github.com/dloder0/AAD-Connect-MIM-FIM-Scripts/wiki/Reformat-AADConnect-Sync-Rule-Export-for-Easy-Comparisons" target="_blank">Reformat AADConnect Sync Rule Export for Easy Comparisons</a><br />
<br />
Updated 2020.04.03, moved link to the GitHub RepositoryDavid Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-91458681047255959352017-01-03T16:30:00.000-05:002017-01-03T17:00:26.690-05:00Remote Server Administration Tools for Windows 10<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Cross Post from <a href="https://blogs.technet.microsoft.com/askpfeplat/2017/01/03/remote-server-administration-tools-for-windows-10/" target="_blank">https://blogs.technet.microsoft.com/askpfeplat/2017/01/03/remote-server-administration-tools-for-windows-10/</a></span><br />
<span style="font-family: Calibri;"><br /></span>
<span style="font-family: "calibri";">Hello everyone, my name is </span><a href="https://social.technet.microsoft.com/profile/david%20%20loder/"><span style="color: #0563c1; font-family: "calibri";">David
Loder</span></a><span style="font-family: "calibri";">, long-time reader, first-time PFE blogger, based out of Detroit,
Michigan.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">And I have a confession to
make.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">I hate servers.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Or more precisely I hate logging in to
servers.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If youâve been administering Windows Server for any length
of time, youâre hopefully aware of the Remote Server Administration Tools
(RSAT) package.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">RSAT provides the server
management tools for the Windows client Operating Systems like Windows 7 or
Windows 10 so that you donât have to RDP into a Domain Controller just to run
the Active Directory Users and Computers GUI.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">The RSAT package is OS specific.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">There is a different package for each client
OS that corresponds to the matching server OS.</span><span style="margin: 0px;"><span style="font-family: "calibri";">
</span></span><span style="font-family: "calibri";">There are links to each of the packages from the main RSAT Knowledge
Base article at </span><a href="https://support.microsoft.com/en-us/kb/2693643"><span style="color: #0563c1; font-family: "calibri";">https://support.microsoft.com/en-us/kb/2693643</span></a><span style="font-family: "calibri";">.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If you are a typical enterprise customer youâve most likely
been running Windows 7 as your client, and are just now starting to explore
Windows 10.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Because of the OS specifics, RSAT for Windows 10 is tied to
Windows Server 2016.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">The Tech Previews
all had a preview version of RSAT available for them.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Since Windows Server released, only the RTM
version of RSAT for Windows 10 is available for download.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">On the download page, youâll currently see it
as v1.2 with the WindowsTH-RSAT_WS2016-x64.msu name or WindowsTH-RSAT_WS2016-x86.msu
if youâre planning on running 32-bit Windows 10 for some reason.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Iâm personally surprised weâre still making
x86 versions of RSAT available.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">The first caveat youâll hit is that Windows Server 2016 RTM corresponds
to Windows 10 build 1607, also known as the Anniversary Update.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">If you are running one of the earlier
releases of Windows 10 (builds 1511 or 1507), many of the RSAT tools from the
current v1.2 download will not work.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">For
example, if you open Active Directory Users and Computers and look at the
properties of a user, most of the tabs will be missing, including the General
tab.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Instead youâll get a view that
looks like this.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "calibri";"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS8gTg9jG1SI8wJ9Hmznvq3f_tY1yvD_CEywXs7T3ku4SST1QaU8TI4Vz5luHnOWrEIpM7jk28WYmbQOo806SDK4gJRp2mIq8JJKKbomrheEMqS_J_lvbSN_f_ZlVkkLOSsCOwN569uNPe/s1600/1511failure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS8gTg9jG1SI8wJ9Hmznvq3f_tY1yvD_CEywXs7T3ku4SST1QaU8TI4Vz5luHnOWrEIpM7jk28WYmbQOo806SDK4gJRp2mIq8JJKKbomrheEMqS_J_lvbSN_f_ZlVkkLOSsCOwN569uNPe/s320/1511failure.png" width="320" /></a></span></div>
<br />
<br />
<div style="margin: 0px 0px 11px;">
<span style="margin: 0px;"></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Or if you open the newer Active Directory Administrative
Center, then try to open a userâs properties, the console will crash.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">To avoid these problems, you must be on Windows 10 build
1607.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">When you upgrade from an earlier build to 1607, RSAT will
not remain installed.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Youâll have to
reinstall after upgrading.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">And youâll be
treated to the expected results within ADAC and ADUC.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="margin: 0px;"></span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "calibri";"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4kLnDhE06VCUIpOdVM-DbJReAb9shWyDm0iSb1ILkTbQiGQPlNRo06lZH2s0_8FxlgxcLOVmuo2RYdIh3uDadhl9Rr0wJrrhpe6xcM-oof4lujet6XGMRDLGpCQ5IE5iZ0gXyFqRdVLPe/s1600/1607Good.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4kLnDhE06VCUIpOdVM-DbJReAb9shWyDm0iSb1ILkTbQiGQPlNRo06lZH2s0_8FxlgxcLOVmuo2RYdIh3uDadhl9Rr0wJrrhpe6xcM-oof4lujet6XGMRDLGpCQ5IE5iZ0gXyFqRdVLPe/s320/1607Good.PNG" width="320" /></a></span></div>
<br />
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">One nice thing about RSAT for Windows 10 is that you no
longer have to enable the tools after installing the package.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">All the tools are automatically enabled.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Windows 7 required installing RSAT and then
remembering where to find the GUI to enable the tools.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">This behavior is back to how Windows 2000/3
worked.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">It was re-introduced with RSAT
for Windows 8, but I can count on one hand the number of admins Iâve seen
running that platform in the field.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Here is the full list of GUI tools that are added to the
Start Menu Windows Administrative Tools folder:</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Active Directory
Administrative Center</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Active Directory
Domains and Trusts</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Active Directory
Module for Windows PowerShell</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Active Directory
Users and Computers</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Certification
Authority</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Cluster-Aware
Updating</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">DFS Management</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">DHCP</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">DNS</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Failover Cluster
Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">File Server Resource
Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Group Policy Management</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Microsoft Azure Services</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Network Load
Balancing Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Online Responder
Management</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Remote Access
Management</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Remote Desktop Gateway
Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Remote Desktop
Licensing Diagnoser</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Remote Desktop
Licensing Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Routing and Remote
Access</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Server Manager</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Shielding Data File
Wizard</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Template Disk Wizard</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Volume Activation Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="font-family: "calibri";">Windows Server
Update Services</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">The full list of features that are enabled are:</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Feature
Administration Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">BitLocker
Password Recovery Viewer</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">DCB
LLDP-Agent Management Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Failover
Clustering Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Group
Policy Management Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">IP
Address Management (IPMA) Client</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Network
Controller Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Network
Load Balancing Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">NIC
Teaming Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Shielded
VM Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Role
Administration Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Active
Directory Certificate Services Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Certification
Authority Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Online
Responder Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">AD
DS and AD LDS Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Active
Directory Module for Windows PowerShell</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">AD
DS Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Active
Directory Administrative Center</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">AD
DS Snap-ins and Command-line Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">DHCP
Server Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">DNS
Server Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">File
Services Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Distributed
File System Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">FSRM Management</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">NFS
Administrative Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Storage
Replica Administrative Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote
Access Management Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">DirectAccess
Server Management Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote
Access module for Windows PowerShell</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote
Desktop Services Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote
Desktop Gateway Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote Desktop
Licensing Diagnoser Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px 0px 0px 48px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Remote Desktop
Licensing Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Volume
Activation Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Windows
Server Update Services Tools</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">API
and PowerShell cmdlets</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">User
Interface Management Console</span></div>
<br />
<div style="line-height: normal; margin: 0px;">
<span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Server Manager</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">You may notice a few differences from previous iterations of
RSAT.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Hyper-V is now built in to Windows
10, so the Hyper-V tools are their own features to be turned on or off and are
not part of RSAT anymore.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">The DCB LLDP-Agent
Management Tools includes the </span><a href="https://technet.microsoft.com/en-us/library/mt787118.aspx"><span style="color: #0563c1; font-family: "calibri";">NetLldpAgent
PowerShell Cmdlets</span></a><span style="font-family: "calibri";">.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">The Shielded VM
Tools includes the Provisioning Data File Wizard and the Template Disk
Wizard.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">To find out more about how these
tools help create Shielded VMs you can read Dean Wellsâ blog post on </span><a href="https://blogs.technet.microsoft.com/datacentersecurity/2016/03/23/creating-shielded-vms-as-a-tenant/"><span style="color: #0563c1; font-family: "calibri";">Creating
Shielded VMs Step by Step</span></a><span style="font-family: "calibri";">.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Finally,
the Microsoft Azure Services tool is simply a link to get you started with </span><a href="http://go.microsoft.com/fwlink/?LinkId=401298"><span style="color: #0563c1; font-family: "calibri";">understanding the
Operations Management Suite</span></a><span style="font-family: "calibri";">.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">If youâve gotten your RSAT fix for now, and are wondering
whatâs next, you might want to spend some time reading up on Microsoftâs next
generation of server management tools.</span><span style="margin: 0px;"><span style="font-family: "calibri";">
</span></span><span style="font-family: "calibri";">We now provide an Azure-hosted management portal called Server
Management Tools.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">It uses a gateway
located on-premise to proxy between your on-premise servers and Azure so that
you can securely administer your servers from anywhere on any device.</span><span style="margin: 0px;"><span style="font-family: "calibri";"> </span></span><span style="font-family: "calibri";">Look through their blog at </span><a href="https://blogs.technet.microsoft.com/servermanagement"><span style="color: #0563c1; font-family: "calibri";">https://blogs.technet.microsoft.com/servermanagement</span></a><span style="font-family: "calibri";">
if you want to know more.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">Thanks for spending a little bit of your time with me.</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">-Dave</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<span style="font-family: "calibri";">#proudmicrosoftemployee</span></div>
<br />
<div style="margin: 0px 0px 11px;">
<br /></div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike>David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-19175477406157229832017-01-03T16:25:00.000-05:002017-01-03T16:25:12.221-05:00First PFE Blog Entry<div>
Since I changed employers last year and became a Premier Field Engineer (PFE) with Microsoft, I've been torn about where to continue my posts. I've decided to continue posting here for the ordinary things I want to document for the search engines, and on the Microsoft properties for when I have something really worthy of the PFE platforms space. So to that end, my first PFE post went up today. I'll cross post here just so that I have my own copy of it as well.</div>
<div>
<br /></div>
<div>
Remote Server Administration Tools for Windows 10</div>
<div>
<br /></div>
<div>
<a href="https://blogs.technet.microsoft.com/askpfeplat/2017/01/03/remote-server-administration-tools-for-windows-10" target="_blank">https://blogs.technet.microsoft.com/askpfeplat/2017/01/03/remote-server-administration-tools-for-windows-10</a></div>
<div>
<br /></div>
<div>
</div>
David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-41920620165216307082015-12-09T13:29:00.001-05:002015-12-09T13:32:12.935-05:00Logging PowerShell Error Message OutputWhen designing a PowerShell script that will be executed as a scheduled task, I prefer copious amounts of logging, for obvious reasons. I recently had some fun with getting error messages logged with sufficient detail. Consider the following simple script:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">$A = Get-ChildItem C:\temp<br />try {<br /> $B = Get-ChildItem2 C:\temp<br />} catch {<br /> $Error[0] | Out-File -filepath c:\temp\test.log<br />}</span></blockquote>
<br />
I have forced an error to occur on line 3 by including an invalid command. When run interactively no output is produced on the screen, which is fine because when run as a scheduled task, no one will be there to see it anyways. The log file contains the following content:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">Get-ChildItem2 : The term 'Get-ChildItem2' is not recognized as the name of a cmdlet, function, script file, or <br />operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try <br />again.<br />At C:\Temp\test.ps1:3 char:7<br />+ $B = Get-ChildItem2 C:\temp<br />+ ~~~~~~~~~~~~~~<br /> + CategoryInfo : ObjectNotFound: (Get-ChildItem2:String) [], CommandNotFoundException<br /> + FullyQualifiedErrorId : CommandNotFoundException</span></blockquote>
The output log contains the normal error detail you'd see if running the command interactively.<br />
<br />
<br />
Let's enhance the log with something normal like a timestamp.<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">(get-date -UFormat "%Y%m%d%H%M%S") + ": " + $Error[0] | Out-File -filepath c:\temp\test.log</span></blockquote>
<br />
The output log now contains the content:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">20151209123349: The term 'Get-ChildItem2' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.</span></blockquote>
We successfully added the timestamp, but lost many details such as the line that incurred the error. Let's see if we can restore the missing data to the log file. When we look at the error object, we can see the following information:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">
PS C:\Temp> $Error[0] | gm<br />
<br /> TypeName: System.Management.Automation.ErrorRecord<br />
Name MemberType Definition<br />---- ---------- ----------<br />Equals Method bool Equals(System.Object obj)<br />GetHashCode Method int GetHashCode()<br />GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System....<br />GetType Method type GetType()<br />ToString Method string ToString()<br />CategoryInfo Property System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;}<br />ErrorDetails Property System.Management.Automation.ErrorDetails ErrorDetails {get;set;}<br />Exception Property System.Exception Exception {get;}<br />FullyQualifiedErrorId Property string FullyQualifiedErrorId {get;}<br />InvocationInfo Property System.Management.Automation.InvocationInfo InvocationInfo {get;}<br />PipelineIterationInfo Property System.Collections.ObjectModel.ReadOnlyCollection[int] PipelineIterationInfo {g...<br />ScriptStackTrace Property string ScriptStackTrace {get;}<br />TargetObject Property System.Object TargetObject {get;}<br />PSMessageDetails ScriptProperty System.Object PSMessageDetails {get=& { Set-StrictMode -Version 1; $this.Except...</span></blockquote>
<br />
We have a default to ToString() method. Let's see what that gets us:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">PS C:\Temp> $Error[0].ToString()<br />The term 'Get-ChildItem2' is not recognized as the name of a cmdlet, function, script file, or operable program. Check<br />the spelling of the name, or if a path was included, verify that the path is correct and try again.</span></blockquote>
<br />
<br />
That matches the text that ended up in the second log file. Let's see if we can find where the missing data lives in the ErrorRecord object. The initial output contains the keywords CategoryInfo and FullyQualifiedErrorId. Those are both properties, so let's look at those:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">PS C:\Temp> $Error[0].CategoryInfo</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">Category : ObjectNotFound<br />Activity :<br />Reason : CommandNotFoundException<br />TargetName : Get-ChildItem2<br />TargetType : String</span></blockquote>
<blockquote class="tr_bq">
<br />
<span style="font-family: "courier new" , "courier" , monospace;">PS C:\Temp> $Error[0].FullyQualifiedErrorId<br />CommandNotFoundException</span></blockquote>
<br />
<br />
That's a start as that data is included in the initial output, but is unformatted. We're still missing the pointer to the faulting line in the script. Looking through the other properties, we see that the InvocationInfo property contains the data we were looking for in the PositionMessage property.<br />
<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">PS C:\Temp> $Error[0].InvocationInfo</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">MyCommand :<br />BoundParameters : {}<br />UnboundArguments : {}<br />ScriptLineNumber : 3<br />OffsetInLine : 7<br />HistoryId : 36<br />ScriptName : C:\Temp\test.ps1<br />Line : $B = Get-ChildItem2 C:\temp</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">PositionMessage : At C:\Temp\test.ps1:3 char:7<br /> + $B = Get-ChildItem2 C:\temp<br /> + ~~~~~~~~~~~~~~<br />PSScriptRoot : C:\Temp<br />PSCommandPath : C:\Temp\test.ps1<br />InvocationName : Get-ChildItem2<br />PipelineLength : 0<br />PipelinePosition : 0<br />ExpectingInput : False<br />CommandOrigin : Internal<br />DisplayScriptPosition :</span></blockquote>
<br />
<br />
At this point, we could come up with a mildly complex function to recreate the initial output by referencing the appropriate properties. However, there's an easier way to get the error output.<br />
<br />
<br />
<a href="https://technet.microsoft.com/en-us/library/hh849952.aspx" target="_blank">Out-String</a><br />
<br />
<br />
In all my years of PowerShell-ing, I've never had a reason to use Out-String, as most items will normally render as a string to the console or a file (as was evidenced above). Out-String does exactly what we want in this instance.<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">PS C:\Temp> $Error[0] | Out-String<br />Get-ChildItem2 : The term 'Get-ChildItem2' is not recognized as the name of a cmdlet, function, script file, or<br />operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try<br />again.<br />At C:\Temp\test.ps1:3 char:7<br />+ $B = Get-ChildItem2 C:\temp<br />+ ~~~~~~~~~~~~~~<br /> + CategoryInfo : ObjectNotFound: (Get-ChildItem2:String) [], CommandNotFoundException<br /> + FullyQualifiedErrorId : CommandNotFoundException</span></blockquote>
<br />
<br />
From the console, this output is unsurprisingly identical to the statement $Error[0] issued all by itself.<br />
<br />
<br />
We can add this into our script as follows:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">(get-date -UFormat "%Y%m%d%H%M%S") + ": " + ($Error[0] | Out-String) | Out-File -filepath c:\temp\test.log</span></blockquote>
And finally our log file contains the full content we want:<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">20151209132608: Get-ChildItem2 : The term 'Get-ChildItem2' is not recognized as the name of a cmdlet, function, script file, or <br />operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try <br />again.<br />At C:\Temp\test.ps1:3 char:7<br />+ $B = Get-ChildItem2 C:\temp<br />+ ~~~~~~~~~~~~~~<br /> + CategoryInfo : ObjectNotFound: (Get-ChildItem2:String) [], CommandNotFoundException<br /> + FullyQualifiedErrorId : CommandNotFoundException</span></blockquote>
<br />
<br />
<br />
<br />
<br />
David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-37103781683568694002015-05-28T18:45:00.001-04:002015-05-28T18:45:36.599-04:00Deploy IIS URL Rewrite rules using PowerShellI'm finalizing a FIM implementation that uses the FIM portal. I have some fit-and-finish changes about the URLs I want to implement so that users who type in the site name automatically get to the HTTPS version of the FIM portal, rather than the HTTP version of SharePoint that lives at the root of the website.<br />
<br />
<br />
It took a little while to figure out the syntax of the rewrites and how to deploy via PowerShell. Most of the examples I found only provided the XML definition of the rule. Here are those two rules, ready for deployment via PowerShell (using the <a href="http://www.iis.net/downloads/microsoft/powershell">IIS PowerShell Snap-In</a>).<br />
<br />
<br />
Example: Redirect to HTTPS<br />
<blockquote class="tr_bq">
$SiteName = "FIMSite"<br />
$RuleName = "HTTP to HTTPS"<br />
$Rule = @{<br />
Name = $RuleName<br />
patternSyntax = 'ECMAScript'<br />
stopProcessing = 'True'<br />
match = @{<br />
url = '(.*)'<br />
ignoreCase = 'True'<br />
negate = 'False'<br />
}<br />
conditions = @{<br />
logicalGrouping = 'MatchAll'<br />
trackAllCaptures = 'True'<br />
}<br />
action = @{<br />
type = 'Redirect'<br />
url = 'https://{HTTP_HOST}/{R:1}'<br />
appendQueryString = 'False'<br />
redirectType = 'Permanent'<br />
}<br />
}<br />
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule<br />
$match = @{<br />
input = '{HTTPS}'<br />
matchType = 'Pattern'<br />
pattern = 'off'<br />
ignoreCase = 'True'<br />
negate = 'False'<br />
}<br />
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules/rule[@Name='$RuleName']/conditions" -Name "." -Value $match</blockquote>
<br />
<br />
Example: Redirect to Application<br />
<blockquote class="tr_bq">
$SiteName = "FIMSite"<br />
$RuleName = "Redirect to FIM Application"<br />
$Rule = @{<br />
Name = $RuleName<br />
patternSyntax = 'ECMAScript'<br />
stopProcessing = 'True'<br />
match = @{<br />
url = '^$'<br />
ignoreCase = 'True'<br />
negate = 'False'<br />
}<br />
action = @{<br />
type = 'Redirect'<br />
url = '/IdentityManagement/default.aspx'<br />
appendQueryString = 'False'<br />
redirectType = 'Permanent'<br />
}<br />
}<br />
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule</blockquote>
<br />
<br />David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-52616953494662113802014-09-29T20:47:00.000-04:002014-09-29T20:47:44.480-04:00Fun ways to shoot yourself in your own footStep 1. Devise an awesome failover scenario with boot-from-SAN, SAN mirroring, automatic DNS selectors and all sorts of fun stuff.<br />
<br />
Step 2. Add lots of hosts entries to your servers to cover up problems with your DNS usage.<br />
<br />
Step 3. Forget about Step 2.<br />
<br />
Step 4. Have a failure that exercises the engineered solution in Step 1.<br />
<br />
Step 5. Spend the next several hours wondering why your service isn't working before blaming the directory and calling in the experts because one error message happens to include the word "logon".<br />
David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-46738129583758795512013-08-26T06:53:00.002-04:002022-09-01T10:55:44.734-04:00Sending Encrypted S/MIME Messages with PowerShellFirst you need the public key of the recipient. In this example we will retrieve the public key from AD. Public keys are stored in userCertificate which is a multivalued attribute, so we must pick a valid certificate from all the certificates that may be in the attribute. Weâre looking for a certificate which is usable for Secure Email and is currently valid for use (within a 5 minute skew). We will pick the first certificate that meets those criteria.<br />
<blockquote>
$RecipientCN='someusername' <br />$RootDSE = [ADSI]("LDAP://RootDSE") <br />$SearchForestForPerson = New-Object DirectoryServices.DirectorySearcher <br />$SearchForestForPerson.SearchRoot = "GC://" + $RootDSE.rootDomainNamingContext <br />$SearchForestForPerson.SearchScope = "subtree" <br />$SearchForestForPerson.PropertiesToLoad.Add("distinguishedname") | Out-Null <br />$SearchForestForPerson.PropertiesToLoad.Add("mail") | Out-Null <br />$SearchForestForPerson.PropertiesToLoad.Add("usercertificate") | Out-Null <br />$SearchForestForPerson.Filter = ("(&(objectClass=person)(CN=$RecipientCN))") <br />$Recipient = $SearchForestForPerson.FindOne()<br />
$ChosenCertificate = $null <br />$Now = Get-Date <br />If ($Recipient.Properties.usercertificate -ne $null) { <br /> ForEach ($UserCertificate in $Recipient.Properties.usercertificate) { <br /> $ValidForSecureEmail = $false <br /> $Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$UserCertificate <br /> $Extensions = $Certificate.Extensions <br /> ForEach ($Extension in $Extensions) { <br /> If ($Extension.EnhancedKeyUsages -ne $null) { <br /> ForEach ($EnhancedKeyUsage in $Extension.EnhancedKeyUsages) { <br /> If ($EnhancedKeyUsage.FriendlyName -eq "Secure Email") { <br /> $ValidForSecureEmail = $true <br /> break <br /> } <br /> } <br /> If ($ValidForSecureEmail) { <br /> break <br /> } <br /> } <br /> } <br /> If ($ValidForSecureEmail) { <br /> If ($Now -gt $Certificate.NotBefore.AddMinutes(-5) -and $Now -lt $Certificate.NotAfter.AddMinutes(5)) { <br /> $ChosenCertificate = $Certificate <br /> } <br /> } <br /> If ($null -ne $ChosenCertificate) { <br /> break <br /> } <br /> } <br />} </blockquote>
Now that we have a valid certificate, compose and send the email. The forum message at <a href="http://social.msdn.microsoft.com/Forums/en-US/74e4711e-1f66-43a7-9e3b-bc9cfbcd1b73/sending-smime-encrypted-email-using-c" title="http://social.msdn.microsoft.com/Forums/en-US/74e4711e-1f66-43a7-9e3b-bc9cfbcd1b73/sending-smime-encrypted-email-using-c">http://social.msdn.microsoft.com/Forums/en-US/74e4711e-1f66-43a7-9e3b-bc9cfbcd1b73/sending-smime-encrypted-email-using-c</a> provided most of the basis for getting the encryption correct.<br />
<blockquote>
Add-Type -assemblyName "System.Security" <br />
$MailClient = New-Object System.Net.Mail.SmtpClient "relay.widgets.com" <br />$Message = New-Object System.Net.Mail.MailMessage<br />
$Message.To.Add($Recipient.properties.mail.item(0)) <br />$Message.From = "noreply@widgets.com" <br />$Message.Subject = "Unencrypted subject of the message" <br />$Body = "Encrypted body of the message"<br />
$MIMEMessage = New-Object system.Text.StringBuilder <br />$MIMEMessage.AppendLine('Content-Type: text/plain; charset="iso-8859-1"') | Out-Null <br />$MIMEMessage.AppendLine('Content-Transfer-Encoding: 7bit') | Out-Null <br />$MIMEMessage.AppendLine() | Out-Null <br />$MIMEMessage.AppendLine($Body) | Out-Null <br />[Byte[]] $BodyBytes = [System.Text.Encoding]::ASCII.GetBytes($MIMEMessage.ToString())<br />
$ContentInfo = New-Object System.Security.Cryptography.Pkcs.ContentInfo (,$BodyBytes) <br />$CMSRecipient = New-Object System.Security.Cryptography.Pkcs.CmsRecipient $ChosenCertificate <br />$EnvelopedCMS = New-Object System.Security.Cryptography.Pkcs.EnvelopedCms $ContentInfo <br />$EnvelopedCMS.Encrypt($CMSRecipient) <br />[Byte[]] $EncryptedBytes = $EnvelopedCMS.Encode() <br />$MemoryStream = New-Object System.IO.MemoryStream @(,$EncryptedBytes) <br />$AlternateView = New-Object System.Net.Mail.AlternateView($MemoryStream, "application/pkcs7-mime; smime-type=enveloped-data;name=smime.p7m") <br />$Message.AlternateViews.Add($AlternateView)<br />
$MailClient.Send($Message) </blockquote>
David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com1tag:blogger.com,1999:blog-4018181297398983593.post-24792531213051280632013-06-18T17:52:00.001-04:002013-06-19T08:02:17.937-04:00FIM CSExport fails to run as a scheduled task<p> </p> <p>In our FIM environment we want to retrieve the list of pending exports.  This is typically accomplished with a âcsexport.exe MAName /f:xâ command.  On my dev environment as a user with FIMSyncAdmins rights, the export is produced as expected.</p> <p>When I ran the command as a scheduled task I would receive this error message in our log file</p> <blockquote> <p><font face="Courier New">Microsoft Identity Integration Server Connector Space Export Utility v4.1.3419.0 <br />c 2012 Microsoft Corporation. All rights reserved</font></p> <p><font face="Courier New">Failed to export connector space. <br />Error: <error>The Synchronization Service Manager service has stopped.</error> <br /></font></p> </blockquote> <p>Itâs an odd message in that the Sync service was absolutely running.</p> <p>After making sure there was nothing wrong with the PowerShell script that was driving the command, I eventually tried elevating the service account to include local admin rights, and at that point it succeeded.</p> <p>From there I took a leap of faith that the Sync service account really was running, but under a non-admin scheduled task, it couldnât see that the service was running for some reason.  Recalling the <a title="Non-administrators cannot remotely access the Service Control Manager after you install Windows Server 2003 Service Pack 1" href="http://support.microsoft.com/kb/907460" target="_blank">Service Control Manager hardening from Windows Server 2003 SP1</a>, I was guessing the scheduled task couldnât query the SCM.</p> <p>Sure enough, reviewing the default ACLs</p> <blockquote> <p><font face="Courier New">C:\Windows>sc sdshow FIMSynchronizationService</font></p> <p><font face="Courier New">D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCR <br />RC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)</font></p> </blockquote> <p>As an Interactive User (IU) you get read access to the service.  But as a scheduled task you donât get the IU SID.  The solution is to grant the FIMSyncAdmins group read access to the service.</p> <p>With a small PowerShell script to <a title="Windows PowerShell Tip: Working With SIDs" href="http://technet.microsoft.com/en-us/library/ff730940.aspx" target="_blank">determine the local groupâs SID</a>, we can update the SDDL for the service</p> <blockquote> <p><font face="Courier New">C:\Windows>sc sdset FIMSynchronizationService D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;; <br />CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)</font><font face="Courier New"><font style="background-color: #ffff00">(A;;CCLCSWLOCRRC;;;S-1-5-2 <br />1-2974223652-3803999246-3267058373-1009)</font>(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWR <br />PWPDTLOCRSDRCWDWO;;;WD) <br />[SC] SetServiceObjectSecurity SUCCESS</font></p> </blockquote> <p>And now CSExport works from a scheduled task.</p> David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-19559116005333465212012-11-07T14:10:00.001-05:002019-10-08T13:51:42.213-04:00Disable DHCP Authorization Check<br />
Redocumenting this here so I donât forget (as it just came up again).<br />
Use the HKLM\System\CurrentControlSet\Services\DHCPServer\Parameters DisableRogueDetection REG_DWORD = 1 from <a href="http://support.microsoft.com/kb/297847">http://support.microsoft.com/kb/297847</a>.<br />
Original discussion of the topic is archived at <a href="http://www.activedir.org/ListArchives/tabid/55/forumid/1/postid/30880/view/topic/Default.aspx" title="http://www.activedir.org/ListArchives/tabid/55/forumid/1/postid/30880/view/topic/Default.aspx">http://www.activedir.org/ListArchives/tabid/55/forumid/1/postid/30880/view/topic/Default.aspx</a>.David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com0tag:blogger.com,1999:blog-4018181297398983593.post-8201760195507369882012-11-01T08:50:00.001-04:002012-11-07T14:06:43.945-05:00Conditionally exporting Null values using IIF in FIM<p> </p> <p>Iâm re-documenting this here so I donât forget about it again.</p> <p>FIM will not, under any circumstance, export a Null value as the result of an IIF statement in an outbound flow!</p> <p>IIF is broken, and has been broken from the initial FIM release.  See <a href="http://social.technet.microsoft.com/Forums/en-US/ilm2/thread/da35429d-935a-4abe-85ed-a5d13e8df1a0/" target="_blank">Clear/delete attribute through Synchronization Rule</a> and <a href="http://social.technet.microsoft.com/Forums/en-AU/ilm2/thread/57ef761e-6f40-44a5-9881-bd9f2224a3b8" target="_blank">Using IIF to conditionally flow an authoritative attribute delete</a>.</p> <p>So I see three possible solutions to this problem.</p> <ol> <li>Classic coded sync rules for attributes with conditional export logic. </li> <li>Denormalize the metaverse so that all calculations can be performed inbound and the result stored in the metaverse, then use only direct export flows. </li> <li>(And the one I'm choosing at the moment) Perform a direct flow of a NullString attribute in the outbound flow to ensure that nulls are written.  Then add dependent sync rules for each condition that flow the calculated value when the condition is met.  This can be a bit messy to look at in FIM Service as dependent sync rules can only use logical AND when constructing the scope filters, so OR must be expressed as additional dependent sync rules, which can greatly increase the number of rules required.  In outbound flows, the last writer wins.  The null value in the parent rule is first.  If the condition is met, the dependent rule will write its value second, thus becoming the winning value that is exported.  When the condition ceases to be met the direct null value flow from the parent is allowed to win again and becomes the exported value. <br /></li> </ol> <p>UPDATE (2012.11.07)</p> <p>Hotfix rollup 4.1.2548.0 from <a title="http://support.microsoft.com/kb/2750671" href="http://support.microsoft.com/kb/2750671">http://support.microsoft.com/kb/2750671</a> includes a fix to IIF.  I havenât tested it yet, but good news for once on one of my FIM DCRs.</p> David Loderhttp://www.blogger.com/profile/15741815450513900329noreply@blogger.com2