1
votes

I am trying to send slack message by powershell and I got stuck. here is my script. Looks like I can't use $result for -text.

What I am trying to do is to send an alert to slack channel if there is any free disk space lower than 15% or 10%.

I am using PSSlack from Powershell Gallery.

$ErrorActionPreference = "Continue"; 
$percentCritcal = 15;

$computers = Get-Content "D:\Disk_Usage\ServerList.txt"
$result = foreach($computer in $computers) 
{ 
    $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3" 
    $computer = $computer.ToUpper() 
    foreach($disk in $disks) 
    {         
        $Size = $disk.Size
        $Freespace = $disk.FreeSpace
        $sizeGB = [Math]::Round($Size / 1073741824, 2)
        $freeSpaceGB = [Math]::Round($Freespace / 1073741824, 2)
        $percentFree = [Math]::Round(($freespace / $size) * 100, 2);

        $ResultHash = [ordered]@{
            Computer = $computer
            Drive = $disk.DeviceID
            SizeGB = $sizeGB
            UsedGB = $sizeGB - $freeSpaceGB
            FreeGB = $freeSpaceGB
            PercFree = $percentFree  
        } 

        New-Object -TypeName PSObject -Property $ResultHash
    }  
}

$Result = $Result | Where-Object {$_.PercFree -lt 10}

if ($Result) 
{
    $token = 'xxxxxxxxxxx'
    $Result = $Result | Format-Table | Out-String

    New-SlackMessageAttachment -Color $_PSSlackColorMap.red `
                               -Title 'Disk Free Space Alert' `
                               -Text $result  `
                               -Fallback 'Bad boy' |

    New-SlackMessage -Channel '#it-test' `
                     -IconEmoji :bomo: `
                     -AsUser `
                     -Username 'BOT' |

    Send-SlackMessage -Token $token  
}

The result is like this, it is repeating the same drive for couple timesenter image description here

Any idea?

1
What's $result ? You are not emitting anything out. - Adil Hindistan

1 Answers

5
votes

The problem with your code is that $Result never gets populated with anything. The simplest fix would be to create an object in the ForEach loop, which will then populate $Result.

For example:

$result = foreach($computer in $computers) 
{ 
    $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3" 
    $computer = $computer.ToUpper() 
    foreach($disk in $disks) 
    {         
        $Size = $disk.Size
        $Freespace = $disk.FreeSpace
        $sizeGB = [Math]::Round($Size / 1073741824, 2)
        $freeSpaceGB = [Math]::Round($Freespace / 1073741824, 2)

        $ResultHash = [ordered]@{
            Computer = $computer
            deviceID = $disk.DeviceID
            volName = $disk.VolumeName 
            percentFree = [Math]::Round(($Freespace / $Size) * 100, 2) 
            sizeGB = $sizeGB
            freeSpaceGB = $freeSpaceGB
            usedSpaceGB = $sizeGB - $freeSpaceGB
        }

        New-Object -TypeName PSObject -Property $ResultHash
    }  
}

Explanation:

The above code has taken your existing variables and turned them in to properties of a hash table @{ }. This hash table is then used to create the properties of an object with New-Object.

Because New-Object is on a line on it's own, it's result goes in to the pipeline, which is ultimately output to $Result because that's where you send the result of the ForEach.

[ordered] in front of the Hashtable should keep the properties in the order that they've been defined. Note that this requires PowerShell v3 or above.


Depending on how you want it to look, you might want to also do this to $Result after the ForEach and before you use it in the Slack Message:

$Result = '```' + ($Result | Format-Table | Out-String) + '```'

This should make the message formatted as fixed width code in a tabular format. Of course you might want to modify the output differently, just a suggestion.