PowerShell - want to automatically run a .ps1 at a certain time of a {work}day and then get an email with the output

0

Lets start with that I'm just now learning PowerShell. So, I'm monitoring drive space on all the servers in our company and I'd like to automate the process. This is what I got

$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'" | Select-Object Size, FreeSpace

Write-Host ("{0}GB total" -f [math]::truncate($disk.Size / 1GB))
Write-Host ("{0}GB free on C: OS" -f [math]::truncate($disk.FreeSpace / 1GB))

I'd like this to be run 9am every {week}day (if possible) and then get an email with the output of the .ps1.

Can anyone point me to the right direction?

ModestN

Posted 2016-08-25T09:16:35.227

Reputation: 1

1I've done this before by using Task Scheduler. Simply open the program, right click "Task Scheduler (Local)" - Create Task.. From here you can do whatever you want. If you want a mail sent you can go to Actions - New - Send an e-mail. If this is what you're looking for then please tell me, I will write it as an answer instead :) – Bungicasse – 2016-08-25T10:24:54.107

I know there is an email option, but how do I make PowerShell output which is this to be in that email is what I'm trying to understand and make it work.

– ModestN – 2016-08-25T12:06:25.567

This is the other part of the solution, which I cannot answer, so here is some useful links: link and link

– Bungicasse – 2016-08-25T12:19:19.080

Answers

0

This script is ready to go as is with minimal changes. You need to make sure that you have a list of servers in a file called servers.txt that is explained at the top of the code. The list should look like the following:

CompanyDC
CompanyFileServer
CompanyExchange
CompanyRandomServer

This script also has to be run as a domain admin because of the wmi calls. The $cred variable on line 1 will establish that and ask for the password via a UAC window each time the script is run.

The #SMTP Deets section is already using a free relay server. All you have to do is makeup a from address and then input the to address as the email you want the report to get sent to.

I have written the table so that when the email comes through, the servers will also be color coded green/yello/red based on the amount of disk space left. The threshholds are: Green >20% left || Orange 11%-20% || Red 0%-10%.

Here is a sample of what the email will look like:

enter image description here

Edit the $cred , $ServerName directory (see sample txt file above), $smtpFrom and $smtpTo and you're good to go.

$cred = Get-Credential -Credential 'domain\user'
$ServerName = Get-Content "C:\temp\servers.txt"
$ConvertToGB = (1024 * 1024 * 1024)
$enter1 = "`r"
$enter2 = "`r`n"

# Smtp deets
$smtpServer = "relay.appriver.com"
$smtpPort = "2525"
$smtpFrom = "reporting@yourcompany.com"
$smtpTo = "MyEmail@company.com"
$messageSubject = "Daily Server Report"

# Set up an SmtpClient
$smtpClient = New-Object Net.Mail.SmtpClient
$smtpClient.Host = $smtpServer
$smtpClient.Port = $smtpPort

# Create the MailMessage 
$mailMessage = New-Object Net.Mail.MailMessage
$mailMessage.From = $smtpFrom
$mailMessage.To.Add($smtpTo)
$mailMessage.Subject = $messageSubject
$mailMessage.IsBodyHtml = $true

# style
$htmlReport += "<style>"
$htmlReport += "BODY{background-color:white;}"
$htmlReport += "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$htmlReport += "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;}"
$htmlReport += "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;}"
$htmlReport += "</style>"


# table
$htmlReport += "<table>"
$htmlReport += "`n"
$htmlReport += "<tr>"
$htmlReport += "<th>ServerName</th>"
$htmlReport += "<th>Total Space</th>"
$htmlReport += "<th>Free Space</th>"
$htmlReport += "<th>Percent Free</th>"
$htmlReport += "</tr>"
foreach($Server in $ServerName)
{
    $disk = Get-WmiObject -Credential $cred Win32_LogicalDisk -ComputerName $Server -Filter "DeviceID='C:'" | Select-Object Size,FreeSpace
    $htmlReport += "<tr>"
    $htmlReport += "<td>$($Server)</td>"
    $htmlReport += "<td>$([Math]::Truncate($disk.Size / $ConvertToGB))  GB </td>"
    $htmlReport += "<td>$([Math]::Truncate($disk.FreeSpace / $ConvertToGB))  GB </td>"
    if([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100) -le 10)
    {
        $htmlReport += "<td><font color=red> $([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100))  % </font></td>"
    }
    if([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100) -gt 10 -and [Math]::Truncate(($disk.FreeSpace / $disk.size) * 100) -le 20)
    {
        $htmlReport += "<td><font color=orange> $([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100))  % </font></td>"
    }
    if([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100) -gt 20)
    {
        $htmlReport += "<td><font color=green> $([Math]::Truncate(($disk.FreeSpace / $disk.size) * 100))  % </font></td>"
    }
    $htmlReport += "</tr>"
}

$htmlReport += "</table>"



# Now create an AlternateView from the HTML contents
$messageBody = [Net.Mail.AlternateView]::CreateAlternateViewFromString($htmlReport, 'text/html')

# Add the HTML view to the MailMessage
$mailMessage.AlternateViews.Add($messageBody)

# And finally send the message
$smtpClient.Send($mailMessage)
pause

Edit - And then use task scheduler on a reliable machine that is always on at 9am to set this ps1 to run. "Task Scheduler > Create Basic Task > Name Task > Choose Daily as the start > ACtion: Recur every 1 day @ xx time you set > Start a program > browse for your ps1 > finish.

Narzard

Posted 2016-08-25T09:16:35.227

Reputation: 2 276