【问题标题】:Emailing a Hard Drive Disk Space Alert Using Powershell使用 Powershell 通过电子邮件发送硬盘空间警报
【发布时间】:2016-08-12 20:12:43
【问题描述】:

我一直在浏览网页,试图找到一种方法,如果可能的话,可以使用 power shell 将低磁盘空间警报从 Gmail 帐户通过电子邮件发送到共享邮箱,但我正在努力解决我设法拼凑的查询。

$EmailFrom =  "FromEmail@Gmail.com"
$EmailTo = "ToEmail@Gmail.com"
$SMTPServer = "smtp.gmail.com" 
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("Username", "Password"); 
$Computers = "Local Computer"
$Subject = "Disk Space Storage Report" 
$Body = "This report was generated because the drive(s) listed below have less than $thresholdspace % free space. Drives above this threshold will not be listed." 

[decimal]$thresholdspace = 50

$tableFragment = Get-WMIObject  -ComputerName $computers Win32_LogicalDisk `
| select __SERVER, DriveType, VolumeName, Name, @{n='Size (Gb)' ;e={"{0:n2}" -f ($_.size/1gb)}},@{n='FreeSpace (Gb)';e={"{0:n2}" -f ($_.freespace/1gb)}}, @{n='PercentFree';e={"{0:n2}" -f ($_.freespace/$_.size*100)}} `
| Where-Object {$_.DriveType -eq 3} `
| ConvertTo-HTML -fragment

$regexsubject = $Body
$regex = [regex] '(?im)<td>'

if ($regex.IsMatch($regexsubject)) {$smtpclinet.send($fromemail, $EmailTo, $Subject, $Body)}

脚本运行但没有任何反应,任何帮助都会很棒!!!

【问题讨论】:

  • 对调试应用分而治之的策略。将脚本分成几部分并找出失败的部分。 WMI 查询是否报告了良好的结果?您可以通过 Gmail 发送任意邮件吗?
  • 有些错字对smtpclinet没有帮助。为什么不使用Send-MailMessage?无论如何,你什么也得不到,因为你从未将$tableFragment 合并到$Body 中。如果$Body 不包含带有表格数据的 HTML 表格,则永远不会发送邮件。
  • 你的另一个问题。 $Body 包含一个 $thresholdspace 变量。 $thesholdspace 变量直到 $Body 已经使用该值之后才设置。
  • @vonPryz 是的,我已经设法将电子邮件直接从 powershell 发送到另一个邮箱,然后再将它们切碎并重新组合在一起。我已经尝试过这种技术,但没有运气。
  • @ChrisDent - 我之前使用的是 Send-mailmessage,但我遇到了各种各样的错误,所以我切换了。我已经修正了我的拼写(感谢发现)。一开始我对powershell不是很了解。你能举个例子说明应该怎么写吗?

标签: email powershell


【解决方案1】:

我的版本会更长,因为我已经做了一个 Send-MailMessage 的替代品,这样我的和 Send-MailMessage 之间的交换就很简单了。

这是一种可能的方法。 ConvertTo-Html 上的 Fragment 参数有很好的用途,但在这里没有太多理由这样做。

这是一个脚本,应该是一个 .ps1 文件。在 param 块中设置了我真的不想硬编码超出默认值的强制性内容。

param(
    [String[]]$ComputerName = $env:COMPUTERNAME,

    [Decimal]$Theshold = 0.5,

    [PSCredential]$Credential = (Get-Credential)
)

#
# Supporting functions
#

# This function acts in much the same way as Send-MailMessage.
function Send-SmtpMessage {
    param(
        [Parameter(Mandatory = $true, Position = 1)]
        [String[]]$To,

        [Parameter(Mandatory = $true, Position = 2)]
        [String]$Subject,

        [String]$Body,

        [Switch]$BodyAsHtml,

        [String]$SmtpServer = $PSEmailServer,

        [Int32]$Port,

        [Switch]$UseSSL,

        [PSCredential]$Credential,

        [Parameter(Mandatory = $true)]
        [String]$From
    )

    if ([String]::IsNullOrEmtpy($_)) {
        # I'd use $pscmdlet.ThrowTerminatingError for this normally
        throw 'A value must be provided for SmtpServer'
    }

    # Create a mail message
    $mailMessage = New-Object System.Net.Mail.MailMessage
    # Email address formatting si validated by this, allowing failure to kill the command
    try {
        foreach ($recipient in $To) {
            $mailMessage.To.Add($To)
        }
        $mailMessage.From = $From
    } catch {
        $pscmdlet.ThrowTerminatingError($_)
    }
    $mailMessage.Subject = $Subject

    $mailMessage.Body = $Body
    if ($BodyAsHtml) {
        $mailMessage.IsBodyHtml = $true
    }

    try {
        $smtpClient = New-Object System.Net.Mail.SmtpClient($SmtpServer, $Port)
        if ($UseSSL) {
            $smtpClient.EnableSsl = $true
        }
        if ($psboundparameters.ContainsKey('Credential')) {
            $smtpClient.Credentials = $Credential.GetNetworkCredential()
        }

        $smtpClient.Send($mailMessage)
    } catch {
        # Return errors as non-terminating
        Write-Error -ErrorRecord $_
    }
}

#
# Main
#

# This is inserted before the table generated by the script
$PreContent = 'This report was generated because the drive(s) listed below have less than {0} free space. Drives above this threshold will not be listed.' -f ('{0:P2}' -f $Threshold) 

# This is a result counter, it'll be incremented for each result which passes the threshold
$i = 0
# Generate the message body. There's not as much error control around WMI as I'd normally like.
$Body = Get-WmiObject Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName $ComputerName | ForEach-Object {
    # PSCustomObject requires PS 3 or greater.
    # Using Math.Round below means we can still perform numeric comparisons
    # Percent free remains as a decimal until the end. Programs like Excel expect percentages as a decimal (0 to 1).
    [PSCustomObject]@{
        ComputerName     = $_.__SERVER
        DriveType        = $_.DriveType
        VolumeName       = $_.VolumeName
        Name             = $_.Name
        'Size (GB)'      = [Math]::Round(($_.Size / 1GB), 2)
        'FreeSpace (GB)' = [Math]::Round(($_.FreeSpace / 1GB), 2)
        PercentFree      = [Math]::Round(($_.FreeSpace / $_.Size), 2)
    }
} | Where-Object {
    if ($_.PercentFree -lt $Threshold) {
        $true
        $i++
    }
} | ForEach-Object {
    # Make Percentage friendly. P2 adds % for us.
    $_.PercentFree = '{0:P2}' -f $_.PercentFree

    $_
} | ConvertTo-Html -PreContent $PreContent | Out-String

# If there's one or more warning to send.
if ($i -gt 0) {
    $params = @{
        To         = "ToEmail@Gmail.com"
        From       = "FromEmail@Gmail.com"
        Subject    = "Disk Space Storage Report"
        Body       = $Body
        SmtpServer = "smtp.gmail.com"
        Port       = 587
        UseSsl     = $true
        Credential = $Credential
    }
    Send-SmtpMessage @params
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2012-09-08
    • 2020-04-21
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多