simy8891 Posted May 24, 2014 Share Posted May 24, 2014 Hi guys, I know what I'm asking it's a bit of a pain, but is anybody out there able to translate the following PS script to AutoIT? I don't really understand a few parts of it and I'm not quite sure is even possible to keep (more or less) the same syntax. This script gets all AD's in the domain and then gets the last logon details from each one of them for each single Computer Object in order to get a real last logon date. This cannot be done with either Get-ADComputers in powershell or with the AD UDF function for a simple reason: It takes about 100 hours against the 20 minutes of the below (About 6100 machines). If anybody's interested, the below already works, and you can just replace the Write-Host with an export to csv (which I'm not able to do at the moment due my limited PS knowledge). The reason I'm asking this is because I've got a huge AutoIT script behind the scene already working with the data this script should get: expandcollapse popup#Get DirectorySearchers for each DC $dcSearchers = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers | ? { Test-Connection $_.IPAddress -Count 1 -Quiet } | % { $_.GetDirectorySearcher() } foreach ($dcSearcher in $dcSearchers) { $dcSearcher.Filter = '(objectClass=computer)' $dcSearcher.PageSize = 1000 $dcSearcher.SizeLimit = [Int32]::MaxValue [Void]$dcSearcher.PropertiesToLoad.AddRange(@('lastLogon','name','userAccountControl','description','distinguishedName')) } #Build LastLogon Array $arrayComputers = New-Object System.Collections.ArrayList $arrayComputerInfo = New-Object System.Collections.ArrayList foreach ($dcSearcher in $dcSearchers) { $dcSearcher.FindAll() | ForEach-Object ` { $computerName = $_.Properties.Item('distinguishedname')[0] $index = $arrayComputers.BinarySearch($computerName) if ($index -lt 0) { $arrayComputers.Insert((-bnot $index),$computerName) $computerInfo = @{ 'name' = [string]($_.Properties.Item('name')[0]) 'enabled' = -not (2 -band $_.Properties.Item('useraccountcontrol')[0]) } if ($_.Properties.PropertyNames -icontains 'lastLogon') { $computerInfo.Add('lastlogon',$_.Properties.Item('lastlogon')[0]) } else { $computerInfo.Add('lastlogon',[UInt64]0) } if ($_.Properties.PropertyNames -icontains 'description') { $computerInfo.Add('description',$_.Properties.Item('description')[0]) } else { $computerInfo.Add('description',[String]::Empty) } $arrayComputerInfo.Insert((-bnot $index),$computerInfo) } elseif (($_.Properties.PropertyNames -icontains 'lastLogon') -and ($arrayComputerInfo[$index]['lastlogon'] -lt $_.Properties.Item('lastlogon')[0])) { $arrayComputerInfo[$index]['lastlogon'] = $_.Properties.Item('lastlogon')[0] } } } #Main cls foreach ($computer in $arrayComputerInfo) { Write-Host ('{0} - {1} - {2} - {3}' -f $computer['name'], $computer['enabled'], [DateTime]::FromFileTime($computer['lastlogon']), $computer['description']) } Thanks Link to comment Share on other sites More sharing options...
BrewManNH Posted May 24, 2014 Share Posted May 24, 2014 You should look at the AD UDF for help in using AutoIt to get the Acitve Directory information If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
simy8891 Posted May 24, 2014 Author Share Posted May 24, 2014 You should look at the AD UDF for help in using AutoIt to get the Acitve Directory information Hi, yeah I said it above already. The AD commands are way too slow. The only option is a ldap query. Link to comment Share on other sites More sharing options...
BrewManNH Posted May 24, 2014 Share Posted May 24, 2014 Have you looked at the functions inside the UDF, most of them are already using LDAP. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
water Posted May 24, 2014 Share Posted May 24, 2014 Getting the true last logon date is always very slow because you query every DC in the domain. If one of them is down or responds slowly then it takes forever. Why do you need to query so many machines? Wouldn't a not so accurate logon date be sufficient? My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
simy8891 Posted May 24, 2014 Author Share Posted May 24, 2014 We're merging 4 domains onto one and the report will be shared between a few system engineers who will rely on those. Some of them need a true last logon date which I can get with the above powershell script, across all domain controllers (46 at the moment but the number will increase with the migrations) in only 15 minutes. It took 20ish via VPN. Water, does your UDF have ldap queries? I've tried a couple of example I found on the forum, it is a great UDF but couldn't find something fast enough. One thing to say about the above: With 6k clients and 46 DC's, it'll eat up almost 500MB of RAM but honestly, I'm not really preoccupied about that. Cheers Link to comment Share on other sites More sharing options...
water Posted May 24, 2014 Share Posted May 24, 2014 My UDF uses ADO to connect to a DC or GC and LDAP to query the database. If you could query property LastLogon you would only need to query one DC and get a value that is off the real date by max. 2 weeks. About the LastLogon property: "Please note that this value is NOT replicated between domain controllers - if you want to know the exact last logon time for an account in a domain with more than one domain controllers, you have to check this value on all domain controllers! In Windows 2003 Active Directory, Microsoft introduced another user attribute named lastLogonTimestamp. This attribute is replicated to other DCs, but only after two weeks (minus a random percentage of 5 days), so it is suitable to locate inactive accounts which did not logon to the domain for a long time." My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
simy8891 Posted May 24, 2014 Author Share Posted May 24, 2014 Hi Water, I've tried to get a lastlogon with your UDF, across all domains and it took about 2 minutes (for a single machine). Same story with PS (Get-ADComputer etc...). Unfortunately for the kind of cleanup we're doing, 2 weeks are lots of time. Basically I'm personally looking after the licensing and to do so, we've got to have SCCM up to date and to do that, I'm running reports against AD and SCCM so that people onsite can start finding out what the heck they're doing with their machines. Unfortunately working in a big organisation requires lots of work if people don't focus on theirs. Once everything is settled down and we have a 99% of devices inventoried etc, then I can start looking at the lastlogontimestamp, which is indeed replicated. Now, I'll try to keep working with the .ps1 as a scheduled task. I've started this project by using ADTidy (it also takes about 15/25 minutes to run through all DC's) and creating a new collection for each site we have, then exporting data manually and start comparing it manually. Then, obviously, I've noticed that it was too much work that I could automate, so I started automating the actual report part in excel so I only had to provide the script with the SCCM list for the specific site and the adtidy report, for the specific site (we use a sitecode for each site, so it includes laptops as well, so travellers, that's why I need all DC's). Then I build a report and a subscription in SCCM to automatically export the report against All Systems' collection. Then I made a script which requires the sitecode I want and will catch all the machines. Now, I'll do the same with this script. Once that's done, I'll look at fully automate the process based on a config file which will create a report, daily, for each site. Pretty easy for now, just wanted to stick with AutoIT Link to comment Share on other sites More sharing options...
water Posted May 24, 2014 Share Posted May 24, 2014 _AD_GetLastLoginDate first calls _AD_ListDomainControllers to get a list of all DCs to query for the last login date. To speed up the query you could either limit _AD_GetLastLoginDate to the DCs serving for a site or you could pass an array with DCs to query as parameter 3. My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
simy8891 Posted May 25, 2014 Author Share Posted May 25, 2014 _AD_GetLastLoginDate first calls _AD_ListDomainControllers to get a list of all DCs to query for the last login date. To speed up the query you could either limit _AD_GetLastLoginDate to the DCs serving for a site or you could pass an array with DCs to query as parameter 3. Not really, the problem is with travellers. If I query the local DC in the US and the user's been in EU for 5 days, I'll never know its real last logon date. Plus, unfortunately, we have some connectivity issues with sites in SA or Poland which slow the process down.. Link to comment Share on other sites More sharing options...
water Posted May 25, 2014 Share Posted May 25, 2014 In this case I would do the following: Grab a list of all computer objects you want to check Split the list into (lets say) 5 parts and save each part into a separate file (computers1.txt etc.) Run 5 copies of your script and pass the name of the input file as parameter Let the script query the computers from the input file and write the last logon date into a separate file (result1.txt etc.) Combine the restult files and you are done My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
simy8891 Posted May 27, 2014 Author Share Posted May 27, 2014 Hey water, I've tried some options, one of those is this: It's pretty fast to get all last logons through each DC (about 10/15 minutes). What I do is first get a list of DC with csvde, then, always with csvde, I get a a .csv with all the major info I need (name, description) and I'll use this csv as a base to run through each item. In order to get the last logons I use the below: $sCommand='csvde -f '&$filename&' -s '&$dc&' -d "'&$Domain&'" -p subtree -r "(&(objectCategory=computer))" -l "lastlogon,samAccountName"' _RunDos ( $sCommand ) This is ran in a For cycle for each DC found above. Problem now is comparing then all Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now