The customer I am working for now, asked me to search for a specific IP address in the hosts file on all the computers in the network. To achieve this goal I wrote a very quick-and-dirty PowerShell script:

$FileName = "C:\Windows\System32\drivers\etc\hosts"
$IPAdresses1 = "10.11.12.13"
$IPAdresses2 = "10.11.12.14"
$Directory = "\\server\clienthealth$\Logs"
$ComputerNames = @()

if ($Directory -ne "")
   {
    $ComputerNames    = Get-ChildItem -Path $Directory -Filter *.log | Where {$_.Name -notmatch "powershell"} | Sort-Object Path
   }

Clear-Host

$valCounter = 1
ForEach ($ComputerName in $ComputerNames)
 {

  $Computername = $ComputerName -replace(".log","")

  Write-Progress -Activity "Processing the computers" -Status "Processing computer $ComputerName" -PercentComplete ($valCounter / $ComputerNames.Count * 100)
  If(Test-Connection -Quiet -ComputerName $ComputerName -Count 1)
   {
    $LocalFileName = "\\"+$ComputerName + "\" + $FileName
    $LocalFileName = $LocalFileName -replace ":","$"
    $HostsFile = Get-Content -Path $LocalFileName | Select-String -Pattern $IPAdresses1,$IPAdresses2
    if($HostsFile -ne $Null)
     {
      Write-Host "$ComputerName has $HostsFile in the host file." 
      Write-Host "============================================================================================"
     }
   }
  $valCounter++
 }

We are using Anders Rodland Client Health script to keep our SCCM environment healthy. The log files are stored in the directory \\server\clienthealth$\logs. The log file name is equal to the computer name, with .log as the extension. So it was quite easy: just go through the log files, remove the .log part, check if the computer online, and in case yes, change C:\Windows\System32\drivers\etc\hosts to a UNC path, open it, and search for one of the IP addresses. If one of the IP addresses is found, display it on the screen. 

The usage of this script is very limited. So I added some more functionality:

  • Search not only in single files but also in multiple files in folders
  • Export the results to a CSV file
  • Mail the CSV file with the results if needed
  • Specify various options to specify the computer names:
    • All the computer names in a specific OU and its child OUs.
    • All the computer names specified in a text file
    • All the computer names can be found in the Client Health logs directory.
    • All the computer names that are mentioned as a parameter

Examples

So there are various options to search in files for specific content. 

The script:

If you want to use the mail options, you will have to modify the last part of the code and specify your own SMTP server details. When used with Office365 you are prompted to enter your Office 365 credentials. Office 365 does not allow anonymous sending of emails. 

<#
.SYNOPSIS
    Finds entries in files on remote computers.

.DESCRIPTION
    Finds entries in files on remote computers and export the computername, currently logged on user, filename and
    the entry to a CSV file. 

.EXAMPLE
    Find the entry 10.12.14.15 in c:\windows\system32\drivers\etc\hosts on computers PC1 and PC2
     ."CheckFilesForEntries (v05).ps1" -LookFor 10.12.14.15 -FileName c:\windows\system32\drivers\etc\hosts -ComputerNames PC1,PC2

.EXAMPLE
    Find the entry 80004005 in all the log files in C:\windows\ccm\logs\*.log on computers PC1 and PC2
     ."CheckFilesForEntries (v05).ps1" -LookFor 80004005 -FileName c:\windows\ccm\logs\*.log -ComputerNames PC1,PC2

.EXAMPLE
    Find the entry 80004005 in all the files in C:\windows\ccm\logs\ on computers PC1 and PC2
     ."CheckFilesForEntries (v05).ps1" -LookFor 80004005 -FileName c:\windows\ccm\logs\ -ComputerNames PC1,PC2

.EXAMPLE
    Find the entry 80004005 in all the files in C:\windows\ccm (and its subfolders) on computers PC1 and PC2
     ."CheckFilesForEntries (v05).ps1" -LookFor 80004005 -FileName c:\windows\ccm\ -ComputerNames PC1,PC2 -IncludeSubFolders

.EXAMPLE
    Find the entry 10.12.14.15 in c:\windows\system32\drivers\etc\hosts on computers PC1 and PC2 and mail the CSV file. 
     ."CheckFilesForEntries (v05).ps1" -LookFor 10.12.14.15 -FileName c:\windows\system32\drivers\etc\hosts -ComputerNames PC1,PC2 -MailCSVFile

.EXAMPLE
    Find the entry's 10.12.14.15 or 10.12.14.16 in c:\windows\system32\drivers\etc\hosts on all the computernames which logfiles are in the folder \\server\share\ClientHealth\log
     ."CheckFilesForEntries (v05).ps1" -LookFor 10.12.14.15,10.12.14.15 -FileName c:\windows\system32\drivers\etc\hosts -Directory \\server\share\ClientHealth\log

.EXAMPLE
    Find the entry's 10.12.14.15 or 10.12.14.16 in c:\windows\system32\drivers\etc\hosts on all the computernames which logfiles are in the folder \\server\share\ClientHealth\log.
    Show also the records where the search item is not found or the computer is offline in the results file. 
     ."CheckFilesForEntries (v05).ps1" -LookFor 10.12.14.15,10.12.14.15 -FileName c:\windows\system32\drivers\etc\hosts -Directory \\server\share\ClientHealth\log -ShowNotFounds

.NOTES
    Author:  Willem-Jan Vroom
    Website: https://www.vroom.cc/
    Twitter: @TheStingPilot

v0.1:
   * Initial version.

v0.2:
   * Added the function Test-RemoteManagement to test if there is a valid WSMan Remote connection. 
   * The delimiter character has been changed to ';'. 

v0.3:
   * The mail function does not delete the attachment if the mailsend has failed.
   * Implemented: ShowNotFounds.

v0.4:
   * Improved the search for files, that made it possible to eliminate 2 ForEach loops. :-) And a speed increase. 
   * It is also possible to search on shares, solved an issue in the functions:
       - Convert-ToUNCShare
       - Convert-BackFromUNCShare
   * Implemented: IncludeSubFolders
   * Get-Content is run locally via an Invoke-Command. That speeds up the process!

v0.5:
   * The query the find the files is run on the computer instead of the computer where the script is running from.

#>

[CmdLetBinding(DefaultParameterSetName = 'Computers')]

param
  (
   [Parameter(HelpMessage='Specify the computer names, comma seperated.')]
   [Parameter(Mandatory=$true,  ParameterSetName = 'Computers')] 
   [string[]] $ComputerNames,

   [Parameter(HelpMessage='Specify a file name that contains all the computer names.')]
   [Parameter(Mandatory=$true,  ParameterSetName = 'FileWithComputerNames')]
   [String]   $Inputfile = "",

   [Parameter(HelpMessage='Specify the directory that contains all the computer names.')]
   [Parameter(Mandatory=$true,  ParameterSetName = 'DirWithComputerNames')]
   [String]   $Directory = "",

   [Parameter(HelpMessage='Specify the OU that contains all the computer names.')]
   [Parameter(Mandatory=$true,  ParameterSetName = 'OUWithComputerNames')]
   [String]   $OU = "",

   [Parameter(HelpMessage='Specify the log path.')]
   [Parameter(Mandatory=$false, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$false, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [String]   $LogPath = "\\ins.local\sys\Afdeling\Werkplek Services\Scripts\PowerShell_AddonsClientHealthScript\OUTPUT",

   [Parameter(HelpMessage='Specify the full file names where should be searched in. If more than one file name, the seperate them by a comma.')]
   [Parameter(Mandatory=$true, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$true, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$true, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [String[]] $FileNames = "",

   [Parameter(HelpMessage='Specify what should the searched for. I more than one item, then seperate them by a comma.')]
   [Parameter(Mandatory=$true, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$true, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$true, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [String[]] $LookFor = "",

   [Parameter(HelpMessage='Show the not founds in the results file.')]
   [Parameter(Mandatory=$false, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$false, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [Switch]   $ShowNotFounds,

   [Parameter(HelpMessage='Include subfolders for the file names.')]
   [Parameter(Mandatory=$false, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$false, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [Switch]   $IncludeSubFolders,

   [Parameter(HelpMessage='Mail the results file.')]
   [Parameter(Mandatory=$false, ParameterSetName = 'Computers')]
   [Parameter(Mandatory=$false, ParameterSetName = 'FileWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'DirWithComputerNames')]
   [Parameter(Mandatory=$false, ParameterSetName = 'OUWithComputerNames')]
   [Switch]   $MailCSVFile

  )
# =============================================================================================================================================
# script block
# =============================================================================================================================================

$GetLocalFiles = {

param
 (
  [String[]] $arrFileNames,
  [String[]] $arrLookFor,
  [Bool]     $bolShowNotFounds,
  [Bool]     $bolIncludeSubFolders
 )

 $Table = @()

 $Record = [ordered] @{"LocalFileName" = "";
                       "Entry"         = "";
                       "Line"          = "";
                       "Remark"        = ""}


 # =============================================================================================================================================
 # Make sure that the variable $MatchingFiles only contains files, no folders. 
 # If the path c:\windows\ccm is used, than both files and folders are returned.
 # If the path c:\windows\ccm\*.* is used, than only files are returned.
 # =============================================================================================================================================
        
   if ($arrFileNames.Count -gt 0)
    {
     $MatchingFiles    = Get-ChildItem -Path $arrFileNames -Recurse:$bolIncludeSubFolders -ErrorAction SilentlyContinue| where { $_.GetType().Name -eq "FileInfo" }
     $valNumberofFiles = $MatchingFiles.Count 
     $valFilesCounter  = 1

     ForEach ($MatchingFile in $MatchingFiles)
      {
       Write-Progress -Id 3 -ParentId 2 -Activity "Processing file $($MatchingFile.FullName).   (File $valFilesCounter of $valNumberofFiles files)." -PercentComplete ($valFilesCounter / $valNumberofFiles * 100)
       ForEach ($Entry in $arrLookFor)
        {
         $bolFound      = $False
         Try
          {
           $Content = Get-Content -Path $MatchingFile.FullName -ErrorAction SilentlyContinue -ErrorVariable ErrorText | Select-String -Pattern $Entry
           if($Content -ne $NULL)
            { 
             $bolFound = $True
             ForEach ($Line in $Content)
              { 
               $Record."LocalFileName"  = $MatchingFile.FullName
               $Record."Entry"  = $Entry
               $Record."Line"   = $Line
               $Record."Remark" = ""
               $Table          += New-Object PSObject -Property $Record
              }
            }
           if (-not($bolFound) -and $bolShowNotFounds)
            {
             $Record."LocalFileName"  = $MatchingFile.FullName
             $Record."Entry"  = ""
             $Record."Line"   = ""
             $Record."Remark" = "'$Entry' not found in '$($MatchingFile.FullName)'."
             $Table          += New-Object PSObject -Property $Record
            }
          }
         Catch
          {
           #Write-EntryToResultsFile -PCName $ComputerName          `
           #                         -LocalFileName $LocalFileName  `
           #                         -Remark $ErrorText
          }
        }
       $valFilesCounter ++
      }
      Write-Progress -Id 3 -ParentId 2 -Activity "Processing file $($MatchingFile.FullName).   (File $valFilesCounter of $valNumberofFiles files)." -Completed
    }

   Return $Table
}

# =============================================================================================================================================
# End script block
# =============================================================================================================================================

# =============================================================================================================================================
# Function block
# =============================================================================================================================================

  Function Test-RemoteManagement

   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       15-January-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Test-RemoteManagement
    Source:           https://jdhitsolutions.com/blog/powershell/5014/friday-fun-a-better-test-wsman/
    =============================================================================================================================================
    .SYNOPSIS

    Converts a given filepath to a UNC share.

    #>

    Param
     (
      [String]  $ComputerName
     )

     $Result = Test-WSMan $ComputerName -ErrorAction SilentlyContinue
     
     if($Result)
      {
       Return $True
      }
       else
      {
       Return $false
      }
   }

Function Get-IPAddress
 {
     <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       08-January-2019
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-IPAdress
    =============================================================================================================================================
    .SYNOPSIS

    This function gets the IP address of the given computer.
    #>

    Param
     (
      $ComputerName = ""
     )

    Try
     {
      $Network    = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -ErrorAction SilentlyContinue
     }
      Catch
     {
      $Network    = $NULL
     }

    $IP4orIP6Address = ""
    
    if($Network -ne $Null)
     {
      ForEach ($IPAddress in ($Network.IPAddress))
       {
        if([IPAddress] $IPAddress)
         {
          if ($IP4orIP6Address -eq "")
           {$IP4orIP6Address = $IPAddress} 
            else
           {$IP4orIP6Address = $IP4orIP6Address + " \ " + $IPAddress}
         }
       }
     }
     Return $IP4orIP6Address
 }

 Function Get-Site
 {
     <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       08-January-2019
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-Site
    =============================================================================================================================================
    .SYNOPSIS

    This function gets the site name of the given computer.

    SOURCE: https://www.powershellmagazine.com/2013/04/23/pstip-get-the-ad-site-name-of-a-computer/
    #>

    Param
     (
      $ComputerName = ""
     )

    $RegKeyName   = "SYSTEM\CurrentControlSet\services\Netlogon\Parameters"
    $RegValueName = "DynamicSiteName"

    $Site = (([Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)).OpenSubkey($RegKeyName)).GetValue($RegValueName)

    Return $Site    
    
 }


Function Get-LoggedOnUser
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       11-December-2019
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-LoggedOnUser
    =============================================================================================================================================
    .SYNOPSIS

    This function gets the current logged on user of a computer.

    #>

    param
     (
      [String] $ComputerName
     )
    Try
     {
      $UserName      = ((Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName -ErrorAction SilentlyContinue).UserName).Split("\")[-1]
      $DisplayName   = (Get-ADUser -Filter {SamAccountName -eq $UserName} -Properties DisplayName -ErrorAction SilentlyContinue).DisplayName
     }
      Catch
     {
      $DisplayName   = ""
     }
        
    Return $DisplayName
   }

Function Get-DateTimeFromSCCMLogEntry
   {
     <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       29 January 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-DateTimeFromSCCMLogEntry
    Source:           https://blog.richprescott.com/2017/07/sccm-log-parser.html
    =============================================================================================================================================
    .SYNOPSIS

    This function gets the date and time from a SCCM Log file line.
    #>

    Param
     (
      $LogLine = ""
     )

     Write-Verbose "The logfileline: $LogLine"
     $Time = $LogLine -match '\<\!\[LOG\[(?<Message>.*)?\]LOG\]\!\>\<time=\"(?<Time>.+)(?<TZAdjust>[+|-])(?<TZOffset>\d{2,3})\"\s+date=\"(?<Date>.+)?\"\s+component=\"(?<Component>.+)?\"\s+context="(?<Context>.*)?\"\s+type=\"(?<Type>\d)?\"\s+thread=\"(?<TID>\d+)?\"\s+file=\"(?<Reference>.+)?\"\>'

     if($Time)
      {
       $LocalTime = [datetime]::ParseExact($("$($matches.date) $($matches.time)"),"MM-dd-yyyy HH:mm:ss.fff", $null)
       Return $LocalTime
      }      
      
     Return ""
     
   } 

Function Write-EntryToResultsFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Write-EntryToResultsFile
    =============================================================================================================================================
    .SYNOPSIS

    This function adds the success or failure information to the array that contains the log
    information.

    #>

    Param
     (
      [String]  $PCName                  = "",
      [String]  $LocalFileName           = "",
      [String]  $FoundEntry              = "",
      [String]  $Line                    = "",
      [String]  $Remark                  = ""
     )

    $ADSite            = ""
    $UsernameToDisplay = ""
    $IP                = ""

    if((Test-Connection -ComputerName $PCName -Count 1 -Quiet) -and (Test-RemoteManagement -ComputerName $PCName))
     {
      $ADSite            = Get-Site -ComputerName $PCName
      $UsernameToDisplay = Get-LoggedOnUser -ComputerName $PCName
      $IP                = Get-IPAddress -ComputerName $PCName
     }
    $Timestamp         = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
    $SCCMLogFileTime   = Get-DateTimeFromSCCMLogEntry -LogLine $Line

    $Record  = [ordered] @{"Timestamp"                 = "";
                           "ComputerName"              = "";
                           "IP Address"                = "";
                           "AD Site"                   = "";
                           "Username"                  = "";
                           "Time in SCCM Log File"     = "";
                           "Local file name"           = "";
                           "Found entry"               = "";
                           "Line"                      = "";
                           "Remark"                    = ""
                           }
    
    $Record."Timestamp"                  = $Timestamp
    $Record."ComputerName"               = $PCName
    $Record."IP Address"                 = $IP
    $Record."AD Site"                    = $ADSite
    $Record."Username"                   = $UsernameToDisplay
    $Record."Time in SCCM Log File"      = $SCCMLogFileTime
    $Record."Local file name"            = $LocalFileName
    $Record."Found entry"                = $FoundEntry
    $Record."Line"                       = $Line
    $Record."Remark"                     = $Remark
    $objRecord                           = New-Object PSObject -Property $Record
    $Global:arrTable                    += $objRecord

    Write-Verbose ">>  Write-EntryToResultsFile" 
    Write-Verbose "--> Entry written to the logfile:"
    Write-Verbose "     Timestamp                   = $Timestamp"
    Write-Verbose "     ComputerName                = $PCName"
    Write-Verbose "     IP Address                  = $IP"
    Write-Verbose "     AD Site                     = $ADSite"
    Write-Verbose "     Username                    = $UsernameToDisplay"
    Write-Verbose "     Time in SCCM Log File       = $SCCMLogFileTime"
    Write-Verbose "     Local file name             = $LocalFileName"
    Write-Verbose "     Found entry                 = $FoundEntry"
    Write-Verbose "     Line                        = $Line"
    Write-Verbose "     Remark                      = $Remark"
    Write-Verbose ""
    Write-Verbose "#################################################################"

   }

  Function Export-ResultsLogFileToCSV
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-September-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Export-ResultsLogFileToCSV
    =============================================================================================================================================
    .SYNOPSIS

    This function writes the logfile content to a CSV file.

    #>

    If($Global:arrTable.Count -gt 0)
     {
      $Global:arrTable | Sort-Object -Property ComputerName,"Local file name" | Export-Csv $strCSVLogFileSucces -NoTypeInformation -Delimiter ";"
      Write-Verbose ">> Export-ResultsLogFileToCSV: The file '$strCSVLogFileSucces' has been written." 
     } 
      else
     {
      Write-Error "Something went wrong while writing the logfile '$strCSVLogFileSucces'. Maybe nothing to report..." -Category CloseError 
     } 
   }
 
Function Mail-CSVResultsFile
  {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       09-January-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Mail-CSVResultsFile
    =============================================================================================================================================
    .SYNOPSIS

    Mails the CSV file with the results.

    #>

    Param
     (
      [String]    $Sendername,
      [String[]]  $Recipients,
      [String]    $Attachment,
      [String]    $Subject = "Overview",
      [String]    $SMTPServer,
      [String]    $SMTPPort = 25,
      [Switch]    $SSL,
      [Switch]    $Anonymous
     )

   $SMTPCredentials    = ""
   $ErrorText          = @()
   $bolSuccess         = $True
   $AttachmentFileName = $Attachment.Split("\")[-1]
   if(-not($Anonymous))
    {
    $SMTPCredentials = (Get-Credential)
    }

   $MessageBody = "Hello, 
   
   Please find attached the latest overview of $AttachmentFileName.
   
   With kind regards,
   Willem-Jan Vroom
   "

   if($SSL)
    {
     Write-Verbose "Mail via SSL"
     Send-MailMessage -From $Sendername            `
                      -To $Recipients              `
                      -SmtpServer $SMTPServer      `
                      -Attachments $Attachment     `
                      -Subject $Subject            `
                      -Body $MessageBody           `
                      -Port $SMTPPort              `
                      -Credential $SMTPCredentials `
                      -UseSSL                      `
                      -ErrorVariable ErrorText     `
                      -ErrorAction SilentlyContinue
    }
   else
    {
     Write-Verbose "Mail not via SSL"
     Send-MailMessage -From $Sendername            `
                      -To $Recipients              `
                      -SmtpServer $SMTPServer      `
                      -Attachments $Attachment     `
                      -Subject $Subject            `
                      -Body $MessageBody           `
                      -Port $SMTPPort              `
                      -ErrorVariable ErrorText     `
                      -ErrorAction SilentlyContinue               
    }
  
  if ($ErrorText.Count -gt 0)
   {
    Write-Verbose "SMTP Error text: $ErrorText"
    $bolSuccess = $false
   }

  Return $bolSuccess

  }

# =============================================================================================================================================
# End function block
# =============================================================================================================================================

# =============================================================================================================================================
# Define the variables
# =============================================================================================================================================

  Clear-Host
  
  $Global:arrTable   = @()
  $Results           = @()
  $valCounter        = 1
  $bolMaxComputers   = $False

  if($LogPath -eq "")
   {
    $LogPath   = Split-Path -parent $MyInvocation.MyCommand.Definition
   }
    elseif(-not(Test-Path $('FileSystem::' + $LogPath)))
   {
    New-Item -Path $LogPath -ItemType Directory | Out-Null
    Sleep 1
    if(test-path $('FileSystem::' + $LogPath))
     {
      Write-Verbose "The folder '$LogPath' has been created."
     }
      else
     {
      Write-Error "Something went wrong while creating the folder '$LogPath'. " -Category OpenError
      Exit 2
     }
   }
    else
   {
    Write-Verbose "The folder $LogPath already exists."
   }

# =============================================================================================================================================
# Read the file with all the computer names
# Skip empty lines.
# =============================================================================================================================================
 
  if($Inputfile -ne "")
   {
    if(Test-Path($Inputfile))
     { 
      $ComputerNames = @((Get-Content -Path $Inputfile).Trim() | Where {$_.Length -gt 0})
      Write-Verbose "The inputfile '$Inputfile' has been read."
     }
      else
     {
      Write-Host "The file '$Inputfile' does not exists. Thus quitting."
      Exit 1
     }
   }

# =============================================================================================================================================
# Read the directory with all the computer names
# =============================================================================================================================================

  if ($Directory -ne "")
   {
    $ComputerNames = @(Get-ChildItem -Path $Directory -Filter *.log | Where {$_.Name -notmatch "powershell"} | Sort-Object Path)
   }

# =============================================================================================================================================
# Read the OU with all the computer names
# =============================================================================================================================================

  if ($OU -ne "")
   {
    Try
     {
      Write-Verbose "Reading the computers from the OU $OU and its sub-OU's." 
      $ComputerNames = @((Get-ADComputer -Filter {Enabled -eq "True"} -SearchScope SubTree -SearchBase $OU -Properties cn).cn)
     }
      Catch
     {
      Write-Host "There is an error: $($_.Exception.Message). Check if '$OU' exists."
      Exit 1
     }
   }

# =============================================================================================================================================
# Count the number of computers. If zero, then quit.
# =============================================================================================================================================

  if($ComputerNames.Count -eq 0)
   {
    Write-Host "There are no computers to process!"
    Exit 2
   }

# =============================================================================================================================================
# Get unique computernames.
# =============================================================================================================================================

  $ComputerNames = $ComputerNames | Get-Unique | Sort-Object
  Write-Verbose "The following $($ComputerNames.Count) computers will be processed:"
  ForEach ($ComputerName in $ComputerNames)
   {
    Write-Verbose "Computername: $Computername."
   }

# =============================================================================================================================================
# Define the log file. This log file contains all the results.
# The filename may contain maximum of 3 computer names. Otherwise the filename may be too long.
# =============================================================================================================================================

  $ComputerNameForFileName = ""
  ForEach ($Computer in $ComputerNames)
   {
    $ComputerNameForFileName = "$ComputerNameForFileName $($Computer -replace(".log"))"
    if($valCounter -ge 3)
     {
      $bolMaxComputers = $true
      Break
     }
    $valCounter++
   }
 
  $ComputerNameForFileName = "SearchInFilesForEntries_" + $(($ComputerNameForFileName.Substring(1)).Replace(" ","_"))

  If($bolMaxComputers)
   {
    $ComputerNameForFileName += " (PLUS $($ComputerNames.Count - $valCounter) MORE)"
   }

  $strLastPartOfFileName = " (" + (Get-Date).ToString('G') + ").csv"
  $strLastPartOfFileName = $strLastPartOfFileName -replace ":","-"
  $strLastPartOfFileName = $strLastPartOfFileName -replace "/","-"

  $strCSVLogFileSucces   = $LogPath + "\"+ $ComputerNameForFileName + $strLastPartOfFileName

# =============================================================================================================================================
# Go through the list of computers
# =============================================================================================================================================

  $valCounter = 1
  $Starttime = (Get-Date)
  ForEach ($ComputerName in $ComputerNames)
   {
  
    # =============================================================================================================================================
    # Check if the computer can be reached
    # If so, continue.
    # =============================================================================================================================================
      
      $Computername = $ComputerName -replace(".log")
      If ($ComputerName -eq ".")
       {
        $ComputerName = $env:COMPUTERNAME
       }
      Write-Verbose "Processing computer $ComputerName"
      Write-Progress -Id 2 -Activity "Processing computer $ComputerName   ($valCounter of $($ComputerNames.Count) computers)." -PercentComplete ($valCounter / $ComputerNames.Count * 100)
      If((Test-Connection -Quiet -ComputerName $ComputerName -Count 1) -and (Test-RemoteManagement -ComputerName $ComputerName))
       {
        $Results = Invoke-Command -ComputerName $ComputerName -ScriptBlock $GetLocalFiles -ArgumentList @($FileNames),@($LookFor),$ShowNotFounds,$IncludeSubFolders
        $valNumberOfResults = $Results.Count
        $valResultsCounter  = 1
        ForEach ($Result in $Results)
         {
          Write-Progress -Id 3 -ParentId 2 -Activity "Processing the results ($valResultsCounter of $valNumberOfResults)" -PercentComplete ($valResultsCounter / $valNumberOfResults * 100) 
          Write-EntryToResultsFile -PCName $ComputerName                   `
                                   -LocalFileName $($Result.LocalFileName) `
                                   -FoundEntry $($Result.Entry)            `
                                   -Line $($Result.Line) -Remark $($Result.Remark)
          $valResultsCounter ++     
         }
        Write-Progress -Id 3 -ParentId 2 -Activity "Processing the results ($valResultsCounter of $valNumberOfResults)" -Completed
       }
        else
       {
        Write-Verbose "The computer $ComputerName appears to be offline."
       }
     $valCounter++
   }

# =============================================================================================================================================
# Export the CSV file and mail it.
# Exit afterwards.
# =============================================================================================================================================

  $EndTime = (Get-Date)
  Export-ResultsLogFileToCSV

  If($Global:arrTable.Count -gt 0 -and $MailCSVFile)
   {    
     If(Mail-CSVResultsFile -Sendername "This email address is being protected from spambots. You need JavaScript enabled to view it."                      `
                         -Recipients @("This email address is being protected from spambots. You need JavaScript enabled to view it.","This email address is being protected from spambots. You need JavaScript enabled to view it.") `
                         -SMTPServer "smtp.office365.com"                           `
                         -SMTPPort 587                                              `
                         -SSL                                                       `
                         -Attachment $strCSVLogFileSucces                           `
                         -Subject "Overview") 
       {
        Remove-Item -Path $strCSVLogFileSucces -Confirm:$false | Out-Null
       }
        else
       {
        Write-Host "There was a problem with sending the message."
        Write-Host "The mail has not been sent and the file '$strCSVLogFileSucces' has not been deleted." 
       }

   }

  $Duration = $EndTime - $Starttime

  Write-Host "Script execution took $Duration seconds." 

  Exit 0

Download the zip file CheckFilesForEntries_v05.zip

Before download...

Continue... ×

Download the zip file CheckFilesForEntries_v04.zip

Before download...

Continue... ×

Download the zip file CheckFilesForEntries_v03.zip

Before download...

Continue... ×

Download the zip file CheckFilesForEntries_v02.zip

Before download...

Continue... ×

Download the zip file CheckFilesForEntries_v01.zip

Before download...

Continue... ×