Script to check IIS logging status of multiple servers.

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
LVL 40
SubsunAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Chris DentPowerShell DeveloperCommented:

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
SubsunAuthor Commented:
Excellent.!!!!!!!!.. How do I send it through email?
0
Chris DentPowerShell DeveloperCommented:

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Webinar: Miercom Evaluates Wi-Fi Security

It's not just about Wi-Fi connectivity anymore. A wireless security breach can cost your business large amounts of time, trouble, and expense. Plus, hear first-hand from Miercom how WatchGuard's Wi-Fi security stacks up against the competition in our upcoming webinar!

SubsunAuthor Commented:
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
Chris DentPowerShell DeveloperCommented:

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
Chris DentPowerShell DeveloperCommented:

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

Chris
0
SubsunAuthor Commented:
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
SubsunAuthor Commented:

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
Chris DentPowerShell DeveloperCommented:

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
SubsunAuthor Commented:
Need to make the columns visible.
0
Chris DentPowerShell DeveloperCommented:

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

Chris
0
SubsunAuthor Commented:
No hurry :)
0
Chris DentPowerShell DeveloperCommented:

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
SubsunAuthor Commented:
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
Chris DentPowerShell DeveloperCommented:

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

Chris
0
SubsunAuthor Commented:
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
Chris DentPowerShell DeveloperCommented:

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
SubsunAuthor Commented:
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
Chris DentPowerShell DeveloperCommented:

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
Chris DentPowerShell DeveloperCommented:

 > Sorry for not being specific

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

Chris
0
SubsunAuthor Commented:
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
SubsunAuthor Commented:
When i convert in MB all the servers give correct value.
0
SubsunAuthor Commented:
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
SubsunAuthor Commented:
When i copy paste the script in PS it's working.. What i am doing wrong then :(
0
SubsunAuthor Commented:
Ok got it.. It is due to executionpolicy.. :-)..
0
Chris DentPowerShell DeveloperCommented:

Hey dude,

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

Chris
0
SubsunAuthor Commented:
Yes.. All set to roll.. Thanks a lot.. :-)
0
SubsunAuthor Commented:
I have set "Set-ExecutionPolicy RemoteSigned" on server which run this script.. is there any disadvantage for this?
0
Chris DentPowerShell DeveloperCommented:

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
SubsunAuthor Commented:
LOL.. :-)
0
SubsunAuthor Commented:
Hello Chris,
If time permits, Please advise on my new question? Q_24631061
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.