Sign in to follow this  
Followers 0
bourny

Ad inactive machines

61 posts in this topic

i am writing a script to manage my computers in active directory . i will be moving them around OU`s based on the IP address DNS has them assigned to. This appears to pull out computers that have no IP address since DHCP has released the address for that machine due to the machine not connecting to the network for a while.

This is where my question begins. Is there a way to pull an attribute from AD to find out when the last time the machine connected to the network. If the machine has not connected for a few months I want to isolate this in a different OU for inactive machines.

I have the script for everything but pulling the attribute from AD for the last time it had been on the network..

Many thanks

Share this post


Link to post
Share on other sites



Have a look at http://www.microsoft.com/technet/scriptcen.../lastlogon.mspx. This article explains how to calculate the last logon time.

At http://www.autoitscript.com/forum/index.ph...st&p=422402 you'll find a script that converts the lastlogontimestamp to a readable format.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

if you have xp or 2003 server machine you can use: dsquery computer -inactive <weeks>. This shows you inactive computeraccounts and you may filter or script them.

Move all machines which are inactive for 12 weeks on Domain yourdomain.local into OU Inactive:

dsquery computer -inactive 12 |dsmove -newparent OU=Inactive,dc=yourdomain, dc=local

you may have to use parameter -limit. see dsquery computer /?

;-))

Stefan

Share this post


Link to post
Share on other sites

99ojo - I dont have a 2003 domain unfortunatly but thanks for that.

Water -

Have a look at http://www.microsoft.com/technet/scriptcen.../lastlogon.mspx. This article explains how to calculate the last logon time.

At http://www.autoitscript.com/forum/index.ph...st&p=422402 you'll find a script that converts the lastlogontimestamp to a readable format.

I have looked at both articles - the AutoIt article appears to claim there is a set of code that will do this job but I have looked at the code and tried it - (Placed the correction into what I think is the right place) but it does not work. It looks to me as if I dont need the VBS as the AutiIt coder appears to have managed to get it working and has converted it... Here is my attempt at his code ... Obviously doing something wrong

The Error I get from the below is :

$objRecordSet = $objCommand.Execute

$objRecordSet = $objCommand.Execute^ ERROR

[/code]
Dim $objShell
Dim $objEnv
Dim $CompEnv0
Dim $Description

$objShell = ObjCreate("Wscript.Shell")
$objEnv = $objShell.Environment("Process")
$CompEnv0 = StringLeft($objEnv("COMPUTERNAME"), 4)

GetSiteDescription ("MyDom.co.uk")
MsgBox(0,"",$Description)

Func  GetSiteDescription($sLongDomainName)
  Dim $objConnection, $objCommand, $arrFQDN, $objRecordSet, $objOU
  
  $objConnection = ObjCreate("ADODB.Connection")
  $objConnection.Open("Provider=ADsDSOObject;")

  $objCommand = ObjCreate("ADODB.Command")
  $objCommand.ActiveConnection = $objConnection
  $arrFQDN=StringSplit($sLongDomainName,".")

  $objCommand.CommandText = "<LDAP://OU=LOCATIONS,OU=DEPT" & ",DC=" & $arrFQDN[1] & ",DC=" &  $arrFQDN[2] & ",DC=" & $arrFQDN[3] & ">;(&(objectCategory=organizationalunit)(name=*"& $CompEnv0 &"));Name,distinguishedName,description;subtree"
  
  $objRecordSet = $objCommand.Execute

 ;$objOU = ObjGet("LDAP://" & $objRecordSet.Fields("distinguishedName"))
 ;$Description=$objOU.Get("description")
 ;$objConnection.Close
;Return $Description
  
 ;--------------------Added in Ammended script and remmed out 2 lines above 
 ;$objRecordSet = $objCommand.Execute
  $DistListing = $objRecordSet.Fields("DistinguishedName").value
  $objConnection.Close

  $objDescription = ObjGet("LDAP://"& $DistListing)
  $Description = $objDescription.description
  Return $Description = $objDescription.description
  

  
EndFunc

[code]

Share this post


Link to post
Share on other sites

if you have xp or 2003 server machine you can use: dsquery computer -inactive <weeks>. This shows you inactive computeraccounts and you may filter or script them.

Move all machines which are inactive for 12 weeks on Domain yourdomain.local into OU Inactive:

dsquery computer -inactive 12 |dsmove -newparent OU=Inactive,dc=yourdomain, dc=local

you may have to use parameter -limit. see dsquery computer /?

;-))

Stefan

it works on w2k domains as well.

;-))

Share this post


Link to post
Share on other sites

it works on w2k domains as well.

;-))

When I run this Query it tells me the Query does not work because you are connected to a domain that does not support this query.

I am running "DSQuery Computer -inactive 5"

Share this post


Link to post
Share on other sites

When I run this Query it tells me the Query does not work because you are connected to a domain that does not support this query.

I am running "DSQuery Computer -inactive 5"

set on client HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AdminDebug\ADsOpenObjectFlags to 0x03. it will stop crypting and signing ldap traffic.

Share this post


Link to post
Share on other sites

set on client HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AdminDebug\ADsOpenObjectFlags to 0x03. it will stop crypting and signing ldap traffic.

I have added the Dword and rebooted but does not get around - same error

Share this post


Link to post
Share on other sites

I have added the Dword and rebooted but does not get around - same error

which servicepack is on your w2k domain controller?

Share this post


Link to post
Share on other sites

which servicepack is on your w2k domain controller?

SErvice Pack 4 ....

Not to be rude I appreciate your help but I cannot change my domain controllers to suit this script .... I am Very intersted in how to get the script pointed out earlier to work ....I think this is going off on a tangent now...

Share this post


Link to post
Share on other sites

As the lastlogin attribute is not synchronized between AD controllers you'll have to query each AD controller for this attribute and calculate the most current.

See this link


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

As the lastlogin attribute is not synchronized between AD controllers you'll have to query each AD controller for this attribute and calculate the most current.

See this link

So when I look at the script provided in the http://www.autoitscript.com/forum/index.ph...st&p=422402 appears to have got this working does this mean it may not work as it appears to query the domain not an individual DC - Have I picked you up right

I think I am lost now -.....

I suppose my question is - is there a way to do this in AutoIt or will I have to give this up as a bad job. Object scripting is out of my knowledge at the moment so I am stuck to trying to understand the object scripts in this forum but clearly failing to pick up what need to be done

Share this post


Link to post
Share on other sites

I appear to have got it working using an example script in the link you provided and as it states you have to have the correct DC to get the inmformation ..... Shame there is no way of knowing without going thru all the DC`s which on logged the computer / user on

Thanks water

Share this post


Link to post
Share on other sites

I appear to have got it working using an example script in the link you provided and as it states you have to have the correct DC to get the inmformation ..... Shame there is no way of knowing without going thru all the DC`s which on logged the computer / user on

Thanks water

maybe you should query the age of the password. all computers change their computer password. this is replicated all over the domain, so you have to query only one dc. you may use the tool netpwage to query and pipe into a textfile to work with.

;-))

Share this post


Link to post
Share on other sites

maybe you should query the age of the password. all computers change their computer password. this is replicated all over the domain, so you have to query only one dc. you may use the tool netpwage to query and pipe into a textfile to work with.

;-))

Thanks again for your suggestions 99ojo. I am happy with the script I have now got together - I will simply put the script into a function and spam it with the name of all my DC`s until I get a logon date or an answer to if the CN has never logged on or does not exist. This is simple to do - The hard part is getting a script to actually pull out the date which I now have with the help of the forum.

Thanks again 99ojo - you demonstrate a good knowledge of Ad tools but in this case I want to get AutoIt to do this all in one script without having to bring in external tools that simply bring more scope for issues out of my scripts control.

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

The following example script (based on adfunctions.au3) queries all domain controllers and returns the true last login time

for computer PCTS29 (the sAMAccountName for a computer is the comptuername followed by a dollar sign).

The get the true last login for a user just use @username or the sAMAccountName of the desired user.

Global $objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD
$objConnection.ConnectionString = "Provider=ADsDSOObject"
$objConnection.Open("Active Directory Provider") ; Open connection to AD

Global $objRootDSE = ObjGet("LDAP://RootDSE")
Global $strDNSDomain = $objRootDSE.Get("defaultNamingContext") ; Retrieve the current AD domain name
Global $strHostServer = $objRootDSE.Get("dnsHostName") ; Retrieve the name of the connected DC
Global $strConfiguration = $objRootDSE.Get("ConfigurationNamingContext") ; Retrieve the Configuration naming context
Global $objOpenDS = ObjGet("LDAP:")

Global $DCList, $LastLogin=0
_ADListDomainControllers($DCList)

For $i =1 to $DCList[0]
    $sTmp = StringSplit($DCList[$i],",")
    $sTmp = StringSplit($sTmp[1],"CN=",1)
    $sTmp = _GetLogin($sTmp[2],"PCTS29$")
    If $sTmp > $LastLogin Then $LastLogin = $sTmp
Next
ConsoleWrite($LastLogin)    

Func _GetLogin($strHostServer,$sAMAccountName)
    
    $strQuery = "<LDAP://" & $strHostServer & "/" & $strDNSDomain & ">;(sAMAccountName=" & $sAMAccountName & ");ADsPath;subtree"
    $objRecordSet = $objConnection.Execute($strQuery) ; Retrieve the FQDN for the object
    $ldap_entry = $objRecordSet.fields(0).value
    $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object
    $result = $oObject.LastLogin
    $oObject.PurgePropertyList
    
    If $result = "" Then
        Return ""
    Else
        Return $result
    EndIf
    
EndFunc

; _ADListDomainControllers
; Retrieves the names of all domain controllers in the current Domain
Func _ADListDomainControllers(ByRef $DCList)
    $objCommand = ObjCreate("ADODB.Command")
    $objCommand.ActiveConnection = $objConnection
    $objCommand.Properties("Page Size") = 1000
    $objCommand.Properties("Searchscope") = 2
    
    $objCommand.CommandText = "Select distinguishedName FROM 'LDAP://" & $strHostServer & "/ou=Domain Controllers," & $strDNSDomain & "' WHERE objectclass='computer'"
    
    $objRecordSet = $objCommand.Execute
    Dim $DCList[$objRecordSet.RecordCount + 1]
    $objRecordSet.MoveFirst
    
    Do
        $DCList[0] += 1
        
        $objCommand.CommandText = "<LDAP://" & $strHostServer & "/" & $objRecordSet.Fields("distinguishedName" ).Value & ">;;serverReferenceBL;Range=0-*;base"
        $objRecSet2 = $objCommand.Execute
        
        $objRecSet2.MoveFirst
        Do
            $temparray = $objRecSet2.Fields(0).Value
            $DCList[$DCList[0]] = $temparray[0]
            $objRecSet2.MoveNext
        Until $objRecSet2.EOF
        
        $objRecordSet.MoveNext
    Until $objRecordSet.EOF
    
    $objCommand = 0
    $objRecordSet = 0
    Return
EndFunc   ;==>_ADListDomainControllers
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

For the benefit of everyone here is my completed script I have for scanning all my domain controllers for the last logged on date

[/code]
#include <Date.au3>
#include <array.au3>

Dim $LogonInfo[3]
$LogonInfo[0] = "Not Found"
$ArrayOfDcs = _ArrayCreate("l2dc8", "dc1", "dc2", "dc3", "dc4", "dc10", "dc9")
$OUtoScan = "OU=redundant,OU=Client Computers";;;;; This will need to be the full path e.g cn="laptops,cn=Computer Accounts,cn="RootOU" 
$ObjectToLookFor = "cn=BBTest"

$LogonInfo = ScanForObject($ArrayOfDcs, $OUtoScan, $ObjectToLookFor)

Select 
    Case $LogonInfo[0] = "Error" 
        MsgBox(0, "Failed to find Last Logged on date", "Checked All Dc`s and failed to find the object / last logged on date")
    Case $LogonInfo[0] = "Never"
        MsgBox(0, "Completed Scan", "The object specified has never logged onto any DC yet....")
    Case $LogonInfo[0] = "Found" 
        MsgBox(0, "Completed Scan", "Found the following...." & @lf & _
        "Last logged on = " & $LogonInfo[1] & @lf & _
        "Domain Controller = " & $LogonInfo[2])
        
    Case Else
        MsgBox(0, "Failed to find Last Logged on date", "Checked All Dc`s and failed to find the object / last logged on date")
        
EndSelect


Func ScanForObject($ArrayOfDcs, $OUtoScan, $ObjectToLookFor)
    
    For $DC IN $ArrayOfDcs
        
        dim $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
        
        dim $sServer = $DC & ".MYDOM.co.uk"
        dim $sUserPath = $ObjectToLookFor & "," & $OUtoScan & ",dc=MYDOM,dc=co,dc=uk"
        dim $oUser, $oLastLogon, $iLastLogon = 0
        
    ; Get user object
        Local $oUser = ObjGet("LDAP://" & $sServer & "/" & $sUserPath)
        If IsObj($oUser) Then
            $oLastLogon = $oUser.Get("lastLogon")
            If @error Then
            ;MsgBox(16, 'Debug', 'Error occured retreiving $oUser.Get("lastLogon").' & @CRLF & _
            ;       'This attribute may not exist for this object.')
                
                $LogonInfo[0] = "Error"
            ;Continue Looping
                
            Else
            ; Convert IADsLargeInteger parts to 100ns count
                $iLastLogonHigh = $oLastLogon.HighPart
                $iLastLogonLow = $oLastLogon.LowPart
                If $iLastLogonLow < 0 Then $iLastLogonHigh += 1; Compensate for IADsLargeInteger interface error
                $iLastLogon = $iLastLogonHigh * 2 ^ 32
                $iLastLogon += $iLastLogonLow
                
            ; Check if user ever logged in
                If $iLastLogon = 0 Then
                ;MsgBox(64, "Last Logon", "User has never logged on.")
                    $LogonInfo[0] = "Never"
                    ExitLoop
                Else
                ; Convert 100ns count to integer seconds
                    $iSeconds = Floor($iLastLogon / 10000000)
                    
                ; Convert seconds since 12:00AM January 01, 1601 to date string
                    $sLastLogon = _DateAdd("S", $iSeconds, "1601/01/01 00:00:00")
                ; Display result
                ;MsgBox(64, "Last Logon", "$sLastLogon = " & $sLastLogon & " Zulu (UTC)")
                    $LogonInfo[0] = "Found"
                    $LogonInfo[1] = $sLastLogon
                    $LogonInfo[2] = $DC
                    ExitLoop
                EndIf
            EndIf
        Else
        ;MsgBox(16, "Error", "$oUser is not an object, user may not exist.")
            $LogonInfo[0] = "Error"
            
        EndIf
        
        
    Next    

    Return $LogonInfo

EndFunc

Func MyErrFunc()
    
    $LogonInfo[0] = "Error"
    
   ;MsgBox(16, "AutoIt COM Error", "AutoIt intercepted a COM Error:" & @CRLF & _
    ;      "Number is: " & Hex($oMyError.number, 8) & @CRLF & _
     ;    "Windescription is: " & $oMyError.windescription)
      
    SetError(1)
EndFunc;==>MyErrFunc[code]

Share this post


Link to post
Share on other sites

The following script (based on adfunctions.au3) queries all domain controllers and returns the true last login time:

Global $objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD
$objConnection.ConnectionString = "Provider=ADsDSOObject"
$objConnection.Open("Active Directory Provider") ; Open connection to AD

Global $objRootDSE = ObjGet("LDAP://RootDSE")
Global $strDNSDomain = $objRootDSE.Get("defaultNamingContext") ; Retrieve the current AD domain name
Global $strHostServer = $objRootDSE.Get("dnsHostName") ; Retrieve the name of the connected DC
Global $strConfiguration = $objRootDSE.Get("ConfigurationNamingContext") ; Retrieve the Configuration naming context
Global $objOpenDS = ObjGet("LDAP:")

Global $DCList, $LastLogin=0
_ADListDomainControllers($DCList)

For $i =1 to $DCList[0]
    $sTmp = StringSplit($DCList[$i],",")
    $sTmp = StringSplit($sTmp[1],"CN=",1)
    $sTmp = _GetLogin($sTmp[2])
    If $sTmp > $LastLogin Then $LastLogin = $sTmp
Next
ConsoleWrite($LastLogin)    

Func _GetLogin($strHostServer)
    
    $strQuery = "<LDAP://" & $strHostServer & "/" & $strDNSDomain & ">;(sAMAccountName=" & @UserName & ");ADsPath;subtree"
    $objRecordSet = $objConnection.Execute($strQuery) ; Retrieve the FQDN for the object
    $ldap_entry = $objRecordSet.fields(0).value
    $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object
    $result = $oObject.LastLogin
    $oObject.PurgePropertyList
    
    If $result = "" Then
        Return ""
    Else
        Return $result
    EndIf
    
EndFunc

; _ADListDomainControllers
; Retrieves the names of all domain controllers in the current Domain
Func _ADListDomainControllers(ByRef $DCList)
    $objCommand = ObjCreate("ADODB.Command")
    $objCommand.ActiveConnection = $objConnection
    $objCommand.Properties("Page Size") = 1000
    $objCommand.Properties("Searchscope") = 2
    
    $objCommand.CommandText = "Select distinguishedName FROM 'LDAP://" & $strHostServer & "/ou=Domain Controllers," & $strDNSDomain & "' WHERE objectclass='computer'"
    
    $objRecordSet = $objCommand.Execute
    Dim $DCList[$objRecordSet.RecordCount + 1]
    $objRecordSet.MoveFirst
    
    Do
        $DCList[0] += 1
        
        $objCommand.CommandText = "<LDAP://" & $strHostServer & "/" & $objRecordSet.Fields("distinguishedName" ).Value & ">;;serverReferenceBL;Range=0-*;base"
        $objRecSet2 = $objCommand.Execute
        
        $objRecSet2.MoveFirst
        Do
            $temparray = $objRecSet2.Fields(0).Value
            $DCList[$DCList[0]] = $temparray[0]
            $objRecSet2.MoveNext
        Until $objRecSet2.EOF
        
        $objRecordSet.MoveNext
    Until $objRecordSet.EOF
    
    $objCommand = 0
    $objRecordSet = 0
    Return
EndFunc   ;==>_ADListDomainControllers

Looks better than My attempt - Bit more dynamic not having to specify the DC`s - Where do I put the object I want to search for ... Looking but not finding it anywhere - Maybe too late in the day for my eyes to take any more scripts.

Share this post


Link to post
Share on other sites

Sorry - Got it - @username

Share this post


Link to post
Share on other sites

The following example script (based on adfunctions.au3) queries all domain controllers and returns the true last login time

for computer PCTS29 (the sAMAccountName for a computer is the comptuername followed by a dollar sign).

The get the true last login for a user just use @username or the sAMAccountName of the desired user.

Global $objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD
$objConnection.ConnectionString = "Provider=ADsDSOObject"
$objConnection.Open("Active Directory Provider") ; Open connection to AD

Global $objRootDSE = ObjGet("LDAP://RootDSE")
Global $strDNSDomain = $objRootDSE.Get("defaultNamingContext") ; Retrieve the current AD domain name
Global $strHostServer = $objRootDSE.Get("dnsHostName") ; Retrieve the name of the connected DC
Global $strConfiguration = $objRootDSE.Get("ConfigurationNamingContext") ; Retrieve the Configuration naming context
Global $objOpenDS = ObjGet("LDAP:")

Global $DCList, $LastLogin=0
_ADListDomainControllers($DCList)

For $i =1 to $DCList[0]
    $sTmp = StringSplit($DCList[$i],",")
    $sTmp = StringSplit($sTmp[1],"CN=",1)
    $sTmp = _GetLogin($sTmp[2],"PCTS29$")
    If $sTmp > $LastLogin Then $LastLogin = $sTmp
Next
ConsoleWrite($LastLogin)    

Func _GetLogin($strHostServer,$sAMAccountName)
    
    $strQuery = "<LDAP://" & $strHostServer & "/" & $strDNSDomain & ">;(sAMAccountName=" & $sAMAccountName & ");ADsPath;subtree"
    $objRecordSet = $objConnection.Execute($strQuery) ; Retrieve the FQDN for the object
    $ldap_entry = $objRecordSet.fields(0).value
    $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object
    $result = $oObject.LastLogin
    $oObject.PurgePropertyList
    
    If $result = "" Then
        Return ""
    Else
        Return $result
    EndIf
    
EndFunc

; _ADListDomainControllers
; Retrieves the names of all domain controllers in the current Domain
Func _ADListDomainControllers(ByRef $DCList)
    $objCommand = ObjCreate("ADODB.Command")
    $objCommand.ActiveConnection = $objConnection
    $objCommand.Properties("Page Size") = 1000
    $objCommand.Properties("Searchscope") = 2
    
    $objCommand.CommandText = "Select distinguishedName FROM 'LDAP://" & $strHostServer & "/ou=Domain Controllers," & $strDNSDomain & "' WHERE objectclass='computer'"
    
    $objRecordSet = $objCommand.Execute
    Dim $DCList[$objRecordSet.RecordCount + 1]
    $objRecordSet.MoveFirst
    
    Do
        $DCList[0] += 1
        
        $objCommand.CommandText = "<LDAP://" & $strHostServer & "/" & $objRecordSet.Fields("distinguishedName" ).Value & ">;;serverReferenceBL;Range=0-*;base"
        $objRecSet2 = $objCommand.Execute
        
        $objRecSet2.MoveFirst
        Do
            $temparray = $objRecSet2.Fields(0).Value
            $DCList[$DCList[0]] = $temparray[0]
            $objRecSet2.MoveNext
        Until $objRecSet2.EOF
        
        $objRecordSet.MoveNext
    Until $objRecordSet.EOF
    
    $objCommand = 0
    $objRecordSet = 0
    Return
EndFunc   ;==>_ADListDomainControllers

When running this I get

(64) : ==> Subscript used with non-Array variable.:

$DCList[$DCList[0]] = $temparray[0]

$DCList[$DCList[0]] = $temparray^ ERROR

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0