?
Solved

Powershell script help required from a guru

Posted on 2014-08-27
12
Medium Priority
?
232 Views
1 Endorsement
Last Modified: 2014-09-02
Hello PowerShell Masters,

I do require from your expertise to build or provide a script to perform following AD cleanup tasks:

Delete the accounts that haven't logged on for last 6 months for a specific domain [Remove all disabled accounts not used for 6 months, and provide an option if the account is enabled to ask for verification before deleting the account]

Remove group membership for accounts to be deleted

Back up user SID's in AD

Ensure service accounts are not included [is this technically possible? if so or not, please provide details

There are project constraints and we want to make sure that we don't impact users due to the nature of how AD generates the last logon timestamp.[The lastlogontimestamp attribute is not updated with all logon types or at every logon. Which was a condition that was discovered for several of the accounts on the list we pulled out recently from AD]

Your help is highly appreciated
1
Comment
Question by:Jerry Seinfield
  • 6
  • 6
12 Comments
 
LVL 29

Expert Comment

by:becraig
ID: 40289139
Everything else you need can be done except for the service account piece unless you either:

1. Have service accounts with a specific naming convention
2. Have your service accounts in a specific OU.

If not I can script everything else but that piece.

You can do a two part approach (more overhead and time consuming)
Which is create an array from the list of accounts that match the lastlogon value then scan all your computers for  for the logon as value in the service database where the service is enabled, then simply remove those accounts from your list and proceed to delete the others.

The problem here will be the overhead involved based on the size of your organization.

Approx how many servers are we talking about that could have servers with service accounts active  ?
0
 

Author Comment

by:Jerry Seinfield
ID: 40289387
1. Yes, we do have a specific naming convention for service accounts. Each service account starts with SVC-name where name is the name of the application used. For example. SVC-Backups

2. Yes, all service accounts are member of an OU named Service Accounts under the child domain.

Please be aware that our organization has multiple forest with trust relationships and multiple child domains, so the script should be able to identify the forest, the domain and the OU where the accounts are hosted


We do have 2 Domain controllers servers for the root domain and two more for the child domain on each forest. We are talking about an organization of 6000 users.
0
 

Author Comment

by:Jerry Seinfield
ID: 40296983
Hi Becraig,

Do you have any updates? how is the script going so far?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 29

Expert Comment

by:becraig
ID: 40297030
So sorry I was a little busy I'll whip it together in a few minutes.
0
 
LVL 29

Accepted Solution

by:
becraig earned 2000 total points
ID: 40297169
I have made two separate scripts, one for disabled users and one for users enabled but not logged in for 195 days (180 + the ~15 day recommended margin)

$time = (Get-Date).Adddays(-(195))
$delreport = @()
#first step Removing all disabled users not logged in for more than 195 days 
Get-ADuser -filter * | where {$_.Enabled -eq $false -and $_.Name -notlike "SVC_*" -and $_.LastLogonTimeStamp -lt $time} | % {
$user = $_.Name
$grps = ($_.memberof | Get-ADGroup | Select -ExpandProperty Name)
#Remove users from groups
$grps | % {
            Remove-ADGroupMember -Identity $_ -Member $user -whatif
          }

#Remove user from AD
Remove-AdUser -Identity $user -whatif

#create csv report
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'FNAME' -Value $_.GivenName
$item | Add-Member -type NoteProperty -Name 'LNAME' -Value $_.Surname
$item | Add-Member -type NoteProperty -Name 'USERNAME' -Value $_.samaccountname
$item | Add-Member -type NoteProperty -Name 'USERSID' -Value $_.SID
$delreport += $item
}

$delreport | export-csv report.csv -nti

                        
                        
                 

Open in new window

     
$time = (Get-Date).Adddays(-(195))
$delreport = @()
#first step Removing all disabled users not logged in for more than 195 days 
Get-ADuser -filter * | where {$_.Enabled -eq $true -and $_.Name -notlike "SVC_*" -and $_.LastLogonTimeStamp -lt $time} | % {
$user = $_.Name
$grps = ($_.memberof | Get-ADGroup | Select -ExpandProperty Name)
$conf = Read-Host "Are you sure you want to delete user: $user"
#Remove users from groups
#Remove user from AD
switch ($conf)
{
"Y" {
$grps | % {
            Remove-ADGroupMember -Identity $_ -Member $user -whatif
          }
Remove-AdUser -Identity $user -whatif
}
"N" {}
}
#create csv report
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'FNAME' -Value $_.GivenName
$item | Add-Member -type NoteProperty -Name 'LNAME' -Value $_.Surname
$item | Add-Member -type NoteProperty -Name 'USERNAME' -Value $_.samaccountname
$item | Add-Member -type NoteProperty -Name 'USERSID' -Value $_.SID
$delreport += $item
}

$delreport | export-csv Enabled-userdelete.csv -nti

Open in new window

0
 

Author Comment

by:Jerry Seinfield
ID: 40297640
Thanks Becraig,

I guess the what if senteces prevent the deletion until we are sure the script works fine

Is there a way to include a line to export all users accounts that will be deleted on a spreadsheet but without taking any action and validate that those are the correct accounts?

I would like to pull out all the accounts that will be deleted first , validate and then run the scripts again and delete all the accounts once all information is verified
0
 
LVL 29

Expert Comment

by:becraig
ID: 40297656
The whatif prevents deletion and the end of each script actually pipes the output to a report.


The first script is for users already disabled and the second for enabled users not logged in for more than 180 days

You can comment out the lines doing the remove if you just want the report.
0
 

Author Comment

by:Jerry Seinfield
ID: 40298322
can you be more specific? which line needs to be modified only to get the report of users to be deleted?  I need the report of accounts to be deleted, then I will manually validate this information, then need to delete the accounts

Can you please provide the exact lines to be modified for each case?
0
 

Author Comment

by:Jerry Seinfield
ID: 40298687
Are you there Becraig?
0
 
LVL 29

Expert Comment

by:becraig
ID: 40298706
For Enabled users:
$time = (Get-Date).Adddays(-(195))
$delreport = @()
#first step Removing all disabled users not logged in for more than 195 days 
Get-ADuser -filter * | where {$_.Enabled -eq $true -and $_.Name -notlike "SVC_*" -and $_.LastLogonTimeStamp -lt $time} | % {
$user = $_.Name
#create csv report
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'FNAME' -Value $_.GivenName
$item | Add-Member -type NoteProperty -Name 'LNAME' -Value $_.Surname
$item | Add-Member -type NoteProperty -Name 'USERNAME' -Value $name
$item | Add-Member -type NoteProperty -Name 'USERSID' -Value $_.SID
$delreport += $item
}
$delreport | export-csv Enabled-userdelete.csv -nti

Open in new window

                                         


For disabled users:

$time = (Get-Date).Adddays(-(195))
$delreport = @()
#first step Removing all disabled users not logged in for more than 195 days 
Get-ADuser -filter * | where {$_.Enabled -eq $false -and $_.Name -notlike "SVC_*" -and $_.LastLogonTimeStamp -lt $time} | % {
$user = $_.Name
#create csv report
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'FNAME' -Value $_.GivenName
$item | Add-Member -type NoteProperty -Name 'LNAME' -Value $_.Surname
$item | Add-Member -type NoteProperty -Name 'USERNAME' -Value $name
$item | Add-Member -type NoteProperty -Name 'USERSID' -Value $_.SID
$delreport += $item
}
$delreport | export-csv Disabled-report.csv -nti

Open in new window

0
 

Author Comment

by:Jerry Seinfield
ID: 40299646
Any ideas on why the spreadsheet did not return any information? The file is blank
Enabled-userdelete.csv
0
 
LVL 29

Expert Comment

by:becraig
ID: 40299653
It is quite possible you do not have any enabled users who are not SVC accounts who have not logged in for longer than 6 months.

Does the disabled report produce any results ?
0

Featured Post

Who's Defending Your Organization from Threats?

Protecting against advanced threats requires an IT dream team – a well-oiled machine of people and solutions working together to defend your organization. Download our resource kit today to learn more about the tools you need to build you IT Dream Team!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post, I will showcase the steps for how to create groups in Office 365. Office 365 groups allow for ease of flexibility and collaboration between staff members.
I’m willing to make a bet that your organization stores sensitive data in your Windows File Servers; files and folders that you really don’t want making it into the wrong hands.
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

609 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question