Powershell script help required from a guru

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
Jerry SeinfieldAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

becraigCommented:
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
Jerry SeinfieldAuthor Commented:
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
Jerry SeinfieldAuthor Commented:
Hi Becraig,

Do you have any updates? how is the script going so far?
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

becraigCommented:
So sorry I was a little busy I'll whip it together in a few minutes.
0
becraigCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jerry SeinfieldAuthor Commented:
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
becraigCommented:
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
Jerry SeinfieldAuthor Commented:
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
Jerry SeinfieldAuthor Commented:
Are you there Becraig?
0
becraigCommented:
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
Jerry SeinfieldAuthor Commented:
Any ideas on why the spreadsheet did not return any information? The file is blank
Enabled-userdelete.csv
0
becraigCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.