Skip to main content

How to change the logon hours of all the members of a security group with PowerShell

For this exercise, we are going to have to use the Active Directory module of PowerShell.  You will need to execute this in a PowerShell session or ISE running on a Windows Server 2008 R2 server or a Windows 7 client with RSAT installed.

Import-Module ActiveDirectory


I have already set up a security group called Astronauts_GG.  The members of this group are Neil Armstrong, Gus Grissom, Sally Ride, and David Wolf

Out next step is to be able to enumerate all the members of this group.  To do this, type:


Get-ADGroupMember –Identity Astronauts_GG

You will see each user object listed for each member of the group.

Specifying the logon hours is going to be a bit more complex.  Let’s take a look at the logon hours for a user from Active Directory Users and Computers. 

Right click a user account and select Properties 

Click the Account tab. 

Now click the Logon Hours… button.  Below is an image of the logon hours graphic:

image

In order to use PowerShell to configure the logon hours, we need to break the each of the 7 days down into 3 blocks of 8 hours.  We then need to divide each block into 8.

image

The above image represents the division of each day into 3 blocks of 8 hours.  The numbers represent how we will address each block.  Notice that the final block is labeled as '0’ and not ‘21’. 
As for breaking down each block into 8 separate hours, we are going to have to turn to binary math.  In this case each block is equal to one binary number.  The set of 8 blocks is equal to 1 byte.  In this scenario, the lowest order bit will be to the left.  for example, let set the hours of block #1 to be 12AM, 4AM, 5AM  and 7AM.

Time 12AM 1 AM 2 AM 3 AM 4 AM 5 AM 6 AM 7AM
Set ##### ##### ##### #####
Binary 1 2 4 8 16 32 64 128
Add 1 16 32 128

We can see here that if we want to assign this block the times of 12AM, 4AM, 5AM, and 7AM, we will need to add the numbers 1 + 16 + 32 + 128 = 177.  The number 177 is what we will submit to block #1.  Below is the code to do this.  I have to credit the help file for the cmdlet Set-ADUser for the code.  Take a look at example #6 in the help file got Set-ADUser..

$hours = New-Object byte[] 21
$hours[1] = 177
$ReplaceHashTable = New-Object HashTable
$ReplaceHashTable.Add(“logonHours”, $hours)
Set-ADUser “username"” –Replace $ReplaceHashTable

The original task was to set the logon hours by security group.  Here is the code to do it.


$hours = New-Object byte[] 21
$hours[1] = 177
$ReplaceHashTable = New-Object HashTable
$ReplaceHashTable.Add(“logonHours”, $hours)
Get-ADGroupMember –Identity Astronauts_GG | Set-ADUser –Replace $ReplaceHashTable

Line 1 creates a variable holding a new object of the type byte.  A byte is a computer term meaning 8 bits or a binary number that has 8 numerical places.  It also creates an array of byte with 21 cells in the array.

Line 2 set the number we calculated, 177, into the first time set.  We can add additional logon hours by adding extra lines.  For example, we can add $hour[3] = 255.  This will enable the user to log in from 4PM – 12AM on Sunday.

Line 3 creates a new object called a hash table.  A hash table allows you to create a table that will be the values of a property.

Line 4 adds the hash table to the property logonHours

Line 5 first enumerates all the user objects who are members of the group Astronauts_GG. It then passes this output to the next command using the pipe ‘|’ character.  Now the output becomes the input.  We use the –Replace function to completely remove the current logon hours and replace them with the contents of $ReplaceHashTable.

The final Logon Hours table looks like this:

image

Comments

Popular posts from this blog

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.

How to run GPResult on a remote client with PowerShell

In the past, to run the GPResult command, you would need to either physically visit this client, have the user do it, or use and RDP connection.  In all cases, this will disrupt the user.  First, you need PowerShell remoting enabled on the target machine.  You can do this via Group Policy . Open PowerShell and type this command. Invoke-Command –ScriptBlock {GPResult /r} –ComputerName <ComputerName> Replace <ComputerName> with the name of the target.  Remember, the target needs to be online and accessible to you.

Error icon when creating a GPO Preference drive map

You may not have an error at all.  Take a look at the drive mapping below. The red triangle is what threw us off.  It is not an error.  It is simply a color representation of the Replace option of the Action field in the properties of the drive mappings. Create action This give you a green triangle. The Create action creates a new mapped drive for users. Replace Action The Replace action gives you a red triangle.  This action will delete and recreate mapped drives for users. The net result of the Replace action is to overwrite all existing settings associated with the mapped drive. If the drive mapping does not exist, then the Replace action creates a new drive mapping. Update Action The Update action will have a yellow triangle. Update will modify settings of an existing mapped drive for users. This action differs from Replace in that it only updates settings defined within the preference item. All other settings remain as configured on the mapped drive. If the