Gestione degli utenti inattivi su Windows 2003 Server

Oggi ho deciso di ripulire un po’ il dominio.
Ho scritto uno script che permette di
creare un report e/o di spostare gli account e/o di disattivare gli account
che non eseguono l’accesso al dominio (owa compresa) da un tempo
superiore a un numero di giorni
settabili a piacere.
Se può esservi utile, lo allego di seguito.
E’ uno script VBS
Saluti a tutti
Maurizio Proietti

 

 

'Option Explicit
'On Error Resume Next

'—— SCRIPT CONFIGURATION ——
'Creo un report? (si/no)
CreaReport = "si"
'Dove creo il report?
ReportFolder = "\\fs3\SW_PKG\ScriptGestione\Report\"
'ReportFileName = year(now())&"_"&month(now())&"_"&day(now())&".txt"
ReportFileName = year(now())&"_"&month(now())&"_"&day(now())&".csv"

'Sposto gli account UTENTE nella OU definita + sotto? (si/no)
MoveUsersAccount = "si"
'Sposto gli account COMPUTER nella OU definita + sotto? (si/no)
MoveComputersAccount = "no"

'Dove sposto gli account utente inattivi
MoveUsersToOU = "OU=Users,OU=z_InactiveAccount,DC=prvprato1,DC=local"
'Dove sposto gli account macchina inattivi
MoveComputersToOU = "OU=Computers,OU=z_InactiveAccount,DC=prvprato1,DC=local"

'Disabilito gli account? (si/no)
DisableUsersAccount = "si"
DisableComputersAccount = "no"

'Quanti giorni di inattività occorrono per spostare gli account e di conseguenza cancellargli la posta? (deve essere >= 15)
InactiveDaysToMoveAccounts = 90

'Quanti giorni di inattività occorrono per disabilitare gli account? (deve essere >= 15)
InactiveDaysToDisableAccounts = 45

'Dove ricerco
strDomainDN = "CN=Users,DC=prvprato1,DC=local"

'strDomainDN = "DC=prvprato1,DC=local
'strDomainDN = "CN=test3,CN=Users,DC=prvprato1,DC=local"
'strDomainDN = "OU=Users,OU=z_InactiveAccount,DC=prvprato1,DC=local"
'strDomainDN = "DC=prvprato1, DC=local"

' —— END CONFIGURATION ———

'Option Explicit

'——– Cerco e scrivo il lastLogonTimeStamp x utenti ———————

Const OPEN_FILE_FOR_APPENDING = 8

Dim objRootDSE, adoConnection, adoCommand, strQuery
Dim adoRecordset, strDNSDomain, objShell, lngBiasKey
Dim lngBias, k, strDN, dtmDate, objDate
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
Set objShell = Nothing

' Determine DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set objRootDSE = Nothing

' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Search entire domain.
'Nella ver originale c’era questo, ma a me interessa solo la CN=USERS
'strBase = ""
strBase = ""

' Filter on all user objects.
'strFilter = "(&(objectCategory=person)(objectClass=user))"
strFilter = "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "cn,distinguishedName,lastLogonTimeStamp"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 60
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

'Creo il report VUOTO
If (CreaReport = "si") Then
Dim objFileSystem, objOutputFile
Dim strOutputFile
strOutputFile = ReportFolder & ReportFileName
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.CreateTextFile(strOutputFile, TRUE)
objOutputFile.WriteLine("distinguishedName;" & "CN;" & "lastLogonTimeStamp;" & "InactiveDays;" & "Action;" & "operazioni eseguite")
objOutputFile.Close
Set objFileSystem = Nothing
End If

' Enumerate resulting recordset.
Do Until adoRecordset.EOF
LogAction = "0?
Action = "0?
' Retrieve attribute values for the user.
strDN = adoRecordset.Fields("distinguishedName").Value
strCN = adoRecordset.Fields("cn").Value
' Convert Integer8 value to date/time in current time zone.
On Error Resume Next
Set objDate = adoRecordset.Fields("lastLogonTimeStamp").Value
If (Err.Number <> 0) Then
On Error GoTo 0
dtmDate = #1/1/1601#
Else
On Error GoTo 0
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
If (lngLow < 0) Then lngHigh = lngHigh + 1 End If If (lngHigh = 0) And (lngLow = 0 ) Then dtmDate = #1/1/1601# Else dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _ + lngLow)/600000000 – lngBias)/1440 End If End If ' Display values for the user. InactiveDays = DateDiff("d", dtmDate, now) '———————– Sez disabilita utente ———————————————— If (DisableUsersAccount = "si") Then If (InactiveDays >= InactiveDaysToDisableAccounts) Then
'DISABILITO UTENTE
set objUser = GetObject("LDAP://" & strDN)
if (objUser.AccountDisabled = FALSE) then
LogAction = "Account disabled by script"
objUser.AccountDisabled = TRUE
objUser.SetInfo
else
LogAction = "Account già disabilitato"
end if
End If
set objUser = Nothing
End If
'—————— FINE DISABILITA UTENTE ———————–

'———————– Sez sposta utente ————————————————
If (MoveUsersAccount = "si") Then
If (InactiveDays >= InactiveDaysToMoveAccounts) Then
strObjectDN = "LDAP://" & strDN
strObjectRDN = "cn=" & strCN
'SPOSTO UTENTE
set objMoveUsersToOU = GetObject("LDAP://" & MoveUsersToOU)
objMoveUsersToOU.MoveHere strObjectDN, strObjectRDN
LogAction = LogAction & " – Account spostato dallo script"
End If
set objMoveUsersToOU = Nothing
End If
'—————— FINE SPOSTA UTENTE ———————–

'———————– Sez REPORT ————————————————
If (CreaReport = "si") Then
If (dtmDate = #1/1/1601#) Then
dtLastLogon= "Never"
Else
dtLastLogon = dtmDate
End If
If (InactiveDays >= InactiveDaysToDisableAccounts) Then
Action = "To Disable"
End If
If (InactiveDays >= InactiveDaysToMoveAccounts) Then
Action = "To Move and Delete emails"
End If
'Dim objFileSystem, objOutputFile
'Dim strOutputFile

' generate a filename base on the script name
strOutputFile = ReportFolder & ReportFileName

Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.OpenTextFile(strOutputFile, OPEN_FILE_FOR_APPENDING)
objOutputFile.WriteLine(strDN & ";" & strCN & ";" & dtmDate & ";" & InactiveDays & ";" & Action & ";" & LogAction)
objOutputFile.Close

Set objFileSystem = Nothing
End if
' ————————– FINE REPORT ———————————
adoRecordset.MoveNext

Loop

' Clean up.
adoRecordset.Close
adoConnection.Close
Set adoConnection = Nothing
Set adoCommand = Nothing
Set adoRecordset = Nothing
Set objDate = Nothing

Related Posts

2 thoughts on “Gestione degli utenti inattivi su Windows 2003 Server

  1. Anche se questo post ha anni ti scrivo per invitarti a controllare quello che pubblichi su internet (tra l’altro come “tuo”) visto che (a parte gli if aperti e non chiusi o altre dimenticanze) hai commentato gli “if” che abilitano o meno la movimentazione degli account, rendendo totalmente inutile mettere a “no” le variabili che, all’inizio dello script, abilitano tale azione. Fidandomi, e lanciato lo script con “no” a quelle variabili, e mi ha spostato 465 account che ho dovuto rimettere a posto manualmente basandomi sul log che ha creato. Permettimi una leggera alterazione. Ti consiglio di rimuovere questo script o di modificarlo in modo che faccia quello che prometti.

  2. Ti ringrazio per la segnalazione. E ho corretto gli errori.
    Ma avrei qualche appunto da farti….
    intanto non capisco perchè tu metta in dubbio che quello che ho scritto sia “mio”.
    Inoltre, come era facile intuire, non avevo VOLUTAMENTE comentato quelle righe, probabilmente il copia/incolla dall’editor di testi al blog ha fatto saltare qualche formattazione (così come aveva fatto saltare il corretto codice ascii delle virgolette e degli apici) e questo era facilmente comprensibile anche dalla presenza di endif senza il relativo if (se avessi voluto commentare gli if perchè avrei lasciato gli endif???). Inoltre hai modificato il codice senza chiederti cosa tu stessi facendo?
    Comunque ho modificato il post come mi hai giustamente fatto notare, e vorrei ricordare che il copia/incolla da internet senza neppure dare un’occhiata veloce al codice che lanci con privilegi amministrativi, non è molto professionale, soprattutto se hai la responsabilità di 465 account…
    Se invece che un banale errore di pubblicazione su internet il mio codice avesse introdotto una ben nascosta minaccia ai tuoi sistemi?
    Se nel codice ci fosse stata la creazione di un account con privilegi amministrativi che mi consentisse l’accesso al tuo dominio?
    Ognuno è libero di fare ciò che vuole, ma io il codice, prima di eseguirlo, lo leggo 🙂
    Cordiali saluti
    😉

Comments are closed.