Top-Themen

Aktuelle Themen (A bis Z)

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Powershell: Googlemail (GMail) nativ mit Powershell verwalten

Mitglied: colinardo

colinardo (Level 5) - Jetzt verbinden

22.12.2015, aktualisiert 08.06.2016, 7325 Aufrufe, 2 Kommentare, 8 Danke


1. Vorwort

Google bietet über die GMail-API die Voraussetzungen um sein Google-Mail-Konto über diverse Programmierschnittstellen (PHP/Javascript/etc. pp) zu verwalten. Die Authentifizierung der Anwendung welche auf das GMail Konto zugreift, kann dabei über die sichere OAuth-Methode geschehen. Für alle die dies nativ ohne zusätzliche DLLs mit der Powershell benötigen, habe ich mal eine Funktion zur Authentifizierung per OAuth und ein paar der wichtigsten Funktionen zur Verwaltung der Mails geschrieben.
Hauptsächlich sind dies folgende.

Funktionsname Verwendung
Auth-Google Authentifizierung der App per OAuth Methode
Get-GoogleMails Ruft eine Liste von Mails ab welche man mit mehreren Parametern filtern kann
Set-GoogleMailLabels Hiermit verändert man die Labels/Flags einer Nachricht um sie z.B. als gelesen zu markieren oder einer Kategorie zuzuordnen
Remove-GoogleMailMessageLöschen einer Nachricht
Send-GoogleMailMessageSenden einer Nachricht inkl. Attachments

Die Einrichtung der Zugangsdaten in der Google-Developer-Konsole und die Nutzung der Funktionen wird in den folgenden Arbeitsschritten erläutert

2. Erstellen der OAuth Zugangsdaten für das GMail-API

Für den Zugriff via Google API benötigen wir entsprechende Zugangsdaten für unser Skript. Namentlich sind das folgende:
  • Client-ID
  • Clientschlüssel
Meist generiert man hier separate Zugangsdaten für jede Applikation um in der Developerkonsole eine Statistik für jede seiner App abrufen zu können.

Anhand der folgenden Bilderreihe schildere ich die Vorgehensweise wie man diese Zugangsdaten erzeugt.

Zuerst melden wird uns an unserem Google-Konto an und rufen dann folgende Webseite auf:
https://console.developers.google.com

Nun folgt der Bilderreihe welche selbsterklärend sein sollten.

cc7bb40f257dbe7c3e97a55ed1c1e888 - Klicke auf das Bild, um es zu vergrößern

e20b40683b53f1f81260a77d8f7b119e - Klicke auf das Bild, um es zu vergrößern

a68a8209daf69a630317c6e16af7a9b3 - Klicke auf das Bild, um es zu vergrößern

3a3df340d0c164551973b517fb73ec8a - Klicke auf das Bild, um es zu vergrößern

a6f2cf4d1c85f9d7585b79fdddc6144f - Klicke auf das Bild, um es zu vergrößern

28f32f63ca09cef79c51c6ba9445621e - Klicke auf das Bild, um es zu vergrößern

320bfe8b4011cb74769fb52684658d9c - Klicke auf das Bild, um es zu vergrößern

b9b750e7c457325cc7d653a30c66aeff - Klicke auf das Bild, um es zu vergrößern

92f8416d4ae970888c30938ce14f83ce - Klicke auf das Bild, um es zu vergrößern

40b50aaa7e4b0f58d78ef757a41caaef - Klicke auf das Bild, um es zu vergrößern

Hier erfahren wir nun endlich unsere gewünschten Zugangsdaten

69dd38531f6ea6d387065d556c0dfcc4 - Klicke auf das Bild, um es zu vergrößern


3. Anpassung der Variablen im Header

Nachdem wir die Zugangsdaten erhalten haben fügen wir diese im Header des Skripts ein.
Zusätzlich geben wir hier die E-Mail-Adresse des Google-Kontos an.
Wenn man will kann man hier auch den Pfad anpassen in welcher das Refresh-Token als Datei abgelegt wird. Standardmäßig im selben Verzeichnis wie das Skript. Zur Funktion des Refresh-Tokens später mehr.
$global:scopes legt die Zugriffsberechtigung des Skripts auf das Google-Konto fest. Google arbeitet hier mit URLs die je nachdem bestimmte Zugriffsrechte auf das Google Konto gewähren. Die hier benutzte URL gibt dem Skript Vollzugriff auf alle GMail-Funktionen. Man kann hier z.B. auch nur Leserechte gewähren wenn man das möchte. Natürlich sind dann Funktionen welche Mails löschen oder verändern nicht möglich. Mehr zu den Scopes findet man in der API-Referenz zu den Scopes
01.
# ANPASSUNGEN HIER VORNEHMEN ===========================================================
02.

03.
# Client API Zugangsdaten hier eintragen
04.
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
05.
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
06.
# Array der Bereiche die autorisiert werden sollen (In diesem Beispiel erhält die Anwendung Vollzugriff auf alle GMail Funktionen)
07.
$global:scopes = @('https://mail.google.com/')
08.
# Pfad in dem das Refresh-Token gespeichert wird mit dem man ein neues Access Token anfordert (Standardmäßig der Ordner in dem das Skript liegt)
09.
$global:token_path = "$(Split-Path $PSCommandPath -Parent)\refresh.token"
10.
# E-Mail-Adresse des Google-Kontos
11.
$global:gmail_email = 'USER@GMAIL.COM'
12.

13.
# ENDE EINRICHTUNG =====================================================================

4. Haupt-Powershell-Code

01.
<#
02.
    #####################################################
03.
    ###### Google GMAIL-Verwaltung (c) @colinardo #######
04.
    #####################################################
05.
    -> benötigt wird mind. PS Version 3.0
06.
#>
07.

08.
# ANPASSUNGEN HIER VORNEHMEN ===========================================================
09.

10.
# Client API Zugangsdaten hier eintragen
11.
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
12.
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
13.
# Array der Bereiche die autorisiert werden sollen (In diesem Beispiel erhält die Anwendung Vollzugriff auf alle GMail Funktionen)
14.
$global:scopes = @('https://mail.google.com/')
15.
# Pfad in dem das Refresh-Token gespeichert wird mit dem man ein neues Access Token anfordert (Standardmäßig der Ordner in dem das Skript liegt)
16.
$global:token_path = "$(Split-Path $PSCommandPath -Parent)\refresh.token"
17.
# E-Mail-Adresse des Google-Kontos
18.
$global:gmail_email = 'USER@GMAIL.COM'
19.

20.
# ENDE EINRICHTUNG =====================================================================
21.

22.
Add-Type -AssemblyName System.Windows.Forms
23.

24.
<# 
25.
    -------------------------------------------------------------------------------------------
26.
    Funktion: Auth-Google - Haupt-Authentifizierungsfunktion (OAuth 2.0) für Zugriffe auf die Google-Dienste
27.
    -------------------------------------------------------------------------------------------
28.
#>
29.
function Auth-Google {
30.
    # Wenn refresh.token Datei vorhanden lese Token aus
31.
    if ((Test-Path $global:token_path)){
32.
        $content = gc $global:token_path -TotalCount 1
33.
        if ($content.length -gt 0){$global:refresh_token = $content}
34.
    }
35.
    # wenn kein Refresh-Token vorhanden ist, initiale Authorization starten ...
36.
    if(!$global:refresh_token){
37.
        $url = "https://accounts.google.com/o/oauth2/auth?scope=$($global:scopes -join " ")&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=$client_id"
38.
        # Manuelle Authorization mit Userinteraktion
39.
        write-host "Starting Authorization Request in Browser ... (Please Login into your Google-Account, and accept the authorization request, copy the returned code and close the Browser-Window !" -ForegroundColor Green
40.
        Start-Process "iexplore.exe" -ArgumentList $url -Wait
41.
        $authcode = [System.Windows.Forms.Clipboard]::GetText()
42.
        
43.
        $requestbody = @{
44.
        "code"=$authcode
45.
        "client_id"=$client_id
46.
        "client_secret"=$client_secret
47.
        "redirect_uri"='urn:ietf:wg:oauth:2.0:oob'
48.
        "grant_type"="authorization_code"
49.
        }
50.
    
51.
        $result = Invoke-RestMethod 'https://www.googleapis.com/oauth2/v3/token' -Method Post -Body $requestbody
52.
        $global:refresh_token = $result.refresh_token
53.
        set-content $global:token_path -Value $global:refresh_token
54.
        $global:access_token = $result.access_token
55.
        $global:token_expires = $result.expires_in
56.
        $global:token_created = get-date
57.
        return $true
58.
    }else{
59.
        # kein access_token vorhanden => neues access_token via refresh holen
60.
        if (!$global:access_token){
61.
            write-host "Refreshing access_token ..."
62.
            $requestbody = @{
63.
            "refresh_token"=$global:refresh_token
64.
            "client_id"=$client_id
65.
            "client_secret"=$client_secret
66.
            "grant_type"="refresh_token"
67.
            }
68.
            Try{
69.
                $tokenrequest = Invoke-RestMethod 'https://www.googleapis.com/oauth2/v3/token' -Method Post -Body $requestbody -EA Stop
70.
                $global:access_token = $tokenrequest.access_token
71.
                $global:token_created = get-date
72.
                $global:token_expires = $tokenrequest.expires_in
73.
                return $true
74.
            }catch{
75.
                write-host $_.Exception.Message
76.
                return $false
77.
            }
78.
        }else{
79.
            # access_token vorhanden, überprüfe ob es abgelaufen ist
80.
            if((((get-date) - $global:token_created).TotalSeconds) -ge $global:token_expires){
81.
                # access_token ist abgelaufen => fordere ein neues an
82.
                write-host "Access Token has expired ..."
83.
                $global:access_token = ""
84.
                Auth-Google
85.
            }else{
86.
                # gültiges access_token vorhanden
87.
                return $true
88.
            }
89.
        }
90.
    }
91.
}
92.

93.
<# 
94.
    ------------------------------------
95.
    Funktion: Get-GoogleMails
96.
    ------------------------------------
97.
#>
98.
function Get-GoogleMails([string[]]$labels = @('INBOX','UNREAD'),[switch]$includespamtrash,[string]$query,[switch]$raw,[int]$maxResults = 100000 ){
99.
    if(!(Auth-Google)){
100.
        return $false 
101.
    }
102.
    Try{
103.
        $param_spam = $(if($includespamtrash.IsPresent){'&includeSpamTrash=true'}else{'&includeSpamTrash=false'})
104.
        $param_format = $(if($raw.IsPresent){'&format=raw'}else{'&format=full'})
105.
        $param_labels = $(if($labels){'&labelIds=' + $($labels -join '&labelIds=')})
106.
        $param_query = $(if($query){"&q=$([System.Net.WebUtility]::UrlEncode($query))"})
107.
        $uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages?access_token=$($global:access_token)$param_labels$param_spam$param_query&maxResults=$maxResults"
108.
        $result = Invoke-RestMethod $uri -Method Get -ErrorAction Stop
109.
        $mails = @()
110.
        $result.messages.id | %{
111.
            $messageId = $_
112.
            $mail = irm -Uri "https://www.googleapis.com/gmail/v1/users/$($global:gmail_email)/messages/$($messageId)?access_token=$($global:access_token)$param_format" -Method Get -EA Stop
113.
            # UNIX Datum umwandeln
114.
            $mail | add-member -MemberType NoteProperty -Name "Date" -Value ([timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddMilliseconds($mail.internalDate)))
115.
            # Simplen Body extrahieren
116.
            if ($mail.payload.body.data){
117.
                $b64data = $mail.payload.body.data.replace('-','+').replace('_','/')
118.
                $mail | add-member -MemberType NoteProperty -Name 'Body' -Value ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))
119.
            }
120.
            # komplexeren Body bestehend aus Plaintext und HTML Parts und Attachments extrahieren
121.
            if ($mail.payload.parts){
122.
                $mail | add-member -MemberType NoteProperty -Name "Attachments" -Value @()
123.
                $mail | add-member -MemberType NoteProperty -Name "BodyParts" -Value @()
124.

125.
                $mail.payload.parts | %{
126.
                    if($_.filename -eq $null -and $_.body.data -ne $null){
127.
                        $b64data = $_.body.data.replace('-','+').replace('_','/') # google benutzt eine andere Base64 Tabelle
128.
                        $mail.BodyParts += ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))
129.
                    }elseif($_.filename -eq "" -and $_.parts -ne $null){
130.
                        $_.parts | %{
131.
                            $b64data = $_.body.data.replace('-','+').replace('_','/')
132.
                            $mail.BodyParts += New-Object PSObject -Property ([ordered]@{'partId'=$_.partId;'value'=([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))})
133.
                        }
134.
                    }elseif($_.filename -ne $null -and $_.body.attachmentId -ne $null){
135.
                        # part ist ein Attachment
136.
                        $attachment = irm -uri "https://www.googleapis.com/gmail/v1/users/$($global:gmail_email)/messages/$($messageId)/attachments/$($_.body.attachmentId)?access_token=$($global:access_token)$param_format" -Method Get -EA Stop
137.
                        # custom attachment object mit den wichtigsten Daten erstellen und Umwandlung der Base64 Daten in Byte-Array
138.
                        $attachment_object = New-Object PSObject -Property @{'Name'=$_.filename;'Size'=$attachment.Size;'Data'=[convert]::FromBase64String($attachment.data.replace('-','+').replace('_','/'))}
139.
                        # Methode zum Speichern des Attachments hinzufügen
140.
                        $attachment_object | add-member -MemberType ScriptMethod -Name SaveAs -Value {param([parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$filepath)[System.IO.File]::WriteAllBytes($filepath,$this.Data)}
141.
                        $mail.Attachments += $attachment_object
142.
                    }
143.
                }
144.
            }
145.
            # Header leichter zugänglich machen
146.
            if($mail.payload.headers){
147.
                $headers = @{}
148.
                $mail.payload.headers | %{$headers[$_.name] += @($_.value)}
149.
                $mail | add-member -MemberType NoteProperty -Name Headers -Value $headers
150.
            }
151.
            if($mail.raw){
152.
                $b64data = $mail.raw.replace('-','+').replace('_','/') # google benutzt eine andere Base64 Tabelle
153.
                $mail | add-member -MemberType NoteProperty -Name "Body" -Value ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))
154.
            }
155.
            # mail zum Array hinzufügen
156.
            $mails += $mail
157.
        }
158.
        return $mails
159.
        
160.
    }catch [System.Net.WebException]{
161.
        write-host $_.Exception.Message -F Red
162.
        return $false
163.
    }
164.
}
165.
<# 
166.
    ----------------------------------------
167.
    Funktion: Set-GoogleMailLabels
168.
    ----------------------------------------
169.
#>
170.
function Set-GoogleMailLabels([string]$messageid,[string[]]$addlabels,[string[]]$removeLabels){
171.
        if(!(Auth-Google)){
172.
        return $false 
173.
    }
174.
    Try{
175.
        $body_labels = @{}
176.
        if($removeLabels){$body_labels."removeLabelIds" = $removelabels}
177.
        if($addlabels){$body_labels."addLabelIds" = $addlabels}
178.
        $body_labels = $body_labels | ConvertTo-JSON
179.

180.
        $uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/$($messageid)/modify?access_token=$($global:access_token)"
181.
        $result = Invoke-RestMethod $uri -Method POST -ErrorAction Stop -Body $body_labels -ContentType "application/json"
182.
        return $result
183.
    }catch [System.Net.WebException]{
184.
        write-host $_.Exception.Message -F Red
185.
        return $false
186.
    }
187.
}
188.

189.
<# 
190.
    ----------------------------------------
191.
    Funktion: Remove-GoogleMailMessage
192.
    ----------------------------------------
193.
#>
194.
function Remove-GoogleMailMessage([string]$messageid){
195.
    if(!(Auth-Google)){
196.
        return $false 
197.
    }
198.
    Try{
199.
        $uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/$($messageid)?access_token=$($global:access_token)"
200.
        return irm $uri -Method Delete -ErrorAction Stop
201.
    }catch [System.Net.WebException]{
202.
        write-host $_.Exception.Message -F Red
203.
        return $false
204.
    }
205.
}
206.

207.
<# 
208.
    ----------------------------------------
209.
    Funktion: Send-GoogleMailMessage
210.
    ----------------------------------------
211.
#>
212.
function Send-GoogleMailMessage([string]$from = $global:gmail_email,[string[]]$to,[string[]]$cc,[string[]]$bcc,[string]$subject,[string]$body,[switch]$IsHtml,[string[]]$attachments){
213.
        if(!(Auth-Google)){
214.
        return $false 
215.
    }
216.
    Try{
217.
        $mail = new-Object System.Net.Mail.MailMessage
218.
        $mail.From = $from
219.
        $to | %{$mail.to.Add($_)}
220.
        if($cc){$cc | %{$mail.cc.Add($_)}}
221.
        if($bcc){$bcc | %{$mail.Bcc.Add($_)}}
222.
        if($attachments){$attachments | %{$mail.Attachments.Add($_)}}
223.
        $mail.Subject = $subject
224.
        $mail.Body = $body
225.
        $mail.IsBodyHtml = $(if($IsHtml.IsPresent){$true}else{$false})
226.
        $mail.BodyEncoding = [System.Text.Encoding]::UTF8
227.
        $mail.BodyTransferEncoding = [System.Net.Mime.TransferEncoding]::Base64
228.

229.
        $flags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic
230.
        $MailWriter = [System.Net.Mail.SmtpClient].Assembly.GetType("System.Net.Mail.MailWriter")
231.
        $MailWriterConstructor = $MailWriter.GetConstructor($flags,$null,([System.IO.Stream]),$null)
232.
        $sendMethod = [System.Net.Mail.MailMessage].GetMethod("Send",$flags)
233.
        $closeMethod = [System.Net.Mail.MailMessage].GetMethod("Close",$flags)
234.
        $result = New-Object System.IO.MemoryStream
235.
        $writer = $MailWriterConstructor.Invoke($result)
236.
        $sendMethod.Invoke($mail,$flags,$null,@($writer,$true,$true),$null)
237.
        $b64String = [System.Convert]::ToBase64String($result.toArray())
238.
        $result.Close(); $result.Dispose()
239.

240.
        $body = @{
241.
            "raw" = $b64String
242.
        } | ConvertTo-Json
243.
        $uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/send?access_token=$($global:access_token)"
244.
        $result = Invoke-RestMethod $uri -Method POST -ErrorAction Stop -Body $body -ContentType "application/json"
245.
        return $result
246.
    }catch [System.Net.WebException]{
247.
        write-host $_.Exception.Message -F Red
248.
        return $false
249.
    }
250.
}

5. Erläuterungen zur Anwendung der einzelnen Funktionen

5.1 Auth-Google

Diese Funktion stellt sicher das sich die Anwendung bei Google per OAuth 2.0 anmeldet und das benötigte Access-Token für die Anfragen an das API abruft. Existiert noch kein Access-Token z.B. weil die Anwendung das erste mal ausgeführt wird muss die sich die Anwendung erst die Berechtigung des Anwenders holen. Dazu öffnet das Skript beim ersten mal ein Internet-Explorer-Fenster welches auf eine spezielle Autorisierungs-URL leitet. Man loggt sich mit seinem Google-Konto ein und bestätigt dann die Abfrage mit Klick auf den Button Zulassen. Dann erscheint ein Code in einem Textfeld. Diesen kopiert man nun in die Zwischenablage(WICHTIG), und schließt dann das Internet-Explorer Fenster. Das Powershell-Skript bekommt nun mit das der IE geschlossen wurde und schließt die Anforderung des Tokens mit dem Code aus der Zwischenablage ab.
Ein sogenanntes Refresh-Token wird dann in einer Datei namens refresh.token im selben Verzeichnis wie das PS-Skript gespeichert.
Da die angeforderten Access-Tokens immer nur eine bestimmte Gültigkeit haben (meist 30-60 Minuten), muss das Skript also auch regelmäßig ein aktuelles Token anfordern. Dies kann es mit dem Refresh-Token welches als refresh.token gesichert wurd, tun. Dieses File ist also sehr wichtig, denn nur damit kann sich das Skript ohne Userinteraktion bei Google anmelden. Wird das File gelöscht und die PS-Session geschlossen, durchläuft die Funktion zwingend erneut die Anforderung eines Autorisationscodes wie zu Beginn.

Die einzelnen folgenden Funktionen rufen diese Funktion zu Beginn immer auf um sicherzustellen das unser Skript ein gültiges Token für die folgenden Abfragen hat.

5.2 Get-GoogleMails

Diese Funktion ruft eine Liste der Mails ab welche wir über folgende Parameter filtern können

ParameterBeschreibung
[string[]]$labels = @('INBOX','UNREAD') Die Mails müssen alle hier in einem Array angegebenen Labels haben damit sie abgerufen werden, ohne Angabe sind das per Default hier nur ungelesene Mails aus dem Posteingang. Sollen alle Mails berücksichtigt werden einfach ein leeres Array @() übergeben.
[switch]$includespamtrash Switch wenn man möchte das Mails aus dem Mülleimer mit beachtet werden
[string]$query Hier kann ein Querystring zum Abfragen einzelner Mail-Felder angegeben werden. Die Syntax folgt der welche man auch im Suchfeld von GMail verwendet, Beispiel from:user@domain.de
[switch]$raw Switch wenn man den RAW-Inhalt einer Mail erhalten will (siehe dazu https://developers.google.com/gmail/api/v1/reference/users/messages/get)
Für einen leichteren Umgang mit dem Inhalt der Mails (Body/Header/etc.) habe ich ein paar Felder zu den standardmäßig von Google per JSON bereitgestellten hinzugefügt um sie leichter abrufen zu können. Das sind z.B. der Body (Text und HTML wenn vorhanden) die Header und das Empfangsdatum.
Alle verfügbaren Eigenschaften könnt Ihr euch ja einfach per get-member anzeigen lassen.
[int]$maxResults=100000Maximale Anzahl an Mails die abgerufen werden sollen

Ein exemplarischer Aufruf der alle Mails aus dem Posteingang abruft und in der Variablen $mails speichert, sieht dann so aus
01.
$mails = Get-GoogleMails -labels @("INBOX")
Die Funktion enthält nun auch die Attachments in einer einfach abzurufender Weise. Beispiel zum auflisten der Attachments von Mails mit Attachment in der Inbox
01.
$mails = Get-GoogleMails -query 'has:attachment' -labels @("INBOX")
02.
$mails | %{
03.
    write-host "Mail: $($_.Headers.Subject)" -F Green
04.
    $_.Attachments
05.
}
Die Attachment-Objekte enthalten die Daten als Byte-Array[]. Eine benutzerdefinierte Skriptmethode zum Speichern der Attachments im Dateisystem wurde ebenfalls implementiert. Sie lautet SaveAs(<Pfad>). So kann man jedes Attachment abspeichern.
01.
$mails = Get-GoogleMails -query 'has:attachment' -labels @("INBOX")
02.
$mails | %{
03.
    write-host "Mail: $($_.Headers.Subject)" -F Green
04.
    $_.Attachments | %{
05.
        $_.SaveAs("<PFAD für das ATTACHMENT>")
06.
   }
07.
}

5.3 Set-GoogleMailLabels

Diese Funktion verändert die Tags/Labels einer Nachricht. Damit lässt sich eine Mail unter anderem als gelesen markieren indem man das UNREAD Flag entfernt.

Parameter

ParameterBeschreibung
[string]$messageid Die ID der Nachricht. Die ID erhalten wir als Eigenschaft für jede Mail welche wir oben mit Get-GoogleMails abgerufen haben
[string[]]$addlabels Ein String-Array aus Label-Namen welche der Mail hinzugefügt werden sollen
[string[]]$removelabels Ein String-Array aus Label-Namen welche von der Mail entfernt werden sollen
WICHTIG: Die Labels müssen schon in Google existieren, könnt Ihr wenn Ihr wollt mit dem API auch automatisiert hinzufügen, habe das in der Funktion aus Zeitgründen noch nicht hinzugefügt.

Exemplarischer Aufruf um die erste Mail welche wir oben mit Get-GoogleMails abgerufen haben als gelesen zu markieren
Set-GoogleMailLabels -messageid $mails[0].id -removelabels "UNREAD"

5.4 Remove-GoogleMailMessage

Die Funktion macht was ? Natürlich leicht zu erraten, sie löscht Mails.

Parameter

ParameterBeschreibung
[string]$messageid Die ID der Nachricht. Die ID erhalten wir als Eigenschaft für jede Mail welche wir oben mit Get-GoogleMails abgerufen haben

Exemplarischer Aufruf um die erste Mail welche wir oben vorher mit Get-GoogleMails abgerufen haben, zu löschen
Remove-GoogleMailMessage -messageid $mails[0].id

5.5 Send-GoogleMailMessage

Die Funktion sendet eine Mail über das GMail-System.

Parameter

ParameterBeschreibung
[string]$from = $global:gmail_email Absender-Email-Adresse festlegen, ohne Angabe wird hier die im Header des Skripts angegebene Adresse verwendet
[string[]]$to String-Array aus Empfängeradressen
[string[]]$cc String-Array aus CC-Adressen
[string[]]$bcc String-Array aus BCC-Adressen
[string]$subject Betreff der Nachricht
[string]$body Body der Nachricht. Wenn der Switch $isHtml gesetzt ist kann dieser auch HTML-Anweisungen enthalten
[switch]$IsHtml Switch gibt an ob der Body HTML-Anweisungen enthält, welche angewendet werden sollen
[string[]]$attachments Ein String-Array aus Dateisystem-Pfaden welche als Attachments an die Mail angehängt werden sollen

Exemplarischer Aufruf zum Versenden einer Mail
01.
Send-GoogleMailMessage -to "user@domain.de" -subject "Testsubject" -body "Mein Body kann auch <strong>HTML</strong> enthalten." -IsHtml -attachments 'C:\test.txt'

6. Abschließende Kommentare

Ich weiß das die Anleitung noch nicht sämtliche mögliche Funktionen de GMail-Apis bereitstellt, das war auch nicht meine Intention. Anhand der einzelnen Funktionen kann man sich aber nun sehr einfach ab schauen, wie man Requests an das API schickt und verarbeitet. Es sollte also mit Hilfe der API-Dokumentation zu GMail nun nicht mehr viel Arbeit sein, seine eigenen Funktionen zum implementieren.

Die Authentifizierungs-Funktion kann ebenfalls auch für die anderen APIs wie z.B. das Kalender-API benutzt werden. Ich habe hier auch schon einige Funktionen für den Google-Kalender geschrieben, die ich bei Zeiten auch mal veröffentlichen werde so es die Zeit zulässt.

Ich hoffe ihr habt nun viel Spaß mit dem Skript.

Wie immer geschieht die Verwendung jeglichen Codes auf eigene Gefahr ... Bei Verwendung des Codes in anderen Projekten bitte einen Vermerk der Quelle auf diese Seite einfügen.

Gruß @colinardo

Gefällt euch der Beitrag und Ihr wollt weiterhin solche Beiträge hier sehen, freue ich mich wie immer auf eine kleine Spende.
If you like my contribution please support me and donate

Updates

Datum Änderung
08.06.2016 Fehlerbehebung in der Auth-Google Funktion.
04.01.2016 Update und Fehlerbehebung der Funktion Get-GoogleMails. Diese wurde um eine einfachere Verarbeitung von Attachments erweitert
Mitglied: 114757
22.12.2015, aktualisiert um 19:51 Uhr
@colinardo HAMMER kann man dazu nur sagen

Vielen Dank....
THUMBS UP! Weiter so!

Gruß jodel

p.s. Die Google-Kalender-Funktionen die du anscheinend auf Lager hast würden mich auch sehr interessieren Ich klingel dazu aber mal bei dir an wenn ich darf...
Bitte warten ..
Mitglied: bitrider
28.12.2015 um 15:02 Uhr
Ich bin begeistert
Danke dir
Bitte warten ..
Ähnliche Inhalte
Batch & Shell
Powershell elevated
Tipp von AnkhMorporkBatch & Shell2 Kommentare

Ein kleiner Tipp am Rande für alle PS-Novizen (ich wars einfach leid): Um eine Konsole mit elevated rights schnell ...

Batch & Shell
Weiterentwicklung von Powershell
Information von Penny.CilinBatch & Shell

Anbei ein Artikel im Heise Newsticker bzgl. Powershell: Systemverwaltung: PowerShell goes Cross-Plattform

Windows 10
Powershell 5 BSOD
Tipp von agowa338Windows 108 Kommentare

Aktuell gibt es in PowerShell (Version 5.11.4393.206) einen sehr fiesen Bug. Wenn man die PowerShell "Als Administrator" startet und ...

Batch & Shell

Robocopy mit Powershell und Fortschrittsanzeige

Anleitung von SamTrexBatch & Shell2 Kommentare

Die Aufgabe Ich sichere von Zeit zu Zeit verschiedene Verzeichnisse von unserem Familien-Server auf mehrere externe Festplatten weg. In ...

Neue Wissensbeiträge
Windows 7

Windows 7 u. Server 2008 (R2) SHA-2-Update kommt am 12. März 2019

Information von kgborn vor 1 TagWindows 75 Kommentare

Kleine Info für die Admins der oben genannten Maschinen. Ab Juli 2019 werden Updates von Microsoft nur noch mit ...

Firewall
PfSense 2.5.0 benötigt doch kein AES-NI
Information von ChriBo vor 2 TagenFirewall2 Kommentare

Hallo, Wie sich einige hier erinnern werden hat Jim Thompson in diesem Aritkel beschrieben, daß ab Version 2.5.0 ein ...

Internet
Copyright-Reform: Upload-Filter
Information von Frank vor 4 TagenInternet1 Kommentar

Hallo, viele Menschen reden aktuell von Upload-Filtern. Sie reden darüber, als wären es eine Selbstverständlichkeit, das Upload-Filter den Seitenbetreibern ...

Google Android

Blokada: Tracking und Werbung unter Android unterbinden

Information von AnkhMorpork vor 4 TagenGoogle Android1 Kommentar

In Ergänzung zu meinem vorherigen Beitrag: Blokada efficiently blocks ads, tracking and malware. It saves your data plan, makes ...

Heiß diskutierte Inhalte
Hardware
IT-Werkzeugkoffer bis 50,- EUR
gelöst Frage von departure69Hardware43 Kommentare

Hallo. Ich bin als IT-Systembetreuer einer Gemeinde zusätzlich auch der IT-Systembetreuer einer Grund- und Hauptschule. Dort muß ich jedoch ...

Netzwerke
Verteilung von Programmdaten außerhalb des internen Netzwerkes
Frage von mertaufmbergNetzwerke27 Kommentare

Guten Morgen liebe Administratoren, ich versuche zurzeit eine möglichst sichere und einfache Lösung zu suchen, um ein Programmverzeichnis über ...

Netzwerkmanagement
Richtfunknetzwerk mit vielen Hops stabiler gestalten
Frage von turti83Netzwerkmanagement22 Kommentare

Hallo, in meinem Dorf habe ich vor ca. einem Jahr ein Backbone aufgebaut um die Nachbarschaft mit Internet zu ...

Hyper-V
Intel MSC Raid 5 Rebuild
Frage von DannysHyper-V19 Kommentare

Hallo Community, Ich habe einen Modul Server von Intel in Betrieb. Dort ist eine Festplatte aus dem Raid 5 ...