Solved

Having trouble getting drive information on servers using powershell

Posted on 2009-07-09
4
949 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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Suggested Solutions

Are you one of those front-line IT Service Desk staff fielding calls, replying to emails, all-the-while working to resolve end-user technological nightmares? I am! That's why I have put together this brief overview of tools and techniques I use in o…
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…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

776 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