Link to home
Start Free TrialLog in
Avatar of Robert Perez-Corona
Robert Perez-CoronaFlag for United States of America

asked on

Can I use powershell to generate list of users who logged in to computers in AD

hello, I need to gather a list of computers, users who log into the computers and service tags(dell tags). Last logged on time would be helpful as well.

I am trying to clean up my asset management system as well as AD while trying to avoid going around all 200+ computers

It is ok if the dell service/system tag is not possible to obtain the service tag, but the computers and their respective users will be needed.

The users do NOT use roaming profiles. They all log on to their dedicated workstations.

Is there any script I am over looking out there that can help me out here?

Many thanks.
t
Avatar of Luis Moura
Luis Moura
Flag of Portugal image

SOLUTION
Avatar of Niten Kumar
Niten Kumar
Flag of Fiji image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes, that is true, My script output is based on if logged in at the time,.
Avatar of Robert Perez-Corona

ASKER

Thanks for the feedback! I will give this a shot a soon as I get to the office
Apologies for the late reply folks.

I edit the script as per your instructions. However, when I run the script via dos or powershell, it seems to process but nothing is generated. I simply end up at another dos/power shell prompt
Am I missing something? Is it possible to generate a csv or at least list the results?

Many thanks
I'm sure I confused you on trying to show to different types of accessing data.  My fault.  This one is to search your domain of anyone logged in.  (At the time you run it).  Otherwise it will fail.  Place this script in ISE.  Run once to load the function.  Then type the function name.  Get-LoggedOnUser.  Example:   PS C:\powershell\Get-LoggedOnUser

It will search and write to the host.  If you want to go to csv, change "Out-Host to Export-Csv C:\yourpath\YourFile.csv. Also change your DC name to your own.  Its in CAPS where to change.  



<#Run this funcion under Windows Powershell ISE.  Depending on your environment.  This goes through  every
  computer, and takes a while.  If you decide to use the paramenter Computername, then remove the remarks of
 the paramenter.  And just type in an array of machines.  That goes faster...E.g. Get-loggedOnUser -computername -server1,server2,computer1
 #>


 # Pipeline version otherwise use parameter and rem this out
 $Comps =  Get-ADComputer -Filter * -Server -YOURDCNAME -Properties * |select -ExpandProperty  name

 function Get-LoggedOnUser {
 #Requires -Version 2.0            
  <# [CmdletBinding()]            
  Param             
    (                       
     [Parameter(Mandatory=$true,
                Position=0,                          
                ValueFromPipeline=$true,            
                ValueFromPipelineByPropertyName=$true)]            
     [String[]$ComputerName
    )#End Param
 #>   

 Begin            
 {            
  Write-Host "`n Checking Users . . . "
  $i = 0            
 }#Begin          
 Process            
 {
     $Comps | Foreach-object {
     $Computer = $_
     try
         {
             $processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer -EA "Stop")
                 if ($processinfo)
                 {    
                     $processinfo | Foreach-Object {$_.GetOwner().User} | 
                     Where-Object {$_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM"} |
                     Sort-Object -Unique |
                     ForEach-Object { New-Object psobject -Property @{Computer=$Computer;LoggedOn=$_} } | 
                     Select-Object Computer,LoggedOn
                 }#If
         }
     catch
         {
             "Cannot find any processes running on $computer" | Out-Host
         }
      }#Forech-object(Comptuters)       
             
 }#Process
 End
 {

 }#End

 }#Get-LoggedOnUser 

Open in new window

This one is for an array, that you can just type computer names in, because the parameter is -computername.  Run this script once to load the function,  they type Get-LoggedOnUser and then it will ask for a computer name.  Type as many as you like.  Once finished just push enter and it will find the computers you typed in.   (If they are logged in).   This is by computername so nothing to change.  

function Get-LoggedOnUser {
#Requires -Version 2.0            
[CmdletBinding()]            
 Param             
   (                       
    [Parameter(Mandatory=$true,
               Position=0,                          
               ValueFromPipeline=$true,            
               ValueFromPipelineByPropertyName=$true)]            
    [String[]]$ComputerName
   )#End Param

Begin            
{            
 Write-Host "`n Checking Users . . . "
 $i = 0            
}#Begin          
Process            
{
    $ComputerName | Foreach-object {
    $Computer = $_
    try
        {
            $processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer -EA "Stop")
                if ($processinfo)
                {    
                    $processinfo | Foreach-Object {$_.GetOwner().User} | 
                    Where-Object {$_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM"} |
                    Sort-Object -Unique |
                    ForEach-Object { New-Object psobject -Property @{Computer=$Computer;LoggedOn=$_} } | 
                    Select-Object Computer,LoggedOn
                }#If
        }
    catch
        {
            "Cannot find any processes running on $computer" | Out-Host
        }
     }#Forech-object(Computers)       
            
}#Process
End
{

}#End

}#Get-LoggedOnUser

Open in new window

On the 1st script to search whole domain, what I mean by fail is that is will just report back "Cannot find any processes running on PCNAME".  It will continue to search until it has searched all ADcomputers.
Thanks again!

Searching the whole domain seems more like what I need to do. But I will try both of them.

Cheers
Lastly I wrote this for a person that needed who was last logged in for a certain amount of days.  This is from the LastLogon attribute in the ADUser Object.  I deleted the filter of a date -10 days last logged in.  This is in HTML format.  So it will email it to you.  Change the information under "This information you need about your SMTP server" that I have remarked out.  I capitalized what to change.  But notice I had to filter it a different way, otherwise it gives every user.  (Even disabled, ExchangeHealth, etc)  We have our EmployeeID entered for all active users.  Take the Where-Object {$_.EmployeeID -ne $null} if you don't have their ID entered.  Or change to -eq, doesn't matter.  This will search Active Directory of the last successful logon in AD.  Change the selection of what you need as well.  He needed manager, EmployeeID, office, etc.  If you want in a CSV, read instruction in the remarks at the bottom of the script.  



# Get date values
 $Date = Get-Date
 [String]$Year = $Date.Year
 [String]$Month = $Date.Month
 [String]$Day = $Date.Day
 
 # Pad the date parts with leading 0's
 If ( $Month.ToString().Length -lt 2 ) { $Month = '0' + $Month }
 If ( $Day.ToString().Length -lt 2 ) { $Day = '0' + $Day }



# This is information you need about your SMTP server

$SMTPServer = "MAIL.DOMAIN.COM"
$messageSubject = "All Domain Users"
$smtpfrom = "ANYNAME.DOMAIN.COM"
$smtpto = "VALIDEMAILADDRESS@DOMAIN.COM"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

<# 
    Convert to HTML  You can go to this site to find more color names.
    I use what I can see well. http://www.w3schools.com/colors/colors_names.asp
#>

$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color:lightgray: text-align;right}"
$a = $a + "TD{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color:whitesmoke}"
$a = $a + "</style>"

<# 
    Here is the amount of days.  I picked 10.  You can change the -gt to whatever you want.
    Keep in mind I get a lot of dates of the year 1600.  I think thats because they never logged in.
    Also, because of Exchange I get all the Exchange HealthMailboxes, etc.  But my Domain is 
    in theprocess of cleaning up bad accounts.
    You can limit it by OU and use -searchbase for a specific OU
    Or what I did, and only
#> 

$AllUsers = get-aduser -filter *  -properties DisplayName,lastlogon,Manager,EmployeeID,office | Where-Object {$_.EmployeeID -ne $null} `
             |sort-object lastlogon `
             |select name,DisplayName,@{Exp={([datetime]::FromFileTime($_.lastlogon))};label="Last logon time"} `
             ,@{n="Manager Name";e={(Get-ADUser -Identity $_.Manager -properties DisplayName).DisplayName}},employeeID,office


            
            
<#  
    If you need to export to CSV by the date of the file place what I have below to the $allUsers variable
    Then put -attacments at the end of H1> and the path you exported it too
  
    |export-csv "C:\powershell\Scripts\lastlogon-audit_$Year$Month$Day.csv" -NoTypeInformation -Delimiter ";"
#>


$message.Body = $AllUsers | ConvertTo-HTML -head $a -body "<H1>Users Logged In Times From AD</H1>"

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

Open in new window

Thanks guys