REMOVE DISABLE USERS From AD Groups
Answers (2)
I don't have a PS script but I do have a QAD VBScript. It shouldn't be beyond the wit of Man to convert. It looks for computer and user accounts but that behaviour is easy to change by editing the filter applied in the query:
Users only
strCommandText = strCommandText & "&(objectCategory=User)(samAccountType=805306368)"
strCommandText = strCommandText & "(userAccountControl:1.2.840.113556.1.4.803:=2)"
Machines only
strCommandText = strCommandText & "&(objectCategory=Computer)(samAccountType=805306369)"
strCommandText = strCommandText & "(userAccountControl:1.2.840.113556.1.4.803:=2)"
'On Error Resume Next
Dim strYear
Dim strMonth
Dim strDay
Dim strDateConst ADS_SCOPE_SUBTREE = 2
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
Const ADS_PAGE_SIZE = 100
Const ADS_TIMEOUT = 30Const adUseClientBatch = 3 '// Obsolete, same as adUseClient
Const adUseNone = 1 '// Obsolete, no cursor service
Const adUseServer = 2 '// Default, use the cursor supplied by provider or database
Const adUseClient = 3 '// Use client-side cursor supplied by the local cursor library
Const adOpenStatic = 3 '// Use static cursorDim strExcludeOUlist
Dim dtmTestDate'//------------------------------------------------------------------------------------------------------------//
'// Force use of CScript
'//------------------------------------------------------------------------------------------------------------//
Call ForceCScriptExecution(True)dtmTestDate = #16/03/2012# '// This is the date against which we're going to test.
'// It needs to be in US format so 6/1/2011 is 1st June 2011dtmTestDate = DateAdd("d", -90, Date())
strExcludeOUList = "Exchange" '// Exclude any account with an OU which includes this text
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 intIndex = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(intIndex) * 256^intIndex)
Next
End If
Set objShell = NothingSet objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.CursorLocation = adUseClientobjConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnectionWith objCommand
.Properties("SearchScope") = ADS_SCOPE_SUBTREE
.Properties("Page Size") = ADS_PAGE_SIZE
.Properties("Timeout") = ADS_TIMEOUT
.Properties("Cache Results") = False
End WithstrCommandText = ""
strCommandText = strCommandText & "<LDAP://" & strDNSDomain & ">"
strCommandText = strCommandText & ";"
strCommandText = strCommandText & "("strCommandText = strCommandText & "|(samAccountType=805306368)(samAccountType=805306369)"
strCommandText = strCommandText & "(userAccountControl:1.2.840.113556.1.4.803:=2)"'// Include any user who DOES NOT have an Exchange account defined
'strCommandText = strCommandText & "(!homeMDB=*)"'// Include any user who has an Exchange account defined
'strCommandText = strCommandText & "(homeMDB=*)"strCommandText = strCommandText & ")"
strCommandText = strCommandText & ";distinguishedName,sAMAccountName,Name,lastLogonTimeStamp;Subtree"'// Comma-delimited list of attribute values to retrieve
strAttributes = "distinguishedName,lastLogonTimeStamp"objCommand.CommandText = strCommandText
Set objRecordSet = objCommand.ExecuteWith objRecordSet
.MoveFirst.Sort = "Name asc"
WScript.Echo "Total number: " & .RecordCount
Do Until .EOF
'// Retrieve attribute values for the user
'strDN = .Fields("distinguishedName").Value'// Convert Integer8 value to date/time in current time zone
On Error Resume NextdtmLastLogonDate = ConvertInteger8ToDate(.Fields("lastLogonTimeStamp").Value, lngBias)
strName = .Fields("Name").Value
strsAMAccountName = .Fields("sAMAccountName").Value
strdistinguishedName = .Fields("distinguishedName").Value
'// The date needs to be in US format
'If (dtmLastLogonDate < #4/1/2011#) Then
If (dtmLastLogonDate < dtmTestDate) Then
'Wscript.Echo strName
'Wscript.Echo strsAMAccountName
If InStr(strdistinguishedName, strExcludeOUList) = 0 Then
'Wscript.Echo strsAMAccountName & "," & strdistinguishedName & ", Last logged on: " & dtmLastLogonDate
'Wscript.Echo strsAMAccountName & "," & strdistinguishedName & "," & dtmLastLogonDate
'// For display/data sorting purposes, we want this date in UK format
strYear = Year(dtmLastLogonDate)
strMonth = Month(dtmLastLogonDate)
strDay = Day(dtmLastLogonDate)
strDate = strDay & "/" & strMonth & "/" & strYear
Wscript.Echo strsAMAccountName & "|" & strdistinguishedName & "|" & strDate
End If
Else
'Wscript.Echo strDN & ";" & dtmLastLogonDate
End If.MoveNext
Loop
End WithFunction ConvertInteger8ToDate(ByVal objDate, ByVal lngBias)
'// Function to convert Integer8 (64-bit) value to a date,
'// adjusted for local time zone biasDim lngAdjust
Dim lngDate
Dim lngHigh
Dim lngLowlngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objDate.LowPart'// Account for bug in IADslargeInteger property methods
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End IfIf (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End IflngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) + lngLow) / 600000000 - lngAdjust) / 1440
ConvertInteger8ToDate = CDate(lngDate)
End FunctionSub ForceCScriptExecution(ByVal blnQuoteArguments)
Dim objShellRun
Dim strArgument
Dim strArguments
Dim strCmdLine
Dim intIndex'// If running in CScript, do nothing
If UCase(Right(WScript.FullName, 11)) = "CSCRIPT.EXE" Then
Exit Sub
End IfIf WScript.Arguments.Count > 0 Then
strArguments = ""
For intIndex = 0 To (WScript.Arguments.Count - 1)
If Len(strArguments) = 0 Then
strArguments = WScript.Arguments(intIndex)
Else
strArguments = strArguments & " " & WScript.Arguments(intIndex)
End If
NextIf blnQuoteArguments Then
strArguments = Chr(34) & strArguments & Chr(34)
End If
End If'// If running in WScript, execute the script using CScript
'// and then quit this script
If UCase(Right(WScript.FullName, 11)) = "WSCRIPT.EXE" Then
Set objShellRun = CreateObject("WScript.Shell")
'objShellRun.Run "CSCRIPT.EXE """ & WScript.ScriptFullName & """", 1, False
strCmdLine = "CSCRIPT.EXE "If InStr(WScript.ScriptFullName, " ") > 0 Then
strCmdLine = strCmdLine & Chr(34)
End If
strCmdLine = strCmdLine & WScript.ScriptFullNameIf InStr(WScript.ScriptFullName, " ") > 0 Then
strCmdLine = strCmdLine & Chr(34)
End If
If Len(strArguments) > 0 Then
strCmdLine = strCmdLine & " "
strCmdLine = strCmdLine & strArguments
End If
objShellRun.Run strCmdLine, 1, False
Set objShellRun = Nothing
WScript.Quit
End If'// If script engine is anything else, quit with an error
WScript.Echo "Unknown scripting engine."
WScript.Quit
End Sub
Finding group memberships is harder because you need to take account of nested memberships. Check out Mr Mueller's excellent VBSes. I have his code in scripts I use but it's surrounded by my "fluff" and would be hard to use straight out of the box, as it were.
EDIT:
Is there some reason that the scripts that one can find from Googling are of no use?!?