How to get lastLogonTimestamp from all DCs for specific users - active-directory

I'm trying to make a script for query all the users from specific users in my domain and get the last "lastLogonTimestamp" from each user , and export the result to a csv file . eg : "SOL*" for users beginning SOL
I obtain the results for most users for "last logon date" the date 31/12/1600 06:00:00 p.m but i dont know why for some users get the correct date and for other for users the date of the year 1600, regardless if they are in the same OU or not.
Get-ADDomainController -filter * |
% {Get-ADUser -Filter "Enabled -eq 'True' -and SamAccountName -like 'SOL*'" -server $_.name -Properties Name,SamAccountName,Description,EmployeeID,EmployeeNumber,EmailAddress,LastLogon,Manager,Title,Department,Organization,Enabled -SearchBase "OU=users,DC=contoso,DC=local" |
Select Name,SamAccountName,Description,EmployeeID,EmployeeNumber,EmailAddress,#{N='Last‌​Logon'; E={[DateTime]::FromFileTime($_.LastLogon)}},Manager,Title,Department,Organizatio‌​n,Enabled}|
Group samaccountname |
ForEach{$_.Group | Sort LastLogon -Descending | Select -First 1} |
Export-Csv "C:\export\AD_Export.csv" -NoTypeInformation

That means that user has never logon using that particular DC.
For example, an employee in US will probably never contact the Europe DC during logon. In this case the lastlogon on Europe DC will be "31/12/1600 06:00:00 p.m" (min value of lastlogon is January 1, 1601 (UTC), the time you saw is "time-zoned").
One more thing, lastLogonTimestamp and lastLogon are 2 different attributes.
lastLogon record the exact logon time but is not replicated among DC.
lastLogonTimestamp is replicated, but it is only an approximation.
(by default it can be <= 14 days earlier than actual value, only useful for finding idle account...)
In your case, you are actually talking about lastLogon.

Related

Export specific output from an array

I have the below code that displays all groups that users which have a SamAccountName starting with 'X' are members of, and that exports the output in a CSV file:
Get-ADUser -Filter {SamAccountName -like "X*"} -Properties memberof |
Select name, #{N="MemberOf";E={$_.memberof -join ";"}} |
Export-Csv "C:\Users\chicken\Desktop\export_powershell\extract_test.csv"
The code works fine, but I have some problems with the output. Indeed it returns all groups that users are members of, but I only need to export one specific group (the group that starts by 'G-ORG') for each user.
How can I filter the output to only have groups that start with 'G-ORG' for each user?
Example output:
User1,"CN=YVD_Access; CN=Proxy_ACCESS_GD; CN=RVH_BIS HSBC; CN=G-ORG-MULTI-CANAL-APPLICATION; CN=......"
USER2,"CN=G-ORG-ARCHI; CN=Proj_X; CN=Proj_X; CN=X_REF; CN=......"
USER3,"CN=HAV_SH; CN=G-ORG-IT; CN=EPH; CN=......"
USER...
Required output:
User1,"CN=G-ORG-MULTI-CANAL-APPLICATION"
USER2,"CN=G-ORG-ARCHI"
USER3,"CN=G-ORG-IT;"
USER...
Simply filter the member list for distinguished names that begin with CN=G-ORG- instead of joining all of them:
$_.memberof | Where-Object { $_.StartsWith('CN=G-ORG-') }
If there could be more than one match you can then either join the results
($_.memberof | Where-Object {...}) -join ';'
or select one of them (e.g. the first)
$_.memberof | Where-Object {...} | Select-Object -First 1
depending on the requirements.

Logon, logoff script analysing using PowerShell

I'll first explain what I'm trying to achieve.
For a project they want to monitor the pilot group of PCs. And they want the following information:
Total unique users that logged on
Total log on
Time of each session per user
So I went ahead and created a logon- and logoff script. The output of these scripts is a txt file each month.
For example: File 01-2017.txt contains:
25-01-2017,09:29,lky9,WS257737,Logon
25-01-2017,10:37,lky9,WS257737,Logoff
25-01-2017,10:01,1f57,WS157954,Logon
25-01-2017,10:29,7df6,WS248751,Logon
25-01-2017,10:34,7df6,WS248751,Logoff
25-01-2017,10:48,1f57,WS157954,Logoff
Now I have (unsuccesfully) tried getting all of this in an array, with Get-Content. Because when I can achieve this, I can try further. PowerShell skills still very poor, but I can manage arrays okay. So the questions is;
Can anyone please explain to me how I get this in an array?
What you need is to import a CSV using the Import-CSV cmdlet since this will give you all records as an array of objects:
$logList = Import-Csv -Path "Path_to_01-2017.txt" -Header #('Date', 'Time', 'User', 'PC', 'Type')
Output:
Date : 25-01-2017
Time : 09:29
User : lky9
PC : WS257737
Type : Logon
Date : 25-01-2017
Time : 10:37
User : lky9
PC : WS257737
Type : Logoff
Date : 25-01-2017
Time : 10:01
User : 1f57
PC : WS157954
Type : Logon
Date : 25-01-2017
Time : 10:29
User : 7df6
PC : WS248751
Type : Logon
Date : 25-01-2017
Time : 10:34
User : 7df6
PC : WS248751
Type : Logoff
Date : 25-01-2017
Time : 10:48
User : 1f57
PC : WS157954
Type : Logoff
Example how you can use this to answer your questions:
#total unique users that logged on
$logList.User | select -Unique | Measure | select -ExpandProperty Count
#Total log on
$logList | where Type -eq LogOn | Measure | select -ExpandProperty Count
#Time of each session per user
# This is a bit tricky so I leave that up to you :p
I'd use a totally different approach. The event viewer holds the logon & logoff timestamp with a user id (I think it's the sid of the user). Then you only need to keep track of unexpected restarts to make sure that's your cut off point for any sessions that only have a logon event up to that time.
Then you can just run a script at any give time on a scheduled task or something. You won't have to run during logon/logoff which will probably impact logon time (not much but still).

Get the latest date

I have an array that I call $data.
I want to get the earliest dates from the $data array for each host in my csv file. The user will input a host and it will find the earliest date it was modified.
Hostname LastModified
HD 9/8/2012
LOG 9/15/2004
NETMAN 12/25/2004
NETMAN 5/5/2015
LOG 1/4/2013
LOG 6/6/2011
So if they input LOG, I want it to give me the earliest date.
Created on 9/15/2004
Code:
$data= import-csv ".\Earliest Date Template.csv"
$Hostname=Read-Host "Please enter Host Name"
$data | Foreach-Object {$_."Last Modified" = [DateTime]$_."Last Modified"; $_} | Group-Object Hostname| Foreach-Object {$_.Group | Sort-Object LastModified | Select-Object -First 1}
Grouping them does seem like the way to go but you don't need to do that. Just sort the entire list by date then select the last option from the list (that matches the host name you are looking for).
$hostname = Read-Host "Please enter Hostname"
$data | Sort-Object {[DateTime]$_."LastModified"} | Where-Object{$_.Hostname -eq $hostname} | Select -Last 1
You might need to do some user validation but something like this seems to work with your sample data:
Please enter Hostname: log
Hostname LastModified
-------- ------------
LOG 1/4/2013
If you then only want the date it would just be a matter of expanding the value from the result.
$data |
Sort-Object {[DateTime]$_."LastModified"} |
Where-Object{$_.Hostname -eq $hostname} |
Select -Last 1 -ExpandProperty LastModified

How to find String from attribute proxyAddresses?

How to find string "SMTP:*" (primary user address) in attributte proxyAddresses, then save in to variable and compare with value in attribute company. If there is a match (or no match) then exported into CSV file.
The number of values proxyAddresses is different:
smtp:adam#ff.ju.com,SMTP:adam#zf.ju.com,smtp:adam#ju.com
or
smtp:adam#ff.ju.com,SMTP:adam#ef.ju.com
or
SMTP:adam#ff.ju.com
Values in attributte company are only two characters: ff or zf or ju. They are always two characters after the #.
I have about two thousand users in Active Directory.
I have a code
Get-ADUser -Filter * -SearchBase 'DC=ju,DC=com' -Properties company,proxyaddresses |
select company, #{L='ProxyAddress'; E={$_.proxyaddresses -join"; "}}
Result is a column Company (two char) and a column proxyaddresses (there are all values). I need only the value SMTP:xxx#xxx.
Select the proxyaddresses element that begins with an uppercase SMTP::
#{n='ProxyAddress';e={$_.proxyaddresses | Where-Object {$_ -clike 'SMTP:*'} | Select-Object -First 1}}
The operator -clike does a case-sensitive comparison.

Get files (in folder,subfolder from a drive) based on last access parameter in powershell

I want a script to list all files in folder/subfolder with a particular last access date.
I have a script to show a subfolder:
get-childitem -Recurse | Where {$_.psIsContainer -eq $true} | select {$_.Fullname}
Thank you for your help.
Get-ChildItem -Recurse | ? { $_.lastaccesstime -ge [datetime]"12/18/11"} | select fullname
this give you a files's list with lastaccesstime attribute greater or equal 18 december 2011 00.00 am.
Get-ChildItem -Recurse | ? { $_.lastaccesstime -ge [datetime]"12/01/11" -and $_.lastaccesstime -lt [datetime]"12/02/11"} | select fullname
this give all file with lastaccesstime in date december 01 2011 from 00.00am to 11.59pm
lastaccesstime is a complete reference to date and time, that's why you need to specifies a range for a single date match.

Resources