Powershell 检索可用磁盘空间少于10%的所有存储

Powershell 检索可用磁盘空间少于10%的所有存储,powershell,Powershell,自从我用SQL以外的语言编程或编写脚本以来,已经有很长一段时间了,由于受到限制,我需要得到一个脚本,该脚本将以低于10%的速度向我显示所有存储(包括装入点),到目前为止,我已经来到这里,但我仍然停留在如何使用迭代器上 我正在努力格式化电子邮件。有什么帮助吗 $TotalGB = @{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1073741824),2)}} $FreeGB = @{Name="FreeS

自从我用SQL以外的语言编程或编写脚本以来,已经有很长一段时间了,由于受到限制,我需要得到一个脚本,该脚本将以低于10%的速度向我显示所有存储(包括装入点),到目前为止,我已经来到这里,但我仍然停留在如何使用迭代器上

我正在努力格式化电子邮件。有什么帮助吗

    $TotalGB = @{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1073741824),2)}}
    $FreeGB = @{Name="FreeSpace(GB)";expression={[math]::round(($_.FreeSpace / 1073741824),2)}}
    $FreePerc = @{Name="Free(%)";expression={[math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) * 100),0)}}

    $emailFrom="example@example.com"
    $emailTo="test@example.com"

    function get-mountpoints {
$volumes = Get-WmiObject win32_volume -Filter "DriveType='3'" -ComputerName someComputer| Where-Object {$_.DriverLetter -eq $null}
if(($volumes | Select VolumeName, Label, $TotalGB, $FreeGB, $FreePerc | ?{$_."Free(%)" -lt 20} | Measure-Object).Count -ne 0)
{
    $volumes | Select VolumeName, Label, $TotalGB, $FreeGB, $FreePerc | ?{$_."Free(%)" -lt 20} | Format-Table -AutoSize
    $Subject="Disk $volumes.Label on $hostname has less than $volumes.$FreeGB GB of free space left, which is $volumes.$FreePerc %" | ?{$_."Free(%)" -lt 20} 
    Send-MailMessage -From $emailFrom -To $emailTo  -Subject $Subject -Body $Subject -Priority High -dno onSuccess, onFailure -SmtpServer "smtp.mail.com" -Port 25  
}
}

get-mountpoints 
这是我想出的最终解决办法

$emailFrom = "mail@mail.com"
$emailTo = "tomail@mail.com"
function Get-Mountpoints {
    param(
        $ComputerName, 
        $FreePercentage,
        $Filter ="DriveType='3'"
    )

  $volumes = Get-WmiObject win32_volume -Filter $Filter -ComputerName $ComputerName |
    Where-Object {$_.DriverLetter -eq $null -and ([math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) * 100),0)) -lt $FreePercentage} 

    if($volumes) {

        # You might want to use the header of the body below, whatever.
        $Subject = "Issue for space on server $ComputerName"

        # When referencing parameter values in a string, you need to tell powershell to evaluate your string in a special way
        # Wrapping things in a $() essentially is an order of operations for evaluation, the more nested, the earlier you will be evaluated
        # You can also use this $() when your variable name abuts a character, like in the % below 
        $Body = "Hostname: $ComputerName `r`n" + [System.Environment]::NewLine # a "shortcut" for system anonymous newlines
        $Body += 
            # If you comment out $Volumes and replace it with the next line, you will get two rows output into $Body
             $Volumes | 
            #  @( [pscustomobject]@{Label = "C"; FreeSpace = 10;}, [pscustomobject]@{Label = "C"; FreeSpace = 10;})  | 
            Foreach-Object {
                "Disk $($_.Label) has less than $([math]::round(($_.FreeSpace / 1073741824),2)) GB of free space left, which is $([math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) * 100),0))% `r`r"
            }
        # In PowerShell, these messages will be supressed unless the console runs $VerbosePreference="Continue" indicating you would like to see more verbose output 
        # I added the -WhatIf so you wont send anything
        #$VerbosePreference="Continue"
        Write-Verbose "From: $emailFrom To: $emailTo"
        Write-Verbose $Subject
        Write-Verbose $Body
        Send-MailMessage -From $emailFrom -To $emailTo -Subject $Subject -Body $Body -Priority High -dno onSuccess, onFailure -SmtpServer "smtp.mail.com" -Port 25
      }
    }

# Why not maintain a list of computers? 
$ComputerList = @(
    "localhost"
)
$ComputerList | ForEach-Object {
    Get-Mountpoints -ComputerName $_ -Filter "DriveType='3'" -FreePercentage 20
} # I Added some parameters so you can make it a little more flexible

谢谢大家的帮助

所以我对你的问题有了很大的自由,并试图弄清问题的意图,我在整个过程中添加了评论,加入了一些参数,使列表、字符串评估和其他一些片段更加灵活

$emailFrom = "example@example.com"
$emailTo = "test@example.com"

function Get-Mountpoints {
    param(
        $ComputerName, 
        $FreePercentage,
        $Filter ="DriveType='3'"
    )

  $Volumes = Get-WmiObject win32_volume -Filter $Filter -ComputerName $ComputerName |
    Where-Object {$_.DriverLetter -eq $null -and $_."Free(%)" -lt $FreePercentage} 

  if($Volumes){

    # You might want to use the header of the body below, whatever.
    $Subject = "To Be Determined"

    # When referencing parameter values in a string, you need to tell powershell to evaluate your string in a special way
    # Wrapping things in a $() essentially is an order of operations for evaluation, the more nested, the earlier you will be evaluated
    # You can also use this $() when your variable name abuts a character, like in the % below 
    $Body = "Hostname: $ComputerName" + [System.Environment]::NewLine # a "shortcut" for system anonymous newlines
    $Body += 
        # If you comment out $Volumes and replace it with the next line, you will get two rows output into $Body
        $Volumes | 
        #  @( [pscustomobject]@{Label = "C"; FreeSpace = 10;}, [pscustomobject]@{Label = "C"; FreeSpace = 10;)  | 
        Foreach-Object {
            "Disk $($_.Label) has less than $([math]::round(($_.FreeSpace + .1 / 1073741824),2)) GB of free space left, which is $([math]::round(((($_.FreeSpace + .1 / 1073741824)/($_.Capacity / 1073741824)) * 100),0))%" + [System.Environment]::NewLine
        } # $_ indicates the current iterated on item 

    # In PowerShell, these messages will be supressed unless the console runs $VerbosePreference="Continue" indicating you would like to see more verbose output 
    # I added the -WhatIf so you wont send anything
    Write-Verbose "From: $emailFrom To: $emailTo"
    Write-Verbose $Subject
    Write-Verbose $Body

    #Send-MailMessage -From $emailFrom -To $emailTo -Subject $Subject -Body $Body -Priority High -dno onSuccess, onFailure -SmtpServer "smtp.mail.com" -Port 25
  }
}


# Why not maintain a list of computers? 
$ComputerList = @(
    "localhost"
)
$ComputerList | ForEach-Object {
    Get-Mountpoints -ComputerName $_ -Filter "DriveType='5'" -FreePercentage 99
} # I Added some parameters so you can make it a little more flexible

您还应该将foreach循环中的Select移动到volumes@OwainEsau很抱歉,你在WMI调用中的定义是什么意思?有一点progressVariables没有传递到电子邮件,甚至主机名都没有。嘿,-发送消息不支持WhatIf(我补充说,在没有测试的情况下,我们的对话结束后)我很惊讶这一部分竟然为您运行……一秒钟后,我实际上对该部分进行了评论:P仍然面临问题如果您对此进行了评论,您看到了什么问题?是否希望查看主题和正文?如果是,您将需要运行$VerbosePreference=“Continue”在您的控制台中,在您运行此操作之前,请注意,我确实更改了用于在我的机器上进行测试的过滤器和自由百分比。