Solved

Having trouble getting drive information on servers using powershell

Posted on 2009-07-09
4
938 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
  • 2
  • 2
4 Comments
 
LVL 70

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 70

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

[Webinar] Disaster Recovery and Cloud Management

Learn from Unigma and CloudBerry industry veterans which providers are best for certain use cases and how to lower cloud costs, how to grow your Managed Services practice in IaaS clouds, and how to utilize public cloud for Disaster Recovery

Question has a verified solution.

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

Suggested Solutions

Microsoft Windows Server Update Service (WSUS) is free for everyone, but it lacks of some desirable features like send an e-mail to the administrator with the status of all computers on the WSUS server. This article is based on my PowerShell script …
"Migrate" an SMTP relay receive connector to a new server using info from an old server.
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

911 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

20 Experts available now in Live!

Get 1:1 Help Now