Pete Hinchley: Collect Logs from Multiple Servers with PowerShell

This is an old post. There are much more efficient methods for performing this task in modern versions of PowerShell.

The code in this post is rather simplistic, and very specific to a particular task, but some of the concepts may prove useful to others.

The requirement was to copy a specific log file from a large number of servers to a central management server, search the copied logs for a specific error code, and write matched entries - using a prefix to denote the server of origin - to a consolidated "results" file.

A few points of interest:

Here is the code:

# An array of servers to be queried.
$servers = @("abc.local.net", "xyz.local.net")

# The local path (on each remote server) of the log file to be collected.
$sourcePath = "c:\logs\log.txt"

# The target folder (on the local management server) into which the log files will be collected.
$targetPath = "c:\archive"

# The path (on the local management server) to the file that will hold the matched log entries.
$searchResultPath = "C:\logs\results.txt"

# The search term.
$searchTerm = "critical error"

# The number of lines searched at the end of each log.
$tail = 100

# Do not change the code below this point.

# Substitute the "admin" share for the local path.
$sourceSharePath = $sourcePath.Replace(':', '$')

# Get the target file name.
$targetName = $sourcePath.split('\')[-1]

# Iterate through the list of servers.
$servers | %{
  $server = $_

  # Get the UNC path to the source log.
  $sourceUncPath = "\\$server\$sourceSharePath"

  # Add the server name to the target path.
  # e.g. log.txt => log.server.txt
  $uniqueTargetName = $targetName.Replace(".", "-$server.")
  $uniqueTargetPath = "$targetPath\$uniqueTargetName"

  # Check if the server is online.
  if (Test-Connection $server -Count 1 -Quiet) {
    Write-Host "$server is online."

    # Check if the source is accessible.
    if (Test-Path $sourceUncPath) {
      Write-Host "`tConnected to $server."

      # Copy the source log to the target folder.
      Write-Host "`tCopying $sourceUncPath to $uniqueTargetPath."
      Copy-Item $sourceUncPath $uniqueTargetPath -Force

      # Seach the tail of the copied log for the pattern.
      Get-Content $uniqueTargetPath -Tail $tail | Select-String $searchTerm -AllMatches | %{
        # Prefix the matched content with the name of the source server and add to the results.
        "$($server): $_" | Out-File -Append $searchResultPath
      }
    } else {
      Write-Host "`tCould not connect to $server." -foregroundcolor magenta
    }
  } else {
    Write-Host "$server is offline" -foregroundcolor magenta
  }
}