We help IT Professionals succeed at work.

Error Running OWA Audit Script

jahhan
jahhan used Ask the Experts™
on
I have a script that audit IIS log files for iPhone sessions.  Whenever I try to audit multiple servers I receive an error message of 'Cannot find path '\\ server2\c$\windows\system32\logfiles\W3SVC1\' because it does not exist. (Get-Content)      '
If I change the order to audit server 2 first I get the message for server1.
--------------------------------------------------------------
http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_26295102.html

#Name: iPhone users syncing through OWA audit
#set the timeframe to audit in days
$Daysold = 90
$Date = (get-date).adddays(-$daysold)
$servers = 'server1' , 'server2'
foreach ($s in $servers)
    {
    Write-host -ForegroundColor Blue "Checking server $s for files from the last $daysold day(s)"
    $logfiles += gci -path \\$s\c$\windows\system32\logfiles\W3SVC1 | where {$_.LastWriteTime -gt $date}
    }
Foreach ($l in $logfiles)
    {
    Write-host "Processing "$l.fullname
    Copy-item $l.fullname -Destination $pwd.path
    $listousers += gc $l.name | where {$_ -match "DeviceType="}
    Remove-Item $l.name
    }
$user = @()
foreach ($l in $listousers | where {$_ -ne $null})
    {
    $u = $l.split(" ")[8]
    if ($user -notcontains $u)
        {
        $user += "$u"
        }
    $u = $null
    }
$body = "<!DOCTYPE html PUBLIC `"-//W3C//DTD XHTML 1.0 Strict//EN`"  `"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd`">"
$body += "<html xmlns=`"http://www.w3.org/1999/xhtml`">"
$body += "<head>"
$body += "<title>iPhone Users</title>"
$body += "</head><body>"
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>iPhone Users</b></td></tr>"
foreach ($y in $user)
    {
    $body += "<tr><td>$y</td></tr>"
    }
$body += "</table>"
$body += "</body></html>"

$smtpServer = "smtpserver.com"
$mailer = new-object Net.Mail.SMTPclient($smtpserver)      
$From = "user1@test.com"
$To = "user1@test.com"
$subject = "iPhone users syncing through OWA in the last $daysold day(s)"
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)      
$msg.IsBodyHTML = $true
$mailer.send($msg)

 
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Author

Commented:
In addition, when I receive an email from the script I only see one column.  I would like to know how to update the html section to present two columns:  one showing the authenticated user and smartphone device (iphone, android, windows mobile).
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Enhanced version, kind of requires PowerShell 2 though.

Chris
#Name: iPhone users syncing through OWA audit
#set the timeframe to audit in days
$DaysOld = 90

$servers = 'server1' , 'server2'

$Servers | ForEach-Object {

  Get-ChildItem "\\$_\c$\windows\system32\logfiles\W3SVC1" | 
      Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-$DaysOld) } |
      ForEach-Object {

    Write-Progress "Copying Files" -Status "$($_.FullName)"

    Copy-Item $_.FullName "$($PWD.Path)\Working\$_.$($_.Name)"
  }
  Write-Progress "Copying Files" $_ -Completed
}

$Report = Get-ChildItem "Working" | Select-Object -First 1 | ForEach-Object {

  $Header = (Get-Content $_.FullName -TotalCount 4 | Where-Object { $_ -Match '#Fields:' })
  $Header = ($Header -Replace '#Fields: ').Split(' ', [StringSplitOptions]::RemoveEmptyEntries)

  Write-Progress "Processing Files" -Status "$($_.FullName)"

  Import-Csv $_.FullName -Delimiter ' ' -Header $Header |
    Where-Object { $_."cs-uri-query" -Match 'DeviceType' } |
    Select-Object `
      @{n='Date';e={ Get-Date "$($_.date) $($_.time)" }},
      @{n='Username';e={ $_."cs-uri-query".Split('&')[0] -Replace '^.*=' }},
      @{n='DeviceType';e={ $_."cs-uri-query".Split('&')[2] -Replace '^.*=' }}
}

Send-MailMessage -To "user1@test.com" -From "user1@test.com" `
  -Body $([String]($Report | ConvertTo-Html)) -BodyAsHtml `
  -Subject "iPhone users syncing through OWA in the last $daysold day(s)" `
  -SmtpServer "smtpserver.com"

Open in new window

Author

Commented:
Chris thanks for the script.  Unfortunately I receive the error message of 'cannot find path \\ server2\c$\windows\system32\logfiles\W3SVC1\' because it does not exist.' when the script analyzes the second server.
Chris DentPowerShell Developer
Top Expert 2010

Commented:

> \\ server2

Really with a space? Or typo with the edit?

Is it actually wrong about the path?

Chris

Author

Commented:
I re-applied the script and it now executes without an error; however, there is still a problem.  When I receive the email there is no information in the body of the message.  I checked the local logged files to confirm the entries I'm focusing on are present, which they are, but its not being reported in the email.
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Lets have it drop the report to a file, that way you can check the file as well. If the file is empty then our search through the logs is failing for some reason.

The report will be saved in the same folder as you run the script from.

Chris
#Name: iPhone users syncing through OWA audit
#set the timeframe to audit in days
$DaysOld = 90

$servers = 'server1' , 'server2'

$Servers | ForEach-Object {

  Get-ChildItem "\\$_\c$\windows\system32\logfiles\W3SVC1" | 
      Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-$DaysOld) } |
      ForEach-Object {

    Write-Progress "Copying Files" -Status "$($_.FullName)"

    Copy-Item $_.FullName "$($PWD.Path)\Working\$_.$($_.Name)"
  }
  Write-Progress "Copying Files" $_ -Completed
}

$Report = Get-ChildItem "Working" | Select-Object -First 1 | ForEach-Object {

  $Header = (Get-Content $_.FullName -TotalCount 4 | Where-Object { $_ -Match '#Fields:' })
  $Header = ($Header -Replace '#Fields: ').Split(' ', [StringSplitOptions]::RemoveEmptyEntries)

  Write-Progress "Processing Files" -Status "$($_.FullName)"

  Import-Csv $_.FullName -Delimiter ' ' -Header $Header |
    Where-Object { $_."cs-uri-query" -Match 'DeviceType' } |
    Select-Object `
      @{n='Date';e={ Get-Date "$($_.date) $($_.time)" }},
      @{n='Username';e={ $_."cs-uri-query".Split('&')[0] -Replace '^.*=' }},
      @{n='DeviceType';e={ $_."cs-uri-query".Split('&')[2] -Replace '^.*=' }}
}

$Report | Export-Csv "ReportBackup.csv"

Send-MailMessage -To "user1@test.com" -From "user1@test.com" `
  -Body $([String]($Report | ConvertTo-Html)) -BodyAsHtml `
  -Subject "iPhone users syncing through OWA in the last $daysold day(s)" `
  -SmtpServer "smtpserver.com"

Open in new window

Author

Commented:
I get a blank email.  In the Powergui app it reads 'Cannot bind argument to parameter 'InputObject' because it is null. (Export-Csv)      At line: 39 char: 21      '
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Ah... a thought... it expects to be using a Working directory, can you see if that exists? It'll be beneath the current folder if it does. I neglected to add a step into create that.

If it does exist it should contain the log files like this:

<servername>.<originallogfilename>

Chris

Author

Commented:
On my local system I do not see a folder with the title of the servers
Commented:
I was able to find a solution.  My script looks like this:
$listofusers = @()
$listofusers1= @()
$listofusers2= @()
$listofusers3= @()
$listofusers4= @()
$listofusers5= @()
$Daysold = 1
$Date = (get-date).adddays(-$daysold)
$servers = 'server1' , 'server2'
foreach ($s in $servers)
    {
    Write-host -ForegroundColor Blue "Checking server $s for files from the last $daysold day(s)"
    $logfiles += gci -path \\$s\c$\windows\system32\logfiles\W3SVC1 | where {$_.LastWriteTime -gt $date}
    }
Foreach ($l in $logfiles)
    {
    Write-host "Processing "$l.fullname
    Copy-item $l.fullname -Destination $pwd.path -Verbose
      $listousers += gc $l.name | where {$_ -match "Microsoft-Server-ActiveSync/iPhone" }
      Remove-Item $l.name
    }
            
$user = @()
foreach ($l in $listousers | where {$_ -ne $null})
    {
    $u = $l.split(" ")[8]
    if ($user -notcontains $u)
        {
        $user += "$u"
        }
    $u = $null
    }
#Android users      
Foreach ($x in $logfiles)
    {
    Write-host "Processing "$x.fullname
    Copy-item $x.fullname -Destination $pwd.path -Verbose
      $listousers1 += gc $x.name | where {$_ -match "Microsoft-Server-ActiveSync/Android" }
      Remove-Item $x.name
    }
      $user1 = @()
foreach ($x in $listousers1 | where {$_ -ne $null})
    {
    $u1 = $x.split(" ")[8]
    if ($user1 -notcontains $u1)
        {
        $user1 += "$u1"
        }
    $u1 = $null
    }
#MS Mobile users      
Foreach ($z in $logfiles)
    {
    Write-host "Processing "$z.fullname
    Copy-item $z.fullname -Destination $pwd.path -Verbose
      $listousers2 += gc $z.name | where {$_ -match "Microsoft-Server-ActiveSync/SmartPhone" }
      Remove-Item $z.name
    }
      $user2 = @()
foreach ($z in $listousers2 | where {$_ -ne $null})
    {
    $u2 = $z.split(" ")[8]
    if ($user2 -notcontains $u2)
        {
        $user2 += "$u2"
        }
    $u2 = $null
    }
#IPod Mobile users      
Foreach ($q in $logfiles)
    {
    Write-host "Processing "$q.fullname
    Copy-item $q.fullname -Destination $pwd.path -Verbose
      $listousers3 += gc $q.name | where {$_ -match "Microsoft-Server-ActiveSync/IPod" }
      Remove-Item $q.name
    }
      $user3 = @()
foreach ($q in $listousers3 | where {$_ -ne $null})
    {
    $u3 = $q.split(" ")[8]
    if ($user3 -notcontains $3)
        {
        $user3 += "$u3"
        }
    $u3 = $null
    }
#Motorola Mobile users      
Foreach ($r in $logfiles)
    {
    Write-host "Processing "$r.fullname
    Copy-item $r.fullname -Destination $pwd.path -Verbose
      $listousers4 += gc $r.name | where {$_ -match "Microsoft-Server-ActiveSync/MotoAndroid" }
      Remove-Item $r.name
    }
      $user4 = @()
foreach ($r in $listousers4 | where {$_ -ne $null})
    {
    $u4 = $r.split(" ")[8]
    if ($user4 -notcontains $u4)
        {
        $user4 += "$u4"
        }
    $u4 = $null
    }
#htcsapphire Mobile users      
Foreach ($s in $logfiles)
    {
    Write-host "Processing "$s.fullname
    Copy-item $s.fullname -Destination $pwd.path -Verbose
      $listousers5 += gc $s.name | where {$_ -match "Microsoft-Server-ActiveSync/htcsapphire" }
      Remove-Item $s.name
    }
      $user5 = @()
foreach ($s in $listousers5 | where {$_ -ne $null})
    {
    $u5 = $s.split(" ")[8]
    if ($user5 -notcontains $u5)
        {
        $user5 += "$u5"
        }
    $u5 = $null
    }
$body = "<!DOCTYPE html PUBLIC `"-//W3C//DTD XHTML 1.0 Strict//EN`"  `"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd`">"
$body += "<html xmlns=`"http://www.w3.org/1999/xhtml`">"
$body += "<head>"
$body += "<title>SmartPhone Users</title>"
$body += "</head>"
$body +="<body>"
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>iPhone Users</b></td></tr>"
foreach ($y in $user)
    {
    $body += "<tr><td>$y</td></tr>"
    }
$body += "</table>"
$body += "<BR>"
# second table      
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>Android Users</b></td></tr>"
foreach ($x in $user1)
    {
    $body += "<tr><td>$x</td></tr>"
    }
      $body += "</table>"
$body += "<BR>"
# Third table      
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>MS Mobile Users</b></td></tr>"
foreach ($z in $user2)
    {
    $body += "<tr><td>$z</td></tr>"
    }
$body += "</table>"
$body += "<BR>"
# Fourth table      
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>IPod Users</b></td></tr>"
foreach ($q in $user3)
    {
    $body += "<tr><td>$q</td></tr>"
    }
$body += "</table>"
$body += "<BR>"
# Fifth table      
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>Motorola Users</b></td></tr>"
foreach ($r in $user4)
    {
    $body += "<tr><td>$r</td></tr>"
    }
$body += "</table>"
$body += "<BR>"
# Sixth table      
$body += "<table border=1>"
$body += "<colgroup>"
$body += "<col/>"
$body += "</colgroup>"
$body += "<tr><td><b>HTCSapphire Users</b></td></tr>"
foreach ($s in $user5)
    {
    $body += "<tr><td>$s</td></tr>"
    }
$body += "<BR>"
$body += "</table>"
$body += "</body></html>"

$smtpServer = "smtp.domain.com"
$mailer = new-object Net.Mail.SMTPclient($smtpserver)      
$From = "admin@domain.com"
$To = "admin@domain.com"
$subject = "Smart Phone users syncing through OWA in the last $daysold day(s)"
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)      
$msg.IsBodyHTML = $true
$mailer.send($msg)