PoshCode Logo PowerShell Code Repository

format-iislog for AWStat by Greg88 23 months ago (modification of post by Greg88 view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/3590"></script>download | new post

This script will homogenize IIS logs in preparation for use with AWStats. It is useful in situations where log formats have changed over the course of a given reporting period. In order to achieve the specified format, null fields will be inserted (as a hyphen) and unwanted fields will be dropped. In this way, logs can be bulk imported into AWStats while avoiding excessive modification of the “Logfile” configuration parameter. Loosely based on http://poshcode.org/3253

Usage:

.\format-iislog.ps1 [old log path] [desired fields] [revised log output file path]

Single log file
.\format-iislog.ps1 “C:\Old Logs\u_ex120218.log” “#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status sc-bytes time-taken” “C:\Revised Logs\u_ex120218.log”

Entire log directory
foreach ($log in (gci “c:\Old Logs”)) {.\format-iislog.ps1 $log.fullname “#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status sc-bytes time-taken” “C:\Revised Logs\$log”}

  1. param
  2. (
  3.         [Parameter(
  4.                 Mandatory=$true,
  5.                 Position = 0,
  6.                 ValueFromPipeline=$true,
  7.                 HelpMessage="Specifies the path to the IIS *.log file to import. You can also pipe a path to Import-Iss-Log."
  8.         )]
  9.         [ValidateNotNullOrEmpty()]
  10.         [string]
  11.         $Path,
  12.        
  13.     [Parameter(
  14.                 Mandatory=$true,
  15.                 Position = 1,
  16.                 ValueFromPipeline=$true,
  17.                 HelpMessage="Specifies the desired field names. Must be in the following format: #Fields: fname1 fname2"
  18.         )]
  19.         [ValidateNotNullOrEmpty()]
  20.         [string]
  21.         $NewPath,
  22.    
  23.     [Parameter(
  24.                 Mandatory=$true,
  25.                 Position = 2,
  26.                 ValueFromPipeline=$true,
  27.                 HelpMessage="Specifies the output location for the modified log file."
  28.         )]
  29.         [ValidateNotNullOrEmpty()]
  30.         [string]
  31.         $OutPath,
  32.    
  33.         [Parameter(
  34.                 Position = 3,
  35.                 HelpMessage="Specifies the delimiter that separates the property values in the IIS *.log file. The default is a spacebar."
  36.         )]
  37.         [ValidateNotNullOrEmpty()]
  38.         [string]
  39.         $Delimiter = " ",
  40.        
  41.         [Parameter(HelpMessage="The character encoding for the IIS *log file. The default is the UTF8.")]
  42.         [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]
  43.         $Encoding = [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]::UTF8
  44.    
  45. )
  46.        
  47. begin
  48.         {
  49.                 $fieldNames = @()
  50.                 $newfieldnames = @()
  51.         }
  52.  
  53. process
  54.         {
  55.  
  56.                 #add headers to new output file
  57.                  (get-content $path)[0..2] | Out-File $outpath -Append -encoding Default
  58.                  $newpath | Out-File $outpath -Append -encoding Default
  59.                
  60.                 #populate $newfieldnames from the mandatory parameter $newpath
  61.                 $newfieldNames = @($newpath.Substring("#Fields: ".Length).Split($Delimiter));
  62.                
  63.                  
  64.            
  65.         foreach($line in Get-Content -Path $Path)
  66.                 {
  67.           # Indentify / parse the log header to determine field names
  68.                 if($line.StartsWith("#Fields: "))
  69.                         {
  70.                                 $fieldNames = @($line.Substring("#Fields: ".Length).Split($Delimiter));
  71.            
  72.                         }
  73.                        
  74.                 # Identify / parse the "non log header" lines to determine field values
  75.                 elseif(-not $line.StartsWith("#"))
  76.                         {
  77.                            $logline = ""
  78.                                
  79.                            $fieldValues = @($line.Split($Delimiter));
  80.                                        
  81.                 #Initialize a hashtable to hold fields and values
  82.                 #Default value is a hyphen
  83.                 #Only fields specified in the $newpath parameter are initialized
  84.                
  85.                                 $output = @{}
  86.                                 foreach ($item in $newfieldnames)
  87.                                         {
  88.                                                         switch($item)
  89.                                                         {
  90.                                                                 "date"{ $output.add("date", "-")}
  91.                                                                 "time"{ $output.add("time", "-")}
  92.                                                                 "s-ip"{ $output.add("s-ip", "-")}
  93.                                                                 "cs-method"{ $output.add("cs-method", "-")}
  94.                                                                 "cs-uri-stem"{ $output.add("cs-uri-stem", "-")}
  95.                                                                 "cs-uri-query"{ $output.add("cs-uri-query", "-")}
  96.                                                                 "s-port"{ $output.add("s-port", "-")}
  97.                                                                 "cs-username"{ $output.add("cs-username", "-")}
  98.                                                                 "c-ip"{ $output.add("c-ip", "-")}
  99.                                                                 "cs-version"{ $output.add("cs-version", "-")}
  100.                                                                 "cs(User-Agent)"{ $output.add("cs(User-Agent)", "-")}
  101.                                                                 "sc-status"{ $output.add("sc-status", "-")}
  102.                                                                 "sc-substatus"{ $output.add("sc-substatus", "-")}
  103.                                                                 "sc-win32-status"{ $output.add("sc-win32-status", "-")}
  104.                                                                 "sc-bytes"{ $output.add("sc-bytes", "-")}
  105.                                                                 "time-taken"{ $output.add("time-taken", "-")}
  106.                                                                 "cs-host"{ $output.add("cs-host", "-")}
  107.                                                                 "cs(Cookie)"{ $output.add("cs(Cookie)", "-")}
  108.                                                                 "cs(Referer)"{ $output.add("cs(Referer)", "-")}
  109.                                                                 "s-sitename"{ $output.add("s-sitename", "-")}
  110.                                                                 "s-computername"{ $output.add("s-computername", "-")}
  111.                                                                 "cs-bytes"{ $output.add("cs-bytes", "-")}
  112.                                                         }
  113.                                         }
  114.  
  115.                                
  116.                 #Add every field from old log file to the $ouptuts hashtable
  117.                 #Portions of the hash table which are not over written at this point retain the default value (hyphen)
  118.                                 for($i = 0; $i -lt $fieldnames.Length; $i++)
  119.                                         {
  120.                                                 $name = $fieldNames[$i]
  121.                                                 $value = $fieldValues[$i]
  122.                                                                  
  123.                                                        
  124.  
  125.                                                                 switch($name)
  126.                                                                 {
  127.                                                          
  128.                                                                 "date"{ $output['date'] = $value}
  129.                                                                 "time"{ $output['time'] = $value}
  130.                                                                 "s-ip"{ $output['s-ip'] = $value}
  131.                                                                 "cs-method"{ $output['cs-method'] = $value}
  132.                                                                 "cs-uri-stem"{ $output['cs-uri-stem'] = $value}
  133.                                                                 "cs-uri-query"{ $output['cs-uri-query'] = $value}
  134.                                                                 "s-port"{ $output['s-port'] = $value}
  135.                                                                 "cs-username"{ $output['cs-username'] = $value}
  136.                                                                 "c-ip"{ $output['c-ip'] = $value}
  137.                                                                 "cs-version"{ $output['cs-version'] = $value}
  138.                                                                 "cs(User-Agent)"{ $output['cs(User-Agent)'] = $value}
  139.                                                                 "sc-status"{ $output['sc-status'] = $value}
  140.                                                                 "sc-substatus"{ $output['sc-substatus'] = $value}
  141.                                                                 "sc-win32-status"{ $output['sc-win32-status'] = $value}
  142.                                                                 "sc-bytes"{ $output['sc-bytes'] = $value}
  143.                                                                 "time-taken"{ $output['time-taken'] = $value}
  144.                                                                 "cs-host"{ $output['cs-host'] = $value}
  145.                                                                 "cs(Cookie)"{ $output['cs(Cookie)'] = $value}
  146.                                                                 "cs(Referer)"{ $output['cs(Referer)'] = $value}
  147.                                                                 "s-sitename"{ $output['s-sitename'] = $value}
  148.                                                                 "s-computername"{ $output['s-computername'] = $value}
  149.                                                                 "cs-bytes"{ $output['cs-bytes'] = $value}
  150.                                                                 }
  151.                                                                    
  152.                                                                
  153.                                         }
  154.                                                        
  155.                                 #$output
  156.                                 $linewriter = $null
  157.                 #Write lines to new log file
  158.                 #Only call upon keys (from output hash) which correspond to desired $newfieldnames as specified in $newpath parameter.
  159.                 #Unwanted fields from old log are inherently dropped
  160.                 #Newly included fields not present in old log are inherently replaced by hypens
  161.                                 foreach ($item in $newfieldnames)
  162.                                  
  163.                                         {
  164.                                                 $linewriter += $output[$item]
  165.                                                 $linewriter += " "
  166.                                         }
  167.                                  
  168.                                 $linewriter |%{$_ -replace " $",""}| Out-File $outpath -Append -encoding Default
  169.                                                          
  170.                         }
  171.                 }
  172.         }
  173.  
  174. # usage example
  175. #.\import-iislog-final.ps1 "C:\Old Logs\u_ex120218.log" "#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status sc-bytes time-taken" "C:\Revised Logs\u_ex120218.log"
  176. #foreach ($log in (gci "c:\Old Logs")) {.\import-iislog-final.ps1 $log.fullname "#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status sc-bytes time-taken" "C:\Revised Logs\$log"}

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me