<# .SYNOPSIS Takes a discourse topic url and prints all posts that contain external links. Useful for identifying spam posts that hide links in subtle places, such as within commas or periods. .DESCRIPTION The Check-Discourse-Topic-Links script takes a URL and uses the Invoke-RestMethod to check each post for the presence of a link_counts field. If the field exists, the script checks whether its internal property is set to false. If so, it prints the post number, the username of the post's author, the external link and the link text. .PARAMETER discourseTopic The discourse topic url to check. Note: the url must begin with http:// or https:// .EXAMPLE .\Check-Discourse-Topic-Links.ps1 https://discussions.unity.com/t/is-it-a-good-idea-to-put-my-game-on-itch-io-first/1657629 #> [CmdletBinding()] param ( [Parameter(Mandatory=$True)] [string]$discourseTopic ) $pageNumber = 0 Write-Host "`n" while($True) { $pageNumber++ $currentPage = $discourseTopic + ".json?page=" + $pageNumber try { Write-Verbose "Getting all posts from $discourseTopic page $pageNumber" $pageData = (Invoke-RestMethod -UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome) -Method GET -Uri $currentPage) } catch { exit } $allPosts = $pageData.post_stream.posts foreach($post in $allPosts) { Write-Verbose "Checking post: $($post.post_number) by $($post.username) `n" if($post.link_counts) { Write-Verbose "Links found in post number $($post.post_number) `n" foreach($link in $post.link_counts) { Write-Verbose "Link: $link `n" if($link.internal -eq $False) { Write-Output "External link found in post number: $($post.post_number) by $($post.username)" Write-Output "$($link.url)" $escapedLink = [regex]::Escape($($link.url)) $pattern = "]*href=`"$escapedLink`"[^>]*>(.*?)" if($post.cooked -match $pattern) { $linkText = $matches[1] Write-Output "Link Text: $linkText `n" } else { Write-Output "No link text found `n" } Write-Verbose "Post body: $($post.cooked) `n" } } } } }