PowerShell History Viewer

Here’s a nice feature of the Active Directory Administrative Centre – the PowerShell History Viewer. Simply undertake your daily tasks as usual and the PowerShell History Viewer will capture what you do and allow you to see the commands it used to perform those tasks. You’ve then taken the first steps needed to automate your most common tasks as you will:

  1. Know which tasks you carry out most regularly and
  2. Know the PowerShell commands to perform those tasks.

To expose the PowerShell History Viewer in the Active Directory Administrative Centre, click on the up arrow at the bottom right of the Admin Centre.

 

You can now perform your usual tasks and the PowerShell for those tasks will be captured there.

The PowerShell used is displayed below – checking the “Show All” box will show all PowerShell commands issued to run the Admin Centre, not just those related to you entering instructions.

 

For the “full” command, right click it and select “Copy”

 

You can then paste it into your favourite editor such as the PowerShell Integrated Scripting Engine (ISE). If you would prefer to just read the string in the GUI then clicking the + sign to the left of the command renders it readable.

 

 

Shutting down the Admin Centre will clear the history so do take a note of any commands you need first.

 

 

 

 

 

Listing group membership and extracting into a CSV file for multiple groups

I’ve been hunting around the web for a powershell script that will list the members of multiple groups and haven’t been able to write one so I’ve written my own.

This script isn’t intended to be perfect but it will give you the bare bones of how to write your script. For example, this script work on the basis of entering all or part of a group name and then reporting on that group. If you enter a blank or * from the group name then it will export user membership in all groups as direct members (add a  recursive switch if you need membership of nested groups). This is useful if you have a group naming convention as you can easily drill down into the groups you want.

It also doesn’t filter out computer accounts so it depends if that’s an issue for you and it reports against the whole AD but you can always filter the Get-ADGroup command to scope it to an individual OU or area of AD.

In any event, like I said I wasn’t able to find anything around to do this so hopefully, if you need to do this, this script will give you a good head start on exporting these values from your directory.

Here’s the script – if copying and pasting into notepad remember to correct some characters such as ‘ and “.

 

Import-Module ActiveDirectory
Write-Host “********************************************************”
Write-Host “* This script will dump out users in named groups, all *”
Write-host “* groups or a range of groups. You will be guided *”
Write-host “* through the process *”
Write-Host “* *”
Write-Host “* All output will be saved to C:SupportScriptOutput *”
Write-Host “********************************************************”
write-host

$strFileName = $(
$selection = read-host ‘Enter the name of file to save results to. Include an extention. (Default = Groupmembership.csv)’
if ($selection) {$selection} else {‘GroupMembership.csv’}
)

$strFileName = “C:SupportScriptOutput” + $strFilename
If (Test-Path $strFileName){
Remove-Item $strFileName
}

Write-Host
Write-Host ‘Enter name of group you would like to export’
Write-Host ‘The script will look for matching groups’
Write-Host
Write-Host ‘Entering the first part of the group name will return all matching groups’
Write-Host ‘For example, Entering “LG-APP-” without the quotation marks will return all application groups’
Write-Host
Write-Host ‘Pressing return will list membership of ALL groups’
Write-host
Write-Host ‘***** WARNING *****’
Write-Host
Write-Host ‘Exporting all group memberships will take some time as it will’
Write-Host ‘include all built in groups and distribution lists – use with caution’
Write-Host

$strGroupNames = $(
$selection = Read-Host ‘Enter name of group you would like to export (no value will return all groups)’
if ($selection) {$selection + ‘*’} else {‘*’}
)

Write-Host
Write-Host ‘Exporting teams with names like ‘ $strGroupNames ‘ to ‘ $strFilename
$data= ‘Group,UserName,UserID’
Write-Output $data | out-file -FilePath $strFileName -Append
$groups = Get-ADGroup -filter {name -like $strGroupNames}
foreach ($Group in $Groups)
{
$usernames = Get-ADGroupMember $($group.name)

foreach ($user in $usernames)
{
$data = $Null
$data = $data + $group.name + “,” + $user.name + “,” + $user.saAMAccountName
Write-Output $data | out-file -FilePath $strFileName -Append

}
}

 

Documenting Group Policy Objects

We all know that there is a simple way to document GPOs, just right click the GPO and select “Save Report” which will create an HTML file but those can be a little hard to understand and don’t include all of the data such as what individual settings do. An alternative is to use the Microsoft Security Compliance Manager (SCM). Version 3.0 is now available for download from http://technet.microsoft.com/en-gb/solutionaccelerators/cc835245.aspx.

By default, SCM imports baselines for the following products:

 

 

Hopefully Microsoft will release the baseline packs for 2012 R2, Windows 8.1, Exchange 2013 and SQL at some point but that doesn’t necessarily prevent the tool being used for documenting most standard settings.

To document the settings, backup your GPO in the usual way and then use the “Import a Group Policy Backup” link in the “Get Information” section.

 

 

Browse to where you have your backup GPO

 

 

Select a name for the “baseline” or GPO settings and click on OK

 

 

Your settings will now be shown as an imported GPO

 

 

You can click on the Excel link to export the settings to Excel

 

 

Choose to enable the content in the excel spreadsheet created

 

 

You will now have your settings in Excel format together with an explanation of each setting and, where covered by the built in security baseline information, details of any vulnerabilities that the setting may address, counter measures that can be deployed to overcome that vulnerability and any impact that setting of the GPO value may cause.

NOTE: Click on the image below to see the level of detail provided for each setting.

 

 

Obviously this is a bit more long winded than simply exporting a report but I hope that you can also see how this does provide far more information around what has been configured and, as it is in Excel, enables you to add a further column with an explanation as to why each setting has been configured.

 

Setting up Active Directory for DR

When setting up a Disaster Recovery site its reasonably standard to deploy Active Directory in that site and let AD replicate as usual to ensure that you have a copy of the directory available.

However, replication between sites (using site links0 can only occur as often as once every 15 minutes, longer if you don’t change the defaults. This means that, if the disaster occurs in that time period, any changes that you make may well be lost.

To overcome this you can set up change based notifications for the site link. This makes updates between sites work as though they are within the same AD site. that is, pretty much as soon as a change occurs, it will replicate across the link. of course, this will generate more traffic between links especially for larger sites but you tend to ind that a DR replication link is usually fairly fast and low latency to allow replication of the virtual machines and data.

To enable notification driven replication between active directory sites, access the site link properties page and update the “options” value.

lab3

The options attribute uses a bitmap. Its possible values are:

Decimal Value Binary Value Explanation
1 1 USE_NOTIFY
2 10 TWOWAY_SYNC
4 100 DISABLE_COMPRESSION

If you want to enable notification without compression (as you are on a LAN like connection, for example, between firewalled segments of the LAN) you can enter the value 5 to enable notification without compression.

How do I use the Windows 2008 R2 Recycle Bin feature ?

New in Windows 2008 R2 active directory is the concept of Active Directory Optional Features and the first of these which have been made available is the Recycle Bin feature. Ever since Active Directory was launched you have been able to recover individual deleted items by undertaking an authoritative restore of sections of the database, even down to an individual object. From 2003 onwards deleted objects have been tombstoned and you have been able to use the ADRestore tool (available to download from http://technet.microsoft.com/en-us/sysinternals/bb963906.aspx). However, the issue with these methods has always been with back links or, to put it another way, restoring these items with any group membership they had and, yes, it has been possible to do that with multiple authoritative restores of the database but that is at best tiresome and at worse can be dangerous. What the Recycle Bin feature does for you is restore with these back links / group memberships in place.

However, to use this feature the first thing you need to do is have your Forest at the Windows 2008 R2 level. Whilst your schema may be at the R2 level (meaning your forest can play host to 2008 R2 Domain Controllers) your domains and forest may still be running Domain Controllers with previous operating systems such as 2008 RTM or 2003 R2. The easy way to check your domain level in Windows 2008 R2 is to start the new Active Directory Administrative Centre. If you select the domain node on the left hand side (the netbios name of my domain is philipflint) then you will be able to check and raise the domain / forest functional levels in the action pane on the right hand side.

 

 

Click to Enlarge
Click to Enlarge

 

If your forest level is not at Windows 2008 R2 you can raise it.

  

Click to Enlarge
Click to Enlarge

 

We can now install the Recycle Bin feature. Care should be taken before undertaking the next procedure. Enabling the Recycle Bin feature for a domain / forest is a one way process with no way back. In a typical environment the recycle bin feature will grow the Active Directory database by 10 – 20% which may have an affect on performance especially in larger environments which many thousands of users where servers have been sized to run the complete database in RAM.

You should also note that, even though the Recycle Bin is an optional feature, it cannot be added as a Role Service nor as a Feature.

 

Click to Enlarge
Click to Enlarge

 

Instead the role is enabled by running a command in PowerShell. PowerShell is installed by default Windows 2008 R2 servers. However, PowerShell itself has no knowledge of Active Directory. Instead we need to load up the scripts and Verbs that PowerShell needs to be aware of to connect and control Active Directory. There are two ways to do this. The first, and simplest, is to click on Start | All Programs | Administrative Tools | Active Directory Module for Windows PowerShell.

 

Click to Enlarge
Click to Enlarge

 

The other alternative is to start PowerShell by clicking on the below icon on the taskbar and then running the command below to import the Active Directory modules.

 

Import-Module ActiveDirectory

 

 

Click to Enlarge
Click to Enlarge

 

We can now enable the Recycle Bin Feature. Below is a piece of code that you can change to use in your environment.

Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration, DC=YourDomain,DC=ComOrNetOrLocal‘ –Scope ForestOrConfigurationSet –Target ‘YourDomain.ComOrNetOrLocal‘ –confirm:$false

I’ve highlighted in Red the three pieces of information you have to change. If you have a two tier domain name (such as .co.uk) then you will have to add another DC= section. An example is given below for a domain called philipflint.co.uk.

Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration, DC=philipflint,DC=co,DC=uk‘ –Scope ForestOrConfigurationSet –Target ‘philipflint.co.uk‘ –confirm:$false

After amendment for the appropriate domain name variables this command is simply cut and paste into the PowerShell window.

 

Click to Enlarge
Click to Enlarge

 

I was not given a chance to back out of the addition of the feature as I used the PowerShell switch –confirm:$false which provides any confirmation when asked. If you do not include this switch then you will be asked to confirm the action.

NOTE: This command needs to be run for each domain in your forest for which the Recycle Bin should be installed.

After synchronising the domain the Recycle Bin will be active on all Domain Controllers and you can now test it out by creating test OU’s and test users and deleting them and restoring them. I have created two users called ‘William Shakespeare‘ and ‘Enid Blyton’ in an OU called ‘Authors‘.

They are both members of the Global Group ‘Famous‘ and the Domain Local group ‘Published‘.

 

Click to Enlarge
Click to Enlarge

 

We can now delete the William Shakespeare account.

 

 

Click to Enlarge
Click to Enlarge

 

To restore a user that has been deleted I have provided a script for you below.

Get-ADObject -Filter {samAccountName -eq “UserLogonName“} -IncludeDeletedObjects | Restore-ADObject

As before, simply change the section in Red with the display name of the user you want to restore. I use the logon name as its something that you can ask the user that they are likely to know but if they don’t know this (‘Its always there, I just enter my password’) then you can use another field which uniquely identifies them, their email address for example.

Get-ADObject -Filter {mail -eq “UsersEmailAddress“} -IncludeDeletedObjects | Restore-ADObject

To restore Williams account we can just enter the following in the PowerShell window.

Get-ADObject -Filter {samAccountName -eq “william.shakespeare“} -IncludeDeletedObjects | Restore-ADObject

 

Click to Enlarge
Click to Enlarge

 

The user account is now restored along with all group memberships.

 

Click to Enlarge
Click to Enlarge

Memberships below.

 

Click to Enlarge
Click to Enlarge

 

Now, of course, its possible that a user may be deleted who is in an OU that has also been deleted. It is not possible to restore the user without first restoring the OU of which they were a member or, in extreme cases, the whole OU tree if multiple OU’s have been deleted.

 

Unless your records are up-to-date there is a chance that you may not know what your exact OU structure was and so you need a method of finding out what was the parent object of a deleted user. The code to do this is below.

Get-ADObject -SearchBase “CN=Deleted Objects, DC=YourDomain,DC=ComOrNetOrLocal‘ ” -ldapFilter:”(msDs-lastKnownRDN=ObjectName)” –IncludeDeletedObjects –Properties lastKnownParent

For example, if we run the above for our deleted William Shakespeare account we would run the following.

Get-ADObject -SearchBase “CN=Deleted Objects, DC=philipflint,DC=com” -ldapFilter:”(msDs-lastKnownRDN=William Shakespeare)” –IncludeDeletedObjects –Properties lastKnownParent

 

 

Click to Enlarge
Click to Enlarge

 

As can be seen from the output, we can see that the last know parent (i.e. the containing OU for this user) was the Authors OU directly under the domain node. Note that the Authors OU has not been deleted and so the user object may be directly restored. Below is a screenshot with the same command but where the Authors OU has been deleted.

 

 

Click to Enlarge
Click to Enlarge

In this case we can query the Authors OU to find its last known good parent until we find a containing object which has not been deleted.

Once we know which is the first object to be restored we can begin the restoration process. Previously I have given you the code to restore a user. The command to restore an OU is slightly different and I show it below.

Get-ADObject -ldapFilter:”(msDs-lastknownRDN=NameOfYourOU)” -IncludeDeletedObjects | Restore-ADObject

In our case we would therefore run the following three commands to restore the OU and the 2 deleted accounts (William Shakespeare and Enid Blyton).

Get-ADObject -ldapFilter:”(msDs-lastknownRDN=Authors)” -IncludeDeletedObjects | Restore-ADObject

Get-ADObject -Filter {samAccountName -eq “william.shakespeare“} -IncludeDeletedObjects | Restore-ADObject

Get-ADObject -Filter {samAccountName -eq “enid.blyton“} -IncludeDeletedObjects | Restore-ADObject

 

Click to Enlarge
Click to Enlarge

 

Note that all objects are restored with the appropriate backlinks in place

 

Click to Enlarge
Click to Enlarge

 

I hope you have found this useful, can see why this is such a powerful feature of the R2 and gives you one more good reason to go for the upgrade.

What level is my Schema at ?

Sometimes you need to have your Schema at a certain level of Windows or may even want to check that a Schema upgrade is successful. One way to do this is to use ADSI Edit and connect to the Schema contect. Looking at the properties of the Schema node we can see the objectVersion attribute of the Schema. For Windows 2008 R2 this is 47.

 

Click to Enlarge
Click to Enlarge

The objectVersion attribute has the values below for different levels of Schema upgrades.

 

Schema Version Release of Windows
13 Windows 2000
30 Windows 2003
31 Windows 2003 R2
44 Windows 2008
47 Windows 2008 R2

 

Of course, there may be a level of risk in accessing objects with ADSI Edit so you want to query the schema version from a command prompt. To do so you can download the free AdFind tool from http://www.joeware.net/freetools/tools/adfind/index.htm and open up an administrative level command prompt (right click cmd.exe ad select “Run As Administrator”), change your path to where you have saved AdFind.exe to and then run the command

Adfind –schema –s base objectVersion

 

Click to Enlarge
Click to Enlarge