Solved

Having trouble getting drive information on servers using powershell

Posted on 2009-07-09
4
983 Views
Last Modified: 2012-08-13
Hello PowerShell Experts,

My PowerShell project for the day is to create a script that ping all the servers in my domain and provide disk information for  any servers that are online.  The script will then put this information into the body of an email and send it to my mailbox.  I have some PowerShell code that will list the servers on the domain, so I wasnt too worried about getting that part of the script to work.  I decided to start out with the part of the script that will return disk information.  To make things run a bit faster, I decided to collect disk information on one server.  By going through previous posts here at Experts-Exchange and reading different resources on the web and going through my Powershell books, here is the code I came up with:

### HEADER SECTION ###
 
$Header = "<style type='text/css'>`n" + `
  "td { width: 200px }`n" + `
  "th { text-align: left }`n" + `
  "</style>"

### SINGLE SERVER TO QUERY SECTION ###

$OnlineServers = "Mail01"

### BODY OF REPORT SECTION ###

$Body = Get-WmiObject -Query "select * from win32_logicaldisk" -ComputerName $OnlineServers | `
Where-Object {$_.drivetype -eq "3"} | `
Select-Object `
@{n="Server";e={$_.SystemName}},`
@{n="Drive Letter";e={$_.DeviceID}},`
@{n="Volume Name";e={$_.VolumeName}},`
@{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
@{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
@{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
@{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}} | `
ConvertTo-HTML -Title "Server Disk Report" -Head $Header

### EMAIL REPORT SECTION ###

$Mail = New-Object System.Net.Mail.MailMessage( `
  "ServerAdmin@test.com", `
  "nick@test", `
  "Server Disk Report", `
  $Body)
 
$Mail.IsBodyHTML = $True
 
$Smtp = New-Object System.Net.Mail.SmtpClient("cas-hub01.test.states")
$Smtp.Send($Mail)

The code above worked great.  I received the email report in the format I expected shown below (trust me, this formatting is good in an email, just not in this post):

Server      Drive Letter      Volume Name      Total Size (GB)      Free Space (GB)      Used Space (GB)      Percentage Used
MAIL01      C:            67.01      38.02      29.00      43.27 %
MAIL01      D:      Exchange Databases      1,465.95      1,309.17      156.79      10.70 %
MAIL01      E:      Exchange Logs      366.49      362.49      4.00      1.09 %

At this point, Im thinking all I need to do now is insert the code at the top of the script that will go out and get a list of all the servers that are online on my domain.  Here is a copy of the script after this code had been added:

### HEADER SECTION ###

$Header = "<style type='text/css'>`n" + `
  "td { width: 200px }`n" + `
  "th { text-align: left }`n" + `
  "</style>"

### COMPILE A LIST OF SERVERS ONLINE SECTION ###

$Servers = Get-QADComputer -OSName "Windows*Server*" | foreach{$_.name} | Sort-Object
$OnlineServers = ""
Foreach ($item in $Servers) {
$PingResult = Get-WmiObject -Query "Select * From win32_PingStatus Where address='$item'"
If ($PingResult.statuscode -eq 0) {
      $OnlineServers = $OnlineServers+ "$item`n"
      }
}

### BODY OF REPORT SECTION ###

$Body = Get-WmiObject -Query "select * from win32_logicaldisk" -ComputerName $OnlineServers | `
Where-Object {$_.drivetype -eq "3"} | `
Select-Object `
@{n="Server";e={$_.SystemName}},`
@{n="Drive Letter";e={$_.DeviceID}},`
@{n="Volume Name";e={$_.VolumeName}},`
@{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
@{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
@{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
@{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}} | `
ConvertTo-HTML -Title "Server Disk Report" -Head $Header

### EMAIL REPORT SECTION ###

$Mail = New-Object System.Net.Mail.MailMessage( `
  "ServerAdmin@test.com", `
  "nick@test", `
  "Server Disk Report", `
  $Body)
 
$Mail.IsBodyHTML = $True
 
$Smtp = New-Object System.Net.Mail.SmtpClient("cas-hub01.test.states")
$Smtp.Send($Mail)

The script is not working with the code that compiles the list of servers online.  The error Im getting is:

Bad path to object (Exception from HRESULT: 0x80080004 (CO_E_BAD_PATH))
At :line:16 char:21
+ $Body = Get-WmiObject <<<<  -Query "select * from win32_logicaldisk" -ComputerName $OnlineServers | `

From what I can gather, PowerShell is having problems using the list of servers created.  Any ideas on how to solve this issue?

As always, any and all help is appreciated.

Regards,
Nick
0
Comment
Question by:ndalmolin_13
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 71

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 24821305

Morning Nick :)

You run into a problem with the list of servers you're building. Get-WMIObject will happily accept a list of server names if they're in an array. It's the line-break delimited string it doesn't like (Get-WMIObject sees the entire thing as a single server name).

A few comments in-line :)

Chris
### HEADER SECTION ###
 
$Header = "<style type='text/css'>`n" + `
  "td { width: 200px }`n" + `
  "th { text-align: left }`n" + `
  "</style>"
 
### COMPILE A LIST OF SERVERS ONLINE SECTION ###
 
# Declare $OnlineServers as an array
$OnlineServers = @()
Get-QADComputer -OSName "Windows*Server*" | %{
  $PingResult = Get-WmiObject -Query "SELECT * FROM win32_PingStatus WHERE address='$($_.Name)'"
  If ($PingResult.StatusCode -eq 0) {
 
    # Add the current name to the array
    $OnlineServers += "$($_.Name)"
  }
}
 
### BODY OF REPORT SECTION ###
 
# Execute Get-WMIObject for every element in the $OnlineServers array
# Added the filter to the WMI query rather than using Where-Object. No point in returning more than we must.
$Body = Get-WmiObject Win32_LogicalDisk -ComputerName $OnlineServers -Filter "DriveType='3'" | `
  Select-Object `
    @{n="Server";e={$_.SystemName}},`
    @{n="Drive Letter";e={$_.DeviceID}},`
    @{n="Volume Name";e={$_.VolumeName}},`
    @{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
    @{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
    @{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
    @{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}} | `
  ConvertTo-HTML -Title "Server Disk Report" -Head $Header
 
### EMAIL REPORT SECTION ###
 
$Mail = New-Object System.Net.Mail.MailMessage( `
  "ServerAdmin@test.com", `
  "nick@test", `
  "Server Disk Report", `
  $Body)
 
$Mail.IsBodyHTML = $True
 
$Smtp = New-Object System.Net.Mail.SmtpClient("cas-hub01.test.states")
$Smtp.Send($Mail)

Open in new window

0
 
LVL 1

Author Comment

by:ndalmolin_13
ID: 24825035
Hello Chris,

Thanks for the response.  I'm out of the office today, but will give your suggestion a try Monday morning.  Have a good weekend.
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 24826043

No worries, have a good weekend too :)

Chris
0
 
LVL 1

Author Closing Comment

by:ndalmolin_13
ID: 31601846
This worked great.  I think I should start using arrays more instead of simple lists.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
A recent project that involved parsing Tableau Desktop and Server log files to extract reusable user queries for use in other systems. I chose to use PowerShell to gather the data, and SharePoint to present it...
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…

705 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