Jump to content

Recommended Posts

Posted

Hi,

 

I have found a very handy powershell script to disable inactive user accounts. It works just how i want it apart from one thing. When an account is disabled its supposed to put in the description "Account Disabled on for Inactivity". But there its supposed to put the date its failing and just leaving a white space.

 

Can anyone help please?

 

Thanks

 

### User Variables ###

# Query Options #
$searchRoot = "domain.local/" # Where to begin your recursive search - If you use top-level (e.g. "domain.local/") make sure to have a trailing slash, otherwise do not use a slash (e.g. "domain.local/Users")
$inactiveDays = 90 # Integer for number of days of inactivity (e.q. 90)
$timeSinceCreation = 30 # Integer for number of "grace" days since the account was created (to prevent disabling of brand new accounts)
$sizeLimit = 0 # How many users do you want returned. 0 = unlimited. Without setting this the default is 1000

# Email Settings #
$emailAlerts = 1 # Turn e-mail alerts on or off. 0 = off
$fromAddr = "[email protected]" # Enter the FROM address for the e-mail alert
$toAddr = "[email protected]" # Enter the TO address for the e-mail alert
$smtpsrv = "192.168.1.1" # Enter the FQDN or IP of a SMTP relay

# Enable Script #
$enableAction = 1 # Change to 0 if you want to "whatif" this script - It will bypass the actual account disabling (turn e-mail alerts on!)

######################

Add-PSSnapin "Quest.ActiveRoles.ADManagement"

$creationCutoff = (Get-Date).AddDays(-$timeSinceCreation)
$inactiveUsers = @(Get-QADUser -SearchRoot $searchRoot -Enabled -NotLoggedOnFor $inactiveDays -CreatedBefore $creationCutoff -SizeLimit $sizeLimit | Select-Object Name,SamAccountName,LastLogonTimeStamp,Description | Sort-Object Name)

### Disable Accounts ###
if ($enableAction -eq 1 -and $inactiveUsers -ne $null){
foreach($user in $inactiveUsers){
Set-QADUser $user.SamAccountName -Description "Account Disabled on $date for Inactivity - $($user.Description)" | Disable-QADUser
}
}
######

### Email Alerts ###
if ($emailAlerts -eq 1 -and $inactiveUsers -ne $null){

$date = Get-Date -DisplayHint Date

$body = @("

NameAccountLast Login")

$i = 0

do {
if($i % 2){$body += "$($inactiveUsers[$i].Name)$($inactiveUsers[$i].SamAccountName)$($inactiveUsers[$i].LastLogonTimestamp)";$i++}
else {$body += "$($inactiveUsers[$i].Name)$($inactiveUsers[$i].SamAccountName)$($inactiveUsers[$i].LastLogonTimestamp)";$i++}
}
while ($inactiveUsers[$i] -ne $null)

$body += ""

Send-MailMessage -To $toAddr -From $fromAddr -Subject "Info: $($inactiveUsers.Count) User Accounts Disabled on $date" -Body "$body" -SmtpServer $smtpsrv -BodyAsHtml
}
######

exit

Posted
I'm no powershell expert, so don't know exactly how it all works but try moving the "$date = ..." line higher up, preferably above the active code, so you could put it at the bottom of all the user variables. That way it will be populated before it's used.
  • Thanks 1
Posted (edited)

:doh: your are correct thats fixed it. One thing is that is shows the exact time as well. It really inst needed do you happen to know how to get it to display only the date? Also It show the date in American format, do you know how to switch it to the British way please?

 

Thanks

Edited by FN-GM
Posted
:doh: your are correct thats fixed it. One thing is that is shows the exact time as well. It really inst needed do you happen to know how to get it to display only the date? Also It show the date in American format, do you know how to switch it to the British way please?

 

Thanks

 

You can use the -format switch on the Get-Date cmdlet to format the output. e.g.

 

Get-Date -format "d/M/yyyy"

 

For details of the format specifiers for Get-Date, take a look here: Windows PowerShell Tip: Formatting Dates and Times

 

Iain.

  • Thanks 1
Posted
how to switch it to the British way please?

A bit late, but here are a few more examples...

 

29-01-2012

[DateTime]::Now.ToString("dd-MM-yyyy")

 

29/01/2012

[DateTime]::Now.ToShortDateString()

 

 

 

For details of the format specifiers for Get-Date, take a look here: Windows PowerShell Tip: Formatting Dates and Times

To quickly see what all of the date/time letters from that link do, try running this...

 

ForEach ($format in "d","D","f","F","g","G","m","r","s","t","T", "u","U","y","dddd, MMMM dd yyyy","M/yy","dd-MM-yy") { "$format`: {0}" -f (Get-Date).ToString($format) }

 

This is what you should get...

 

d: 29/01/2012
D: 29 January 2012
f: 29 January 2012 09:15
F: 29 January 2012 09:15:56
g: 29/01/2012 09:15
G: 29/01/2012 09:15:56
m: 29 January
r: Sun, 29 Jan 2012 09:15:56 GMT
s: 2012-01-29T09:15:56
t: 09:15
T: 09:15:56
u: 2012-01-29 09:15:56Z
U: 29 January 2012 09:15:56
y: January 2012
dddd, MMMM dd yyyy: Sunday, January 29 2012
M/yy: 1/12
dd-MM-yy: 29-01-12

 

Then simply replace the letter after the colon with whichever one you want from the list above... :)

 

"{0:[color="#FF0000"]g[/color]}" -f (Get-Date)

Posted (edited)

I forgot to mention one of the best tips I have found so far regarding the date. As you may know, once a variable has been calculated, it doesn't change from that point on. Therefore, if you get the current date and time at the beginning of your script, it will have changed by the time you actually go to use it in another cmdlet further on.

 

If you would like to re-calculate the $date variable every single time it is used, try this instead...

 

$global:date = Set-PSBreakpoint -Variable date -Mode Read -Action { $global:date = "{0:F}" -f (Get-Date) }

 

http://i.imgur.com/8tHsz.png

Edited by Arthur
  • Thanks 2
Posted

Thanks for the input. What would i need to do with the script I posted to make this now do the same for computer accounts please?

 

Thanks

Posted

Thanks. I had seen that, but the one here does exactly what I want. It will add a note on the account, I can drill down to a particular ou and get it to email me a report.

 

That's why I want to try and convert this one :-)

 

Thanks

Posted

I take it you read my pedantic comments in your related thread?? Not a huge deal but nevertheless something you should be aware of when doing anything based on when a user/computer last logged on, especially if it's a scheduled task that makes changes based on the result.

 

--

 

More broadly: Perhaps it's just what turns up at the top of Google searches but I don't get why QAD keeps getting used for things like this rather than the out-of-box MS ActiveDirectory module on 2008 R2. Then again I get around a bit, so regardless of which might be easiest I will always pick tech that will be there are opposed to tech that might need installing. It's just as easy with MS in this case with their Get-ADUser or alternatively there is Search-ADAccount that can pull out inactive computer/user accounts based on a fixed date or timespan e.g. 90 days, that could then be thrown at Disable- or (don't do it!) Remove- cmdlets.

Posted
I take it you read my pedantic comments in your related thread?? Not a huge deal but nevertheless something you should be aware of when doing anything based on when a user/computer last logged on, especially if it's a scheduled task that makes changes based on the result.

 

I have got this in my mind. I have read a few posts on the net that say you can increase the replication rate of this. Unless i can adapt the script to look at all DC's?

 

More broadly: Perhaps it's just what turns up at the top of Google searches but I don't get why QAD keeps getting used for things like this rather than the out-of-box MS ActiveDirectory module on 2008 R2. Then again I get around a bit, so regardless of which might be easiest I will always pick tech that will be there are opposed to tech that might need installing. It's just as easy with MS in this case with their Get-ADUser or alternatively there is Search-ADAccount that can pull out inactive computer/user accounts based on a fixed date or timespan e.g. 90 days, that could then be thrown at Disable- or (don't do it!) Remove- cmdlets.

 

Sorry i dont understand you, please can you elaborate? Thanks

Posted
I take it you read my pedantic comments in your related thread?? Not a huge deal but nevertheless something you should be aware of when doing anything based on when a user/computer last logged on, especially if it's a scheduled task that makes changes based on the result.

 

Looking at this page the lastLogontimeStamp attribute is replicated to all DC's in real time. My script uses this time stamp (i think). The lastLogon attribute that i think your talking about replicates every 9 - 14 days. So i should be safe. Do you agree?

 

Thanks

Posted

Look again...

 

- lastLogon gets updated every time on the DC where the logon happens but that doesn't replicate.

- lastLogonTimestamp only gets updated when the a logon happens if the current value is more than 9-14 days old. If it is changed that new value does replicate.

 

Your script uses lastLogonTimestamp and a 90 day timespan thus risks picking up some users who in the worst case, last logged on 76 days ago. They're still old and for this kind of thing it's not often an issue.. if you want to guarantee "at least 90 days old" then just use a 104 day timespan instead of 90.

 

OTOH if you're running this daily and must get accounts as soon as they hit 90 days old you will need to look at lastLogon on all the DCs and check the age of the freshest one.

Posted

Depends on what you want to do. Whenever I've set about finding old users or computers I haven't cared about precision, so I'd be happy to use LastLogonTimestamps more than say 100 days old and not worry if that sometimes gets a few accounts that actually last logged on 84-100 days ago coz they're old too.

 

Chasing round for the freshest LastLogon is the kind of thing I'd do if I wanted to know if someone (or a computer) logged on recently e.g. this morning, yesterday etc.,

  • Thanks 1
Posted

Would you know how to make the script chase around please? I assume it would be allot of work?

 

I may Google to see if there is a way to increase the replication period or if there is a way to force the attribute to replicate then run the script. What are your thoughts please?

 

Thanks for your help.

Posted

Can you just confirm i have got something correct.

 

When the users logs on, it will check the DC to see if the timestamp is older than 14 days. If it is older than 14 days it updates it with a new one. If it is under 14 it ignores it. Because of this you wont end up with this scenario:

 

On July 2, the script disables account_A. On July 4, the admin enables the account so that account_A can log in. On July 9, the script runs again and the account is disabled again.

 

Thanks

Posted
I may Google to see if there is a way to increase the replication period or if there is a way to force the attribute to replicate then run the script.

Have you seen this? :confused:

 

“The LastLogonTimeStamp Attribute” – “What it was designed for and how it works” « Ask the Directory Services Team

 

If you need more accuracy, you could query the event logs...

 

It is important to note that the intended purpose of the lastLogontimeStamp attribute to help identify inactive computer and user accounts. The lastLogon attribute is not designed to provide real time logon information. With default settings in place the lastLogontimeStamp will be 9-14 days behind the current date.

 

If you are looking for more “real-time” logon tracking you will need to query the Security Event log on your DC’s for the desired logon events i.e. 528 –Windows XP/2003 and earlier or 4624 Windows Vista/2008. See this blog post by Eric Fitzgerald for more info. (I think he knows something about auditing)

 

IMO your best bet for near real-time data is to use an event log collection service to gather all domain controller security event logs to a centralized database. You can then query a single database for the desired logon events. Microsoft’s solution for security event log collection is Audit Collection Services. There are many 3rd party solutions as well.

Posted
Thanks for the input. What would i need to do with the script I posted to make this now do the same for computer accounts please?

 

Thanks

 

 

Does anyone have any suggestions regarding this please?

 

Thanks

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...