Solved

PowerShell

Posted on 2014-04-19
14
418 Views
Last Modified: 2014-04-20
Any idea what's wrong for the script below ? Is it possible to disable the warning when I run the script ? Tks


$body =  Get-WmiObject Win32_LogicalDisk -filter "DriveType=3' -Computer (Get-Content .\computer.csv) | select SystemName, DeviceID, @{Name="Free (%)";Expression={"{0:N0}" -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }}, @{Name="Size (GB)";Expression={"{0:N1}" -f($_.size/1gb)}},@{Name="Free (GB)";Expression={"{0:N1}" -f($_.freespace/1gb)}} | ConvertTo-Html                          
 
 Send-MailMessage -SmtpServer exdag.abc.com.hk -From dc02.abc.com.hk -To admin@abcl.com.hk -Subject 'Disk Space' -Body ($body -join "`n") -BodyAsHtml
DiskSpace.png
0
Comment
Question by:AXISHK
  • 6
  • 4
  • 4
14 Comments
 
LVL 29

Expert Comment

by:becraig
ID: 40010506
Wasn't this previously answered with :
http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_28412669.html


If I recall the requirement was the same:
To not capture the error on servers you did not have access to then send only the correct info in the email:


$body = @()
(Get-Content .\computer.csv) | % {
Try {
$body += Get-WmiObject Win32_LogicalDisk -filter “DriveType=3" -computer $_ | Select SystemName,DeviceID, @{Name=”Free (%)”;Expression={“{0:N0}” -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }}, @{Name=”Size (GB)”;Expression={“{0:N1}” -f($_.size/1gb)}},@{Name=”Free (GB)”;Expression={“{0:N1}” -f($_.freespace/1gb)}} |
  ConvertTo-Html
	}
	Catch {
		write-host "$_ failed !!" -fore RED
	}
}

Send-MailMessage -SmtpServer exdag.abc.com.cn -From dc02@abc.com.cn -To cngit-admin@abc.com.cn -Subject 'Servers Disk Space Analysis' -Body ($body -join "`n") -BodyAsHtml 

Open in new window

0
 
LVL 69

Expert Comment

by:Qlemo
ID: 40010510
The error is in the very first double quote. Change that to a tick (single quote), and all should be fine. You can also change the first tick to a double quote - doesn't matter which one you take (here), but they need to match.
0
 
LVL 29

Expert Comment

by:becraig
ID: 40010569
Ok so I updated the script I gave you originally I see it was creating multiple html files:
I added an option to verify access first then run the wmi query )

$ErrorActionPreference= 'silentlycontinue'
$servers = @()
(Get-Content .\serverlist.txt) | % {
$error.clear()
$gwmival = Get-WmiObject Win32_LogicalDisk -computer $_
if ($error -ne $null)
{write-host "$_ failed with errors" -fore RED}
else {$servers += $_; }
}
$servers | out-file validlist.txt
 Get-WmiObject Win32_LogicalDisk -filter "DriveType=3" -computer (gc validlist.txt) | Select SystemName,DeviceID, @{Name=”Free (%)”;Expression={“{0:N0}” -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }}, @{Name=”Size (GB)”;Expression={“{0:N1}” -f($_.size/1gb)}},@{Name=”Free (GB)”;Expression={“{0:N1}” -f($_.freespace/1gb)}} | ConvertTo-Html

Send-MailMessage -SmtpServer exdag.abc.com.cn -From dc02@abc.com.cn -To cngit-admin@abc.com.cn -Subject 'Servers Disk Space Analysis' -Body ($body -join "`n") -BodyAsHtml 

Open in new window

0
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.

 
LVL 69

Expert Comment

by:Qlemo
ID: 40010727
becraig,

Don't want to be disrespectful, but your code has several design flaws, is overly complicated, and performing bad because of some work done more than once. It will work, though.

Viewing this question isolated, you seem to miss the point here - there was a syntax error, no WMI error. Of course WMI issues will spit out error messages, but again the script would still work for servers not reporting errors.


AXISHK,

To make sure you get what I told you as correction, and further to show good code formatting style:
$body =  Get-WmiObject Win32_LogicalDisk -filter 'DriveType=3' -Computer (Get-Content .\computer.csv) |
  select SystemName, DeviceID,
    @{Name="Free (%)"; Expression={"{0:N0}" -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }},
    @{Name="Size (GB)"; Expression={"{0:N1}" -f($_.size/1gb)}},
    @{Name="Free (GB)"; Expression={"{0:N1}" -f($_.freespace/1gb)}} |
  ConvertTo-Html

Send-MailMessage -SmtpServer exdag.abc.com.hk -From dc02.abc.com.hk -To admin@abcl.com.hk `
  -Subject 'Disk Space' -Body ($body -join "`n") -BodyAsHtml

Open in new window

0
 
LVL 29

Expert Comment

by:becraig
ID: 40010733
No disrespect.

I accept the flaw in the additional overhead, I just whipped it together as a way to run the code and generate a clean server list for the OP.

Could you highlight for me as a part of my own learning what the other design flaws are, I am very new at this and excited to learn from those who know everything about PS.

That being said I check against ~800 servers for execution time just to see how much overhead was added and it was negligible, which was why I went ahead and posted it.

Thanks again for the critique.
0
 
LVL 69

Accepted Solution

by:
Qlemo earned 250 total points
ID: 40010760
First things first, the following code has the parens around Get-Content removed, and uses proper indenting:
$ErrorActionPreference= 'silentlycontinue'
$servers = @()
Get-Content .\serverlist.txt | % {
  $error.clear()
  $gwmival = Get-WmiObject Win32_LogicalDisk -computer $_
  if ($error -ne $null)
  {write-host "$_ failed with errors" -fore RED}
  else {$servers += $_; }
}
$servers | out-file validlist.txt
Get-WmiObject Win32_LogicalDisk -filter "DriveType=3" -computer (gc validlist.txt) |
  select SystemName, DeviceID,
    @{Name="Free (%)"; Expression={"{0:N0}" -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }},
    @{Name="Size (GB)"; Expression={"{0:N1}" -f($_.size/1gb)}},
    @{Name="Free (GB)"; Expression={"{0:N1}" -f($_.freespace/1gb)}} |
  ConvertTo-Html

Send-MailMessage -SmtpServer exdag.abc.com.cn -From dc02@abc.com.cn -To cngit-admin@abc.com.cn -Subject 'Servers Disk Space Analysis' -Body ($body -join "`n") -BodyAsHtml 

Open in new window


One of the design flaws is the usage of result vars in a piped foreach, just to work with the result once. You can and shall push values directly to the pipe for that purpose:
$ErrorActionPreference= 'silentlycontinue'
$servers = @()
Get-Content .\serverlist.txt | % {
  $error.clear()
  $gwmival = Get-WmiObject Win32_LogicalDisk -computer $_
  if ($error) {write-host "$_ failed with errors" -fore RED} else { $_ }
} | out-file validlist.txt
Get-WmiObject Win32_LogicalDisk -filter "DriveType=3" -computer (gc validlist.txt) |
  select SystemName, DeviceID,
    @{Name="Free (%)"; Expression={"{0:N0}" -f (($_.freespace /1gb) / ($_.size /1gb) * 100) }},
    @{Name="Size (GB)"; Expression={"{0:N1}" -f($_.size/1gb)}},
    @{Name="Free (GB)"; Expression={"{0:N1}" -f($_.freespace/1gb)}} |
  ConvertTo-Html

Send-MailMessage -SmtpServer exdag.abc.com.cn -From dc02@abc.com.cn -To cngit-admin@abc.com.cn -Subject 'Servers Disk Space Analysis' -Body ($body -join "`n") -BodyAsHtml 

Open in new window

Next, I don't see a reason for creating the validlist.txt file, so the whole purpose of the first loop is questionable. Instead, if I want to know which PCs didn't respond, I would compare the result list (as non-HTML then of course) with the original server list to get the differences. But in fact, if I wanted to know and log the failures, I would assume the machines are not reachable (excluding any WMI/DCOM related other error cause), and just ping each with Test-Computer prior to trying to access them.
0
 
LVL 29

Expert Comment

by:becraig
ID: 40010767
Thanks !!!!
 
I did this in notepad and was not really paying attention to indenting :(

On the second note DEFINITELY (I really had not looked at it from that perspective but that improves performance  :~) )

As for the reason to put the list together, the user had previously asked (on another question) about servers that have access denied errors.

The second point for sure I did not think about in whipping this together (GREAT CATCH)

You're awesome dude...
0
 

Author Comment

by:AXISHK
ID: 40011060
Tks. I still have problem schedule it under Window. If I test the script under DOS, it will asked me to reply with "R" before execution. Is it possible to run the script directly ?

Tks
ChkDisk.png
0
 
LVL 29

Expert Comment

by:becraig
ID: 40011069
You can simply add
Set-executionpolicy bypass

In the first like of your script.
0
 
LVL 69

Expert Comment

by:Qlemo
ID: 40011085
Better to switch off security for this call only (Set-ExecutionPolicy is a permanent change):
  powershell -ExecutionPolicy Unrestricted -file ...
0
 

Author Comment

by:AXISHK
ID: 40011099
Still receive the prompt. Actually, I have already set the "set-ExecutionPolicy" to "Unrestricted" but it doesn't help..

Tks
PowerShell.png
0
 
LVL 29

Assisted Solution

by:becraig
becraig earned 250 total points
ID: 40011100
powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File script.ps1

Would be a good way to call it if you need to keep execution policy restricted.
0
 

Author Comment

by:AXISHK
ID: 40011102
The schedule powershell can' t run. I have attached a error message for your reference.

Tks
Task-Scheduler.png
0
 

Author Closing Comment

by:AXISHK
ID: 40011217
Tks
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

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…
This is a PowerShell web interface I use to manage some task as a network administrator. Clicking an action button on the left frame will display a form in the middle frame to input some data in textboxes, process this data in PowerShell and display…
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 …
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

815 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

8 Experts available now in Live!

Get 1:1 Help Now