Functional PowerShell with Slack

I have written this function out a few times. I have made it extremely simple and then went back and added some complexity. I have also run into a situation where I needed to write a tool that was widely used among users with Windows 7-10. So, I needed the tool to be compatible with PowerShell v2. This first function will not work with PowerShell v2 for a few different reasons. I will, however, post both functions.

function Send-ToSlack($channel, $message, $user, $heading=$null, $webhook)
{
    #Slack doesnt accept Arrays, so if it is an array, this converts it to a string
    if(($message -is [array]) -eq "True")
        {
            [System.Collections.ArrayList]$ArrayList = $message

            #Dont use the heading unless you are using an array as an input
            if($heading -ne $null)
                {
                    $ArrayList.Insert(0,$heading)
                    $ArrayList[0] = "*" + $ArrayList[0] + "*"
                    $ArrayList[0] += "`n>>>"
                }

            $message = $ArrayList | Out-String
            }

    #Bundle of information to send to slack
	$payload = @{
		channel   = $channel
		text	  = $message
		username  = $user
	}

    #Send Message via web request to slack        
	Invoke-WebRequest -Body (ConvertTo-Json -Compress -InputObject $payload) -Method Post -Uri $webhook | Out-Null
}

Read More for PowerShell v2 compatibility.

This function I pieced together from a few different places. The problem with PowerShell v2 is that it a) doesn’t support Invoke-WebRequest and b) it doesn’t support ConvertTo-Json. So it requires some improvisation. This is a function inside a function. There is a function inside that will convert our payload to Json to send to Slack. The rest is a more manual, custom way of making a web request. This one also doesn’t support arrays as in input, nor headings. This can be added if I get any requests for it.

function Send-ToSlackv2($channel, $message, $user, $webhook)
{
	$URI = New-Object System.Uri($webhook, $true)
	
	$payload = @{
		channel   = $channel
		text	  = $message
		username  = $user
	}
	
	function ConvertTo-Json20($item)
	{
		[System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") | Out-Null
		$ps_js = New-Object System.Web.Script.Serialization.JavaScriptSerializer
		return $ps_js.Serialize($item)
	}
	
	$payload = ConvertTo-Json20 $payload
	
	$request = [System.Net.WebRequest]::Create($uri)
	$request.ContentType = "application/json"
	$request.Method = "POST"
	
	
	$utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($payload)
	$request.ContentLength = $utf8Bytes.Length
	$postStream = $request.GetRequestStream()
	$postStream.Write($utf8Bytes, 0, $utf8Bytes.Length)
	
	try
	{
		$response = $request.GetResponse()
	}
	catch
	{
		$response = $Error[0].Exception.InnerException.Response;
		Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)"
	}
	$response.Close()
}

These functions can be used practically anywhere. I have added them to other scripts for logging and updating me or others about the status or progress of a running script. There are many uses.