Having trouble getting drive information on servers using powershell

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
LVL 1
ndalmolin_13Asked:
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:

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

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

No worries, have a good weekend too :)

Chris
0
ndalmolin_13Author Commented:
This worked great.  I think I should start using arrays more instead of simple lists.
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
Powershell

From novice to tech pro — start learning today.