Answered by:
Logic Issue

Question
-
Hello,
I'm writing a script, which will detect non reporting devices (they don't send daily logs to our LOG server)
Servers create directories in this format "dnshostname-ipv4address".
Sometimes the devices receive another IP address, so they create multiple folders. I want to detect duplicities, devices they have been removed from AD, no need to keep the logs ($obsolete), devices that they exist in AD but they don't send logs ($syslogmissing), devices that stop reporting but they still exist in AD and they already reported something ($missing)$workdir = "D:\SCRIPTS\PS1\WORK\OBIT" $Source = import-csv $workdir\adcomputers.csv -Header ComputerName | group ComputerName -AsHashTable $htmlreport = "$workdir\report.html" $exclusionlist = "deviceToExclude" $filter=$exclusionlist.Split() | ?{$_ -ne ""} #Hashtable - directory list from LOG server $Mycol = @() $directories = Get-ChildItem $workdir -Directory foreach ($dir in $directories) { $MyObject = [pscustomobject]@{ DnsName = ($dir.name -split (‘-\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b’))[0] FullName = $dir.Name LastWriteTime = $dir.LastWriteTime.Date.ToString('yyyy-MM-dd') } $mycol += $MyObject } $DirTable = $Mycol |group DNSName -AsHashTable #creating unique set of keys from both tables (txt files (or AD computers) and directory list) $Keys = "" $Keys = $($source.Keys) + $($DirTable.keys | ?{$_ -ne ""}) | select -unique | ?{$filter -notcontains $_} #now create new hashtable used for reporting $result = @() $duplicateHT = @() foreach ($key in $keys) { # If only 1 record is found in directory list (1 directory per device) ... if (($DirTable[$key]).count -le 1) { $MyObject = [pscustomobject]@{ Source = $Source[$key].ComputerName FullName = $DirTable[$key].FullName LastWriteTime = $DirTable[$key].LastWriteTime } $result += $MyObject } # now deal with multiple records else { foreach ($duplicate in $DirTable[$Key]) { $MyObject = [pscustomobject]@{ Source = $duplicate.DnsName FullName = $duplicate.FullName LastWriteTime = $duplicate.LastWriteTime } $duplicateHT += $MyObject } } } ## mail parameters [string[]]$recipients = "" $messageParameters = @{ From = "" To = $recipients Cc = "" SmtpServer = "" } $body = "" ## HTML settings $Header = @" <style> body { } h2 { #color:blue; /* jen pokud nenastavujeme primo v convertto-html casti */ } Table { width: 1600px; margin: left; border-width: 1px; border-radius: 0px 0px 5px 5px; border-style: solid; border-collapse: separate; border-spacing: 0; box-shadow: 10px 10px 10px #b3d9ff; border: thin ridge grey; fixed: $true } th,td,tr { #border-collapse: collapse; #border-style: solid; #border-width: 0px; text-align: left; font-family:Arial; font-size:8pt; } th { background: #167F92; border: 0px solid; color: #fff; padding: 2px 2px; } tr:nth-child(even) { background: #dae5f4; } tr:nth-child(odd) { background: #b8d1f3; } tr:hover {background-color: #a3a3c2} td:hover {background-color: red;} td:nth-child(1) { width: 5%; overflow: hidden; text-overflow: ellipsis; } td:nth-child(2) { width: 6%; } td:nth-child(3) { width: 10%; } td:nth-child(4) { width: 5%; } td:nth-child(5) { width: 5%; } </style> "@ $MessageBody = @" "@ ## Correctly reporting $OK = $result |?{$_.FullName -and $_.Source } | ?{$_.lastwritetime -gt (get-date).AddDays(-2).ToString('yyyy-MM-dd')} $body += "<br>" $body += "<b><font color=green>Asi vše OK </font></b><br>" $body += ($OK |ConvertTo-Html -Head $Header) ## Missing daily log $Missing = $result |?{$_.FullName -and $_.Source } | ?{$_.lastwritetime -le (get-date).AddDays(-2).ToString('yyyy-MM-dd')} | sort lastwritetime -Descending $body += "<br>" $body += "<b><font color=orange>Missing daily log... </font></b><br>" $body += ($Missing |ConvertTo-Html) ## Duplicate records $DuplicateRecords = $DuplicateHT | sort @{ e = "Source"; Descending = $true }, @{ e = "LastWriteTime"; Descending = $true } $body += "<br>" $body += "<b><font color=Orange>Duplicate records in SYSLOG share! </font></b><br>" $body += ($DuplicateRecords |ConvertTo-Html) ## Missing in SYSLOG $SyslogMissing = $result | ?{!$_.FullName -and $_.Source} $body += "<br>" $body += "<b><font color=red>Missing on SYSLOG share! </font></b><br>" $body += ($SyslogMissing |ConvertTo-Html) ## Obsolete records in SYSLOG $Obsolete = $result | ?{$_.FullName -and !$_.Source} $body += "<br>" $body += "<b><font color=red>Obsolete records in SYSLOG share! </font></b><br>" $body += ($Obsolete |ConvertTo-Html) set-Content $htmlreport $body -Encoding UTF8 Send-MailMessage @messageParameters -body $messagebody -subject "SyslogReport" -Attachments $htmlreport -BodyAsHtml -Encoding UTF8 write-host ".. script finished, cleaning up." remove-item $workdir\report.html
This is my early version where I got all duplicate records in the $DuplicateRecords table.
Then I realized, its better to have 1st record on $result table, the rest in the $duplicateHT Table
So coming up with this..
foreach ($key in $keys) { if (($DirTable[$key]).count -le 1) { $MyObject = New-Object psobject -Property ([ordered]@{ Source = $Source[$key].ComputerName FullName = $DirTable[$key].FullName LastWriteTime = $DirTable[$key].LastWriteTime }) $result += $MyObject } else { $dupkey1 = $dirtable[$key] |sort lastwritetime -Descending | select -first 1 $dupkey2 = $dirtable[$key] |sort lastwritetime -Descending | select -skip 1 ... } }
Idea was.. $dupkey1 to $results, $dupkey2 to $duplicateHT. But the result was messed up. Directories where I had no opposite record in $source table, still shows up in $OK table instead of $Obsolete one.
Then I took a paper and draw a diagram, how the logic should work.
1) grab all keys ($keys)
2) is $DirTable[$key] found in $source?
* YES - check for duplicity records => 1 record ($results); 2+ records ($duplicateHT)* NO - all entries to $obsoleteMaybe I'm overworking this and there is much simpler way to achieve my goal.
I will propably came up with the solution before I get some reply, but.. at this moment I'm just a little bit stuck.
- Edited by Mekac Thursday, November 30, 2017 12:40 PM
Thursday, November 30, 2017 12:38 PM
Answers
-
You need to forget all of the formatting and write only the simple logic that gets the data required.
\_(ツ)_/
- Marked as answer by Mekac Friday, December 1, 2017 1:14 PM
Thursday, November 30, 2017 4:49 PM