Solved

Script to check IIS logging status of multiple servers.

Posted on 2009-07-08
31
934 Views
Last Modified: 2012-05-07
Please help me to get a script to check IIS logging status of multiple servers.
The script should read the list of servers from a text file and send the report to a distribution list.
Report sample:
------------------------------------------------------------------------------
Name             :        Server1
IIS Logging       :       Enabled
Log Path       :      C:\WINDOWS\system32\LogFiles
Log files Size      :      1 GB
------------------------------------------------------------------------------
Name             :        Server2
IIS Logging       :       Disabled
Log Path       :      C:\WINDOWS\system32\LogFiles
Log files Size      :      NA
------------------------------------------------------------------------------
IISLOG.GIF
0
Comment
Question by:Subsun
  • 18
  • 13
31 Comments
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24802678

This is easier in PowerShell 2.... In PowerShell 1 you have to mess around to get PacketPrivacy on the connection, IIS requires that. So the code I'm giving you is at the bottom.

If you happen to be using PowerShell 2 (CTP) then you can replace the WMI part with this, feeling that into the existing Select-Object statement:

Get-WMIObject -NameSpace root\MicrosoftIISv2 -Class IIsWebServerSetting `
    -ComputerName $Server -Authentication PacketPrivacy

Chris
$Results = @()

ForEach ($Server in Get-Content "ServerList.txt") {

  $WMI = New-Object Management.ManagementScope("\\$Server\root\MicrosoftIISv2")

  $WMI.Options.Authentication = "PacketPrivacy"

  $Query = New-Object Management.ObjectQuery( `

    "SELECT Name, LogFileDirectory, LogFileTruncateSize, LogType, LogFilePeriod FROM IIsWebServerSetting")
 

  $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

  $Results += $Searcher.Get() | Select-Object `

    @{n='Name';e={ $Server }}, `

    @{n='Site';e={ $_.Name }}, `

    @{n='IIS Logging';e={

      Switch ($_.LogType) {

        0 { "Disabled" }

        1 { "Enabled" }

      } }}, `

    @{n='Log Path';e={ $_.LogFileDirectory }}, `

    @{n='Log File Size';e={ 

      If ([Int]$_.LogFileTruncateSize -eq -1) { "Unlimited" } else { 

        "$([Int]$_.LogFileTruncateSize / 1Gb) Gb" } }}

}

$Results

Open in new window

0
 
LVL 40

Author Comment

by:Subsun
ID: 24802921
Excellent.!!!!!!!!.. How do I send it through email?
0
 
LVL 70

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 24803008

It depends how you want it in the email. If you like it in-line the first is for you, if you prefer attachments then the second should be good.

You'll need to update all the fields (to address, from address, mail server, etc).

Chris
$Results = @()

ForEach ($Server in Get-Content "ServerList.txt") {

  $WMI = New-Object Management.ManagementScope("\\$Server\root\MicrosoftIISv2")

  $WMI.Options.Authentication = "PacketPrivacy"

  $Query = New-Object Management.ObjectQuery( `

    "SELECT Name, LogFileDirectory, LogFileTruncateSize, LogType, LogFilePeriod FROM IIsWebServerSetting")

 

  $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

  $Results += $Searcher.Get() | Select-Object `

    @{n='Name';e={ $Server }}, `

    @{n='Site';e={ $_.Name }}, `

    @{n='IIS Logging';e={

      Switch ($_.LogType) {

        0 { "Disabled" }

        1 { "Enabled" }

      } }}, `

    @{n='Log Path';e={ $_.LogFileDirectory }}, `

    @{n='Log File Size';e={ 

      If ([Int]$_.LogFileTruncateSize -eq -1) { "Unlimited" } else { 

        "$([Int]$_.LogFileTruncateSize / 1Gb) Gb" } }}

}

$Results
 

#

# Sending results as the body (HTML)

#
 
 

# Generate the body as HTML

$Body = $Results | ConvertTo-HTML
 

# Create the mail message using $Body

$MailMessage = New-Object System.Net.Mail.MailMessage( `

  "FromAddress@domain.com", `

  "ToAddress@domain.com", `

  "IIS Log Settings", `

  $Body)
 

# Make the mail HTML

$MailMessage.IsBodyHTML = $True
 

# Send the message using "mailserver.domain.com"

$SmtpClient = New-Object System.Net.Mail.SmtpClient("mailserver.domain.com")

$SmtpClient.Send($MailMessage)
 
 
 

#

# Sending results as an attachment

#
 
 
 

# Export Results to $FileName

$FileName = "IISLogSettings.csv"

$Results | Export-CSV $FileName

$File = Get-Item $FileName
 

# Create the mail message

$MailMessage = New-Object System.Net.Mail.MailMessage( `

  "FromAddress@domain.com", `

  "ToAddress@domain.com", `

  "IIS Log Settings", `

  "Please review attachment")
 

# Create the attachment object

$Attachment = New-Object System.Net.Mail.Attachment($File.FullName, `

  [System.Net.Mime.MediaTypeNames].Text.Plain)

$Attachment.ContentDisposition.CreationDate = $File.CreationTime

$Attachment.ContentDisposition.ModificationDate = $File.LastWriteTime

$Attachment.ContentDisposition.ReadDate = $File.LastAccessTime
 

# Add the attachment onto the mail message

$MailMessage.Attachments.Add($Attachment)
 

# Send the message using "mailserver.domain.com"

$SmtpClient = New-Object System.Net.Mail.SmtpClient("mailserver.domain.com")

$SmtpClient.Send($MailMessage)
 

# Unlock the attachment file

$Attachment.Dispose()

Open in new window

0
 
LVL 40

Author Closing Comment

by:Subsun
ID: 31601127
Thanks Chris, you are really a genius. I prefer the first one (Inline). IN the HTML mail, Is there any way to highlight the enabled one in Red and disabled one in green? (I only need to highlight the specific word, If it prints disabled it should be in green, if it prints enabled then green). Not a necessary but if it can be done it will be great, Coz we have some 56 servers to report :(, and it will be easy to identify the red ones.. :)
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24804338

Sure... why not :) Just have to hack the HTML it makes for us a bit.

There was one more attribute I meant to comment on and add.

LogFilePeriod if set to 1 means the site is set to use dates to roll logs rather than size. It seemed important to your configuration here, after all, LogFileTruncateSize will always be set, by default it's 20Mb. Anyway, it's added to the output now.

Chris
$Results = @()

ForEach ($Server in Get-Content "ServerList.txt") {

  $WMI = New-Object Management.ManagementScope("\\$Server\root\MicrosoftIISv2")

  $WMI.Options.Authentication = "PacketPrivacy"

  $Query = New-Object Management.ObjectQuery( `

    "SELECT Name, LogFileDirectory, LogFileTruncateSize, LogType, LogFilePeriod FROM IIsWebServerSetting")

 

  $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

  $Results += $Searcher.Get() | Select-Object `

    @{n='Name';e={ $Server }}, `

    @{n='Site';e={ $_.Name }}, `

    @{n='IIS Logging';e={

      Switch ($_.LogType) {

        0 { "Disabled" }

        1 { "Enabled" } 

      } }}, `

    @{n='Log Path';e={ $_.LogFileDirectory }}, `

    @{n='Log File Size';e={ 

      If ([Int]$_.LogFileTruncateSize -eq -1) { "Unlimited" } else { 

        "$([Int]$_.LogFileTruncateSize / 1Gb) Gb" } }}, `

    @{n='Log File Rollover';e={

      Switch ($_.LogFilePeriod) {

        0 { "Size" }

        1 { "Date" } 

      } }}

}

 

#

# Sending results as the body (HTML)

#

 

# Generate the body as HTML

$Body = $Results | ConvertTo-HTML
 

# Highlight words

$Body = $Body -Replace "Enabled", "<font color='green'>Enabled</font>"

$Body = $Body -Replace "Disabled", "<font color='red'>Disabled</font>"

 

# Create the mail message using $Body

$MailMessage = New-Object System.Net.Mail.MailMessage( `

  "FromAddress@domain.com", `

  "ToAddress@domain.com", `

  "IIS Log Settings", `

  $Body)

 

# Make the mail HTML

$MailMessage.IsBodyHTML = $True

 

# Send the message using "mailserver.domain.com"

$SmtpClient = New-Object System.Net.Mail.SmtpClient("mailserver.domain.com")

$SmtpClient.Send($MailMessage)

Open in new window

0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24804363

Hmm I might have the highlighting the wrong way around :) Hopefully it's easy enough for you to see and fix :)

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24804587
Sure.. I'll check it.. Thanks a lot.. I need to get one more script to collect the disk space usage for multiple servers.. so catch you later.. :)
0
 
LVL 40

Author Comment

by:Subsun
ID: 24811619

One Small help. ;-).. The script work like a treat. My question is, in report I can see the columns when I highlight the text. Can we make the columns visible?

In simple language can we put the result in columns?

IIS.JPG
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24811646

Make them invisible you mean?

We could collapse the borders, play with HTML styles, not sure if that'll give you what you're looking for though?

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24811709
Need to make the columns visible.
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24811715

Ohhh sorry... yeah, we can do that :) Sorry... bit early in the morning (not finished coffee). One moment :)

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24811722
No hurry :)
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24811791

How's this?

The styles we're applying are CSS, so not really anything to do with PowerShell.

If you're not familiar with CSS, we have:

table { border-collapse: collapse }

This gets rid of white space between cell borders.

td, th { border-width: 2px; border-style: solid; text-align: left; padding: 2px 4px }

td (Table Data) and td (Table Header) are the components of the table. We have set the border width to 2 pixels, the style to solid (default colour is black). I changed the text alignment to left for the table header, I don't like the centred look personally. And it looks a bit squashed, so we have 2 pixels of padding at the top and bottom of each cell, and 4 pixels either side.

Best way to play with this is to run:

$Body > "test.html"

Then open up that in Notepad and edit the parts between <Style> until you're happy.

Chris
$Results = @()

ForEach ($Server in Get-Content "ServerList.txt") {

  $WMI = New-Object Management.ManagementScope("\\$Server\root\MicrosoftIISv2")

  $WMI.Options.Authentication = "PacketPrivacy"

  $Query = New-Object Management.ObjectQuery( `

    "SELECT Name, LogFileDirectory, LogFileTruncateSize, LogType, LogFilePeriod FROM IIsWebServerSetting")

 

  $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

  $Results += $Searcher.Get() | Select-Object `

    @{n='Name';e={ $Server }}, `

    @{n='Site';e={ $_.Name }}, `

    @{n='IIS Logging';e={

      Switch ($_.LogType) {

        0 { "Disabled" }

        1 { "Enabled" } 

      } }}, `

    @{n='Log Path';e={ $_.LogFileDirectory }}, `

    @{n='Log File Size';e={ 

      If ([Int]$_.LogFileTruncateSize -eq -1) { "Unlimited" } else { 

        "$([Int]$_.LogFileTruncateSize / 1Gb) Gb" } }}, `

    @{n='Log File Rollover';e={

      Switch ($_.LogFilePeriod) {

        0 { "Size" }

        1 { "Date" } 

      } }}

}

 

#

# Sending results as the body (HTML)

#
 

# Create a header containing a style for the generated HTML

$Head = "<style type='text/css'>`r`n" + `

  "table { border-collapse: collapse }`r`n" + `

  "td, th { border-width: 2px; border-style: solid; text-align: left; padding: 2px 4px }`r`n" + `

  "</style>"
 

# Generate the body as HTML

$Body = $Results | ConvertTo-HTML -Head $Head

 

# Highlight words

$Body = $Body -Replace "Enabled", "<font color='red'>Enabled</font>"

$Body = $Body -Replace "Disabled", "<font color='green'>Disabled</font>"

 

# Create the mail message using $Body

$MailMessage = New-Object System.Net.Mail.MailMessage( `

  "FromAddress@domain.com", `

  "ToAddress@domain.com", `

  "IIS Log Settings", `

  $Body)

 

# Make the mail HTML

$MailMessage.IsBodyHTML = $True

 

# Send the message using "mailserver.domain.com"

$SmtpClient = New-Object System.Net.Mail.SmtpClient("mailserver.domain.com")

$SmtpClient.Send($MailMessage)

Open in new window

0
 
LVL 40

Author Comment

by:Subsun
ID: 24812480
I got below article and I have done some R&D on the script and made the report in my required format (Some learning).. :-)
http://www.microsoft.com/technet/scriptcenter/resources/pstips/jan08/pstip0104.mspx

But you are too fast.. :-) How can I award points for your script?

IIS.JPG
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24812494

Don't worry about it, it's fine under this question, didn't take long :)

Chris
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 40

Author Comment

by:Subsun
ID: 24812608
One problem, My log folder size is (C:\WINDOWS\system32\LogFiles\W3SVC1) around 220 MB but report says 20 MB. I think script not reading reading the total log size?
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24812630

Is that what you want it to do? The script just looks at the configuration in the log settings to figure out when logs are rolled over (hence the column about it being rolled on size or date).

UNC paths accessible? WMI us useless for returning folder sizes. Give me a few minutes, I'll show you what I mean.

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24812697
Sorry for not being specific.
My main objective is to get..
"Server name" IIS "Logging Status" "Log file Path" "Total Size of the log files"
UNC paths are accessible.
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24812699

Here you go. The value can be rounded if it runs to too many decimal places. Want that in too?

Chris
$Results = @()

ForEach ($Server in Get-Content "ServerList.txt") {

  $WMI = New-Object Management.ManagementScope("\\$Server\root\MicrosoftIISv2")

  $WMI.Options.Authentication = "PacketPrivacy"

  $Query = New-Object Management.ObjectQuery( `

    "SELECT Name, LogFileDirectory, LogFileTruncateSize, LogType, LogFilePeriod FROM IIsWebServerSetting")
 

  $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

  $Results += $Searcher.Get() | Select-Object `

    @{n='Name';e={ $Server }}, `

    @{n='Site';e={ $_.Name }}, `

    @{n='IIS Logging';e={

      Switch ($_.LogType) {

        0 { "Disabled" }

        1 { "Enabled" } 

      } }}, `

    @{n='Log Path';e={ $_.LogFileDirectory }}, `

    @{n='Log File Size';e={ 

      $UNCLogFileDirectory = "\\$Server\$($_.LogFileDirectory -Replace ':\\', '$\')\$($_.Name -Replace '/')"

      "$((Get-ChildItem $UNCLogFileDirectory | Measure-Object Length -Sum).Sum / 1Gb) Gb" }}, `

    @{n='Log File Rollover';e={

      Switch ($_.LogFilePeriod) {

        0 { "Size" }

        1 { "Date" } 

      } }}

}

 

#

# Sending results as the body (HTML)

#

 

# Create a header containing a style for the generated HTML

$Head = "<style type='text/css'>`r`n" + `

  "table { border-collapse: collapse }`r`n" + `

  "td, th { border-width: 2px; border-style: solid; text-align: left; padding: 2px 4px }`r`n" + `

  "</style>"

 

# Generate the body as HTML

$Body = $Results | ConvertTo-HTML -Head $Head

 

# Highlight words

$Body = $Body -Replace "Enabled", "<font color='red'>Enabled</font>"

$Body = $Body -Replace "Disabled", "<font color='green'>Disabled</font>"

 

# Create the mail message using $Body

$MailMessage = New-Object System.Net.Mail.MailMessage( `

  "FromAddress@domain.com", `

  "ToAddress@domain.com", `

  "IIS Log Settings", `

  $Body)

 

# Make the mail HTML

$MailMessage.IsBodyHTML = $True

 

# Send the message using "mailserver.domain.com"

$SmtpClient = New-Object System.Net.Mail.SmtpClient("mailserver.domain.com")

$SmtpClient.Send($MailMessage)

Open in new window

0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24812707

 > Sorry for not being specific

Not to worry, I didn't ask either, got caught up in getting the information from WMI :)

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24812962
All looks fine, two thing to check..
1, Need to make it round : like 1.90 GB
2, for one server the actual size of the log file is 78.6 KB and the report returns 7.50133767724037E-05 Gb
0
 
LVL 40

Author Comment

by:Subsun
ID: 24812998
When i convert in MB all the servers give correct value.
0
 
LVL 40

Author Comment

by:Subsun
ID: 24813286
After rounding the result, I am getting the correct report.
Problem, when I run the script from PowerGUI - I get the result
When I run from the PS prompt - I get error (I am running ./iis.ps1)
When I run from command prompt - I get an error (I am running as powershell.exe iis.ps1)

Am I doing something wrong for running script?

Thanks a lot for your patience. :-)
IIS.JPG
0
 
LVL 40

Author Comment

by:Subsun
ID: 24813309
When i copy paste the script in PS it's working.. What i am doing wrong then :(
0
 
LVL 40

Author Comment

by:Subsun
ID: 24813348
Ok got it.. It is due to executionpolicy.. :-)..
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24813536

Hey dude,

Sorry for not responding. Haven't been getting notification mails for some reason. All set now? :)

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24813715
Yes.. All set to roll.. Thanks a lot.. :-)
0
 
LVL 40

Author Comment

by:Subsun
ID: 24813767
I have set "Set-ExecutionPolicy RemoteSigned" on server which run this script.. is there any disadvantage for this?
0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 24814041

Not really, I never really agreed with the requirement for signed code. I understand it, but that doesn't give me the money to digitally sign all of my scripts ;)

Chris
0
 
LVL 40

Author Comment

by:Subsun
ID: 24814050
LOL.. :-)
0
 
LVL 40

Author Comment

by:Subsun
ID: 25032244
Hello Chris,
If time permits, Please advise on my new question? Q_24631061
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Utilizing an array to gracefully append to a list of EmailAddresses
I thought I'd write this up for anyone who has a request to create an anonymous whistle-blower-type submission form created using SharePoint 2010 (this would probably work the same for 2013). It's not 100% fool-proof but it's as close as you can get…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now