Gmail RSS Monitor and File Downloader

Loops at a specified interval and monitors emails for titles which RegEx match [identifier] [url] (e.g. mycoolID http://mirror.math.princeton.edu//ubuntu-17.10.1-desktop-amd64.iso) and downloads the files using BITS to a specified storage location. Uses background jobs so there’s no blocking.

Usage: Configure the settings in the script and run it. Then send an email to the email account configure for RSS monitoring. The email subject / tile should contain your unique identifier (whatever random string you choose (configured in the RegEx variable)), a space, and the URL you wish to have downloaded by the script.

If Windows Defender is enabled on your computer, the script will initiate a scan of the files upon download completion.

It is recommended to setup a separate account to do this with since you have to allow “less secure apps” access in your Gmail Security settings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    # Monitor Gmail and Download Files Based On Title Contents using RegEx
    # Uses the BITS client to download
    # If Enabled, Files are scanned with Windows Defender upon download completion
    # OPTIONS
    # Folder where files will be dropped, no trailing slash \
    $FileDrop = "Z:\FileDrop"
    # RegEx for Title Matching. Should be [Unique Identifier] [URL] E.G.: 'MYuniqID https://download.com/this/file/here.exe'
    # The filename to save in the FileDrop is pulled from the last / of the URL, would be "here.exe" from the example above.
    $titleRegEx = '^myCoolID\s(http[s]{0,1}://.*)'
    # Frequency to check email in minutes
    $freq = 1
    # Gmail Account Info (must allow insecure apps in your security settings)
    $user = "username@gmail.com"
    $pwd = "password1234!"
    # Scan downloaded files with Windows Defender upon completion?
    $scanFiles = $true
    #==============================================================================

    cls
    $makeItStop = $false
    Import-Module BitsTransfer
    $ToGrabFiles = New-Object System.Collections.ArrayList
    $GrabbedFiles = New-Object System.Collections.ArrayList
    $currentJobs = New-Object System.Collections.ArrayList
    $doneJobs = New-Object System.Collections.ArrayList
    $scannedFiles = New-Object System.Collections.ArrayList
    $webclient = new-object System.Net.WebClient
    # access the rss-feed - uses your Gmail email address and password
    $webclient.Credentials = new-object System.Net.NetworkCredential ($user, $pwd)

    Do {

    # download the rss as xml from google
    [xml]$xml = $webclient.DownloadString("https://mail.google.com/mail/feed/atom")
    # check each email
    ForEach ($email in $xml.feed.entry){    
        If ($email.title -match $titleRegEx){ # does the email title match our regex for ID and URL?
            $grab = [pscustomobject] @{URL = $matches[1]}
            If ($GrabbedFiles -notcontains $grab.URL -and $ToGrabFiles -notcontains $grab.URL){
                $null = $ToGrabFiles.Add($grab.URL)
                Write-Host "Added $($grab.URL) to the download list" -ForegroundColor Green            
            }
        }
    }
    # check each URL found in the email titles
    ForEach ($URL in $ToGrabFiles){
        If ($GrabbedFiles -notcontains $URL){        
            $fileName = $URL.Substring($url.LastIndexOf("/") + 1)
            $saveFileName = "$FileDrop\$filename"        
            If (!(Test-Path $saveFileName) ){            
                $newJob = Start-Job -ScriptBlock {
                    param ([string]$URL, [string]$saveFileName)                
                    Start-BitsTransfer -Source $URL -Destination $saveFileName -ErrorVariable jobErr -ErrorAction SilentlyContinue;                
                    Write-Output $URL;                            
                } -ArgumentList $URL, $saveFileName                        
                $null = $currentJobs.Add($newJob.Id)
                $null = $GrabbedFiles.Add($URL)                          
            }Else{
                Write-Output "$saveFileName already exists - skipping!"            
                $null = $GrabbedFiles.Add($URL)
            }
        }Else{
            #"File already grabbed!"
        }
    }    

       ForEach ($job in $currentJobs){
            If ($doneJobs -notcontains $job){
                $status = Get-Job -Id $job
                If ($status.State -eq 'Completed' -and $status.HasMoreData -eq 'True'){                
                    Do{
                        $result = Receive-Job -id $job                    
                        Write-Host "$result :: $($status.state)" -ForegroundColor Green                                                                              
                    }Until($result -eq $null)
                    $null = Stop-Job -Id $job
                    $null = Remove-Job -Id $job                
                    $null = $doneJobs.Add($job)                                    
                }ElseIf ($status.State -eq 'Running'){
                    Do{
                        $result = Receive-Job -id $job                    
                        Write-Host "$result :: $($status.state)" -ForegroundColor Cyan                                                          
                    }Until($result -eq $null)
                }            
                           
                sleep -Seconds 1
            }
        }

         ForEach ($done in $doneJobs){
            $currentJobs.Remove($done)
        }

        If ($scanFiles -eq $true){
            ForEach ($file in Get-ChildItem -Exclude "*.tmp" -LiteralPath $FileDrop | where {$scannedFiles -notcontains $_.Name}){            
                If (Get-Service windefend -ErrorAction SilentlyContinue | where {$_.status -eq "Running"}) {    
                    $scan = Start-MpScan -ScanPath $file.FullName -ScanType QuickScan    
                    $null = $scannedFiles.Add($File.Name)
                }Else{
                    Write-Output "Windows Defender is not running. Unable to scan file: $($file.FullName)"
                    $svc = Get-Service windefend -ErrorAction SilentlyContinue | select status
                    Write-Output "Windows Defender Service is: $($svc.Status)"                
                }
            }
        }
    Write-Output "Sleeping for $freq minutes... Press CTRL+C to Quit"
    sleep -Seconds ($freq * 60)

    } Until ($makeItStop -eq $true)

Leave a Reply

Your email address will not be published. Required fields are marked *