Monday, September 30, 2013

Use FIM and Group Policies to manage Local Administrator permissions

A customer of mine had a requirement to create a domain group for each computer account in their domain. The purpose was very nice. They wanted a domain group to add to the Local Administrators group of each workstation, so that their users could request membership of this group for a period of time, i.e. for installing software that required extra permissions or for managing a laptop that was taken on the road.

It was quite straight forward to import all computer accounts to FIM and use my codeless provisioning framework to create a rule to provision a group to the AD MA for each computer account. Using the codeless framework there was no need to have all computer accounts go to the FIM Service. We provisioned every computer group using the naming convention <computername>-LocalAdmin and afterwards brought the new groups into FIM using another MA - and configured appropriate approval workflows to allow users to request membership of the groups.

The provisioning rule created looked like this (you can read more about the provisioning rules here) -

    <Rule>
      <Name>Provision local admin group to ad</Name>
      <Description></Description>
      <TargetManagementAgentName>ad admin</TargetManagementAgentName>
      <Enabled>true</Enabled>
      <SourceObject>computer</SourceObject>
      <TargetObject>group</TargetObject>
      <Action>provision</Action>
      <RenameDnFlow>
      </RenameDnFlow>
      <Conditions>
        <ConditionBase xsi:type="ConditionAttributeIsPresent">
          <Description>Only if contact has samaccountname</Description>
          <MVAttribute>samaccountname</MVAttribute>
        </ConditionBase>
        <ConditionBase xsi:type="ConditionConnectedTo">
          <ManagementAgentName>cmdb</ManagementAgentName>
        </ConditionBase>
      </Conditions>
      <InitialFlows>
        <AttributeFlowBase xsi:type="AttributeFlowConstant">
          <Constant>CN=#mv:sAMAccountname#-Administrators,OU=LocalAdminGroups,OU=Managed Groups,DC=contoso,DC=com</Constant>
          <Target>[DN]</Target>
        </AttributeFlowBase>
        <AttributeFlowBase xsi:type="AttributeFlowConstant">
          <Constant>#mv:sAMAccountname#-Administrators</Constant>
          <Target>sAMAccountName</Target>
        </AttributeFlowBase>
        <AttributeFlowBase xsi:type="AttributeFlowConstant">
          <Constant>#mv:sAMAccountname#-LocalAdmin</Constant>
          <Target>displayName</Target>
        </AttributeFlowBase>
        <AttributeFlowBase xsi:type="AttributeFlowConstant">
          <Constant>-2147483646</Constant>
          <Target>groupType</Target>
        </AttributeFlowBase>
      </InitialFlows>
    </Rule>


Now, the question remained; how do we effectively get these new computer groups added to the Local Administrator group of each computer, both existing and new computer accounts? Oh, no, it wasn't using PowerShell this time, although I was tempted.

I had a chat with a good colleague of mine from Inceptio, Risto Petersen. Risto is an Active Directory wizard and he had just the recipe; to add a machine specific group to the local Administrators group of every server and/or workstation, you can deploy a Group Policy (GPO) utilizing Computer Configuration Preferences. The steps are -
  1. Create a naming standard for your groups including the computername in the group name. In this example I will use <computername>-LocalAdmin, so that for the computer PC1 the group is PC1-LocalAdmin
  2. Create the necessary groups, one for each computer object. Use scripting or FIM or some other tool. Remember to keep groups in sync with computer objects; i.e. when a computer is deleted the group should also be deleted.
  3. Create a GPO and link it to where your computer objects live in AD
  4. Edit this new GPO
  5. Go to “Computer Configuration”
  6. Go to “Preferences”
  7. Go to “Control Panel Settings”
  8. Go to “Local Users and Groups”
  9. Create a new “Local Group” object for the “Builtin Administrators” group
  10. Set the action to “Update”
  11. In the Members section add “%COMPUTERNAME%-LocalAdmin” or what your naming standard dictates
  12. You might also want to add another general group like “ALL-COMPUTERS-LocalAdmin” to easily delegate rights to all computers
After the next GPO update, your computers will have populated their local Administrators groups with specific computer specific groups. You can then delegate access to individual computers by adding users to these specific computer groups.

A great thank you goes to Risto for this trick - and combining this setup with FIM's self service features, you have a relative simple solution to allow your users access to local administrator permissions.

Tuesday, September 17, 2013

Use PowerShell to get AD schema information

Sometimes when I engage in FIM 2010 or Active Directory projects, I get the question: "Okay, then which attributes do we actually have in our Active Directory then?". It is a fair question and often knowing the site's actual Active Schema at a given point in time can be useful.

Instead of going to the Active Directory Schema snap-in and manual browsing through the scheam, I've created a small PowerShell script that enables you to dump the schema for a user (or other objectclass) into CSV files (or into the PowerShell pipeline) for further processing.

You may find this information about your Active Directory useful or just fun, so here's there script -

$schema = [directoryservices.activedirectory.activedirectoryschema]::getcurrentschema()
$schema.FindClass("user").mandatoryproperties | select name, commonname, description, syntax | export-csv user-mandatory-attributes.csv -Delimiter ';'
$schema.FindClass("user").optionalproperties | select name, commonname, description, syntax | export-csv user-optional-attributes.csv -Delimiter ';'


There is also a short version of the script if you don't want any fancy selecting and exporting, but just want the attribute information in your pipeline -

$objuserclass=[adsi]”LDAP://schema/user”
$objuserclass.mandatoryproperties
$objuserclass.optionalproperties


Feel free to modify it to your specific needs and of course make sure that you run it as a user that has permission to dive into the Active Directory schema.

Enjoy.