Clean Up Active Directory and CM 2012 with Orchestrator

Keeping your AD and CM 2012 environment clean of old objects is key to making sure that you can get accurate and relevant information for your environment. Actually keeping these old and unused objects out of our environment can be a challenge. This article will show you a simple Orchestrator runbook that will clean out these old machines.

Runbook Overview

This is what your runbook will look like. It is split into two sections with the same input. The top line is what actually does the object delete, while the bottom line sends an email and writes a log of what was done. If you do not need a log of what the runbook deleted, the second line is not needed.

1

This runbook runs based on the lastLogonDate property of the Get-ADComputer PowerShell cmdlet. This property defines the last time the computer logged into AD. Anything that has not logged into AD in six months is probably safe to delete. This is an organizational decision, but that is normally the metric I use.

Initialize Data

This activity presents a dialog box where you tell the runbook how many days old the lastLogonDate property can be. To create this, simply drag the “Initialize Data” (located under the “Runbook Control” node) activity into your runbook. Open the activity, click the “Add” button, and give your property a name. I named mine “Age”.

Capture Inactive Computers

Next, we’re going to use a PowerShell script to capture the lastLogonDate property for all devices. Add the “Run .NET Script” to your runbook. It is under the “System Node”. Double-click the activity to open it. Change the “Language” option to PowerShell and paste this code into the script box:

$today = get-date $age = $today.AddDays(<published data from Initalize data>)

$comps = PowerShell { import-module activedirectory get-adcomputer -filter * -properties lastLogonDate -searchbase “” }

$a = @() ForEach ($comp in $comps) { If ($comp.lastLogonDate -lt $age) { $a += $comp.name } }

Be sure to replace with the actual published data. This can be done by right-clicking inside the parentheses, selecting Subscribe, and then Published Data (be sure to keep the parentheses).

There are few things going on in this script. First of all, we are capturing today’s date. Then, we are adding the number of days we entered in the “Initialize Data” activity to today’s date.

Next, we are loading the active directory module and running the Get-ADComputer cmdlet to grab the lastLogonDate property for all computers. In this line, I am specifying an OU for the cmdlet to use, because I do not want to grab servers or devices outside of a particular OU. You can add this as needed with the -searchbase parameter. We are also launching a new PowerShell session to run this command. This is required if your Orchestrator environment is running on Windows Server 2012, or if you have the Windows Management Framework v3.0 installed on your Windows Server 2008 R2 server. Orchestrator runs PowerShell sessions in PowerShell 2, so the import module fails on the import if PowerShell 3 is running on your box. You also need to ensure that you have the Active Directory PowerShell Module installed on the server (this is done through Add Roles and Features).

Finally, we are building an array and adding the computers that meet our date requirements to the array. These are the computers that will be deleted. This array needs to be published. To do this, select the “Published Data” node. Click the “Add” button and fill the form out like this:

2

For the bottom process of the runbook, we also need to publish the date. We will use the date when we write the log file at the end. Add another published data, and fill it out like this:

3

The two “Capture Inactive Computers” activities are exactly the same except for one thing. In the bottom section (the one for the log), the output array is flattened. This is so that the runbook does not split into multiple instances, generating multiple emails and files. To flatten the output, select the “Run Behavior” node and check the “Flatten” checkbox. I separated my output by line, so I also checked that box. You can format it however you want.

4

Delete Computer

I am going to cover the remaining top line of the runbook first. This step will delete the computer from AD. To do this step, you need the Active Directory Integration Pack for Orchestrator. It can be downloaded here: http://www.microsoft.com/en-us/download/details.aspx?id=28020.

Drag the “Delete Computer” activity (located under the “Active Directory” node) into your runbook. Open the activity and set your configuration to your active directory. If you do not have your configuration set up, go to the Options menu in the task bar, select active directory, and put in your AD’s information. Make sure that the account you use to connect has delete permissions to the OU your computers are located in.

Next, right-click in the “Distinguished Name” field and add the “a” published data from the previous step.

Delete Computer from CM 2012

We have to use PowerShell again for this step. Drag another “Run .NET Script” into your runbook. Open it, change the language to PowerShell, and paste this code into the script box:

PowerShell { import-module “C:\Integration Packs and Add-Ons\ConfigurationManager.psd1″ Remove-CMDevice -devicename “<a from Capture Inactive Computers>”

}

Just as in the Capture step, we must load another PowerShell session in order to load the CM 2012 PowerShell module. Also, you must copy “ConfigurationManager.psd1” file from a computer that is running the CM 2012 SP1 console. Note that this step will only work with CM 2012 SP1 and later, because the additional PowerShell integration was not introduced until service pack one. The PSD1 file is located in “C:\Program Files (x86)\ConfigMgr\bin” on a computer that is running the console. You can copy this file into a directory on your runbook server and change the path in my code.

Also make sure that you insert the actual published data into your code.

Send Email

Now we will switch gears and go back to the log part of the runbook. To do this step, drag the “Send Email” activity (located in “Email” node) into your runbook. To configure this activity, open it and fill out the subject and to address. In the “Message” box, right-click, go to published data, and add the “a” variable from the previous step. You can also add any additional information if you want in this box.

Next, go to the “Connect” node and fill out a “From” address and the outgoing mail server settings.

Write Delete Log

Finally, we’re going to write a log of what was deleted. To do this, add the “Append Line” activity (located in the “Text File Management” node) to your runbook. This activity writes lines to a file, but it will also create the file if it does not already exist.

5

Be sure to replace with the name of the file server where you want to write the log. Make sure that your Orchestrator runbook server account as read/write access to the location where the file is being written. The file name is also where we are using the date published data from “Capture Inactive Devices”. I am using it in the file name as shown in the screen shot. Also, in the “Text” field, insert the “a” published data from “Capture Inactive Devices”.

Summary

Keeping your AD and CM 2012 environments clean is important. Old objects can mess up inventories and make AD processing take longer. This is a simple runbook that can analyze this and take action for you. You can also right-click on the link between “Initialize Data” and the top “Capture Inactive Devices” and select disable to disable that section of the runbook. This will allow you to a get report of computers that have been inactive for your given amount of time while not deleting them.

Keep checking back for more Orchestrator runbooks to help in your System Center environment.

email

Written by , Posted .
  • David Olive

    Love the idea of this script. Get the following error on the second step on both the bottom and the top paths:

    Unexpected token ‘foreach’ in expression or statement

    • Alessandro

      try this $a = ForEach ($comp in $comps) { If ($comp.lastLogonDate -lt $age) { $a += $comp.name } }
      Alessandro