Author Posts

January 1, 2012 at 12:00 am

by lucromick at 2012-10-05 21:59:33

Hi All,

I'm trying to write a script that tracks login/logoff times for computers in a specific OU. I would like to append output to a table.txt with the computer name and date/time of the logging event. I'm really sorry about my jumbled code. I'm trying to learn and create this script at the same time. I think my functions should probably be piped together but I'm not sure how.

Additionally, could anyone explain the use of the "@" symbol to me. I know it has something to do with grouping objects but I just don't get it.

Thank you very much for reading. It's much appreciated.

#grab computer information based off the OU

$strComputers = @()
ou = [ADSI]"LDAP://OU=OUname,DC=DCname,DC=.COM"
foreach ($child in $ou.psbase.Children) {
if ($child.ObjectCategory -like '*computer*') { $strComputers += $child.Name }
}

$strComputers = "localhost"

#This code puts the Computers into the string $strComputers, which in turn can be called like this -

$resultsBlank = ""

$ResultsFile = "C:\Users\computer\Desktop\computernames.txt"

foreach ($strComputer in $strComputers) {
$colItems = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $strComputer
foreach ($objItem in $colItems) {
$results = "Name: " + $objItem.Name

out-file -filepath $ResultsFile -append -inputobject $results

}
}

#function that logs computers logging off and on

function eventlog {

Get-EventLog System -Source Microsoft-Windows-Winlogon

$UserProperty = @{n="User";e={(New-Object System.Security.Principal.SecurityIdentifier $_.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])}}
$TypeProperty = @{n="Action";e={if($_.EventID -eq 7001) {"Logon"} else {"Logoff"}}}
$TimeProeprty = @{n="Time";e={$_.TimeGenerated}}
Get-EventLog System -Source Microsoft-Windows-Winlogon | select $UserProperty,$TypeProperty,$TimeProeprty

}

#end by piping function into output text
$results | out-file "C:\Users\computer\Desktop\computlog.txt"
eventlog | out-file "C:\Users\computer\Desktop\computerlog.txt"

by RichardSiddaway at 2012-10-06 03:00:39

Ok

Lets break this down into a couple of areas. Firstly getting the event log info. You are just about there. If we just think about the local machine for a minute we can do this
$env:COMPUTERNAME |
foreach {
$compfile = "C:\test\$($_)log.csv"

$User = @{n="User";e={(New-Object System.Security.Principal.SecurityIdentifier $_.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])}}
$Type = @{n="Action";e={if($_.EventID -eq 7001) {"Logon"} else {"Logoff"}}}
$Time = @{n="Time";e={$_.TimeGenerated}}
Get-EventLog System -Source Microsoft-Windows-Winlogon | select $User, $Type, $Time | Export-Csv -Path $compfile -NoTypeInformation
}

$env:COMPUTERNAME gives us the local computer name. We pipe that into foreach where you create three property definitions (I'll cover those in a bit) and then select from the System log. The results are piped out to a CSV file. I've changed the path just to make my testing easier.

Next job is to get the computer names from an OU

$root = [adsi]""
$ou = [adsi]"LDAP://ou=CompOU,$($root.distinguishedName)"

$search = [adsisearcher]$ou
$search.Filter = "(objectclass=computer)"
$search.SizeLimit = 3000
$search.FindAll() |
foreach {
$_.Properties |
select @{N="Name"; E={$_.name}}, @{N="DistinguishedName"; E={$_.distinguishedname}}
} | sort Name |
Format-Table Name, DistinguishedName -AutoSize

I'm searching the OU for objects of type computer than pulling the name out of the properties. Using the [adsi]"" is a useful trick to get the root part of the distinguished name.

So we've got a list of computers and we know how to pull the logon info – time to put the two bits together

$root = [adsi]""
$ou = [adsi]"LDAP://ou=CompOU,$($root.distinguishedName)"

$search = [adsisearcher]$ou
$search.Filter = "(objectclass=computer)"
$search.SizeLimit = 3000
$search.FindAll() |
foreach {
$computer = $_.Properties["Name"]
$compfile = "C:\test\$($computer)log.csv"

$User = @{n="User";e={(New-Object System.Security.Principal.SecurityIdentifier $_.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])}}
$Type = @{n="Action";e={if($_.EventID -eq 7001) {"Logon"} else {"Logoff"}}}
$Time = @{n="Time";e={$_.TimeGenerated}}
Get-EventLog System -Source Microsoft-Windows-Winlogon -ComputerName $computer | select $User, $Type, $Time | Export-Csv -Path $compfile -NoTypeInformation
}

I haven't had chance to fully test this.

The question about @ I'm assuming relates to the lines like this
$Time = @{n="Time";e={$_.TimeGenerated}}

The @{} structure is called a hash table. Its a collection of key-value pairs separated by semi-colon. What you are doing is creating a new property where n= supplies the name and e= supplies an expression to calculate the property value

Hope this helps

by lucromick at 2012-10-06 13:40:09

Thanks Richard!

You set me in the right direction and taught me a lot with that post.

by lucromick at 2012-10-07 20:18:04

so this line of code automatically finds the FQDN for that particular OU?

Awesome!


$root = [adsi]""
$ou = [adsi]"LDAP://ou=CompOU,$($root.distinguishedName)"

by lucromick at 2012-10-08 06:45:39

Hi Richard,

$search.FindAll() | is causing an error.