Powershell: Googlemail (GMail) nativ mit Powershell verwalten
Inhaltsverzeichnis
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-GoogleMailMessage | Löschen einer Nachricht |
Send-GoogleMailMessage | Senden 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
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.
Hier erfahren wir nun endlich unsere gewünschten Zugangsdaten
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
# ANPASSUNGEN HIER VORNEHMEN ===========================================================
# Client API Zugangsdaten hier eintragen
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
# Array der Bereiche die autorisiert werden sollen (In diesem Beispiel erhält die Anwendung Vollzugriff auf alle GMail Funktionen)
$global:scopes = @('https://mail.google.com/')
# 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)
$global:token_path = "$(Split-Path $PSCommandPath -Parent)\refresh.token"
# E-Mail-Adresse des Google-Kontos
$global:gmail_email = 'USER@GMAIL.COM'
# ENDE EINRICHTUNG =====================================================================
4. Haupt-Powershell-Code
<#
#####################################################
###### Google GMAIL-Verwaltung (c) @colinardo #######
#####################################################
-> benötigt wird mind. PS Version 3.0
#>
# ANPASSUNGEN HIER VORNEHMEN ===========================================================
# Client API Zugangsdaten hier eintragen
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
# Array der Bereiche die autorisiert werden sollen (In diesem Beispiel erhält die Anwendung Vollzugriff auf alle GMail Funktionen)
$global:scopes = @('https://mail.google.com/')
# 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)
$global:token_path = "$(Split-Path $PSCommandPath -Parent)\refresh.token"
# E-Mail-Adresse des Google-Kontos
$global:gmail_email = 'USER@GMAIL.COM'
# ENDE EINRICHTUNG =====================================================================
Add-Type -AssemblyName System.Windows.Forms
# Accept all TLS protocols
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::GetNames([System.Net.SecurityProtocolType])
<#
-------------------------------------------------------------------------------------------
Funktion: Auth-Google - Haupt-Authentifizierungsfunktion (OAuth 2.0) für Zugriffe auf die Google-Dienste
-------------------------------------------------------------------------------------------
#>
function Auth-Google {
# Wenn refresh.token Datei vorhanden lese Token aus
if ((Test-Path $global:token_path)){
$content = gc $global:token_path -TotalCount 1
if ($content.length -gt 0){$global:refresh_token = $content}
}
# wenn kein Refresh-Token vorhanden ist, initiale Authorization starten ...
if(!$global:refresh_token){
$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"
# Manuelle Authorization mit Userinteraktion
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
Start-Process "iexplore.exe" -ArgumentList $url -Wait
$authcode = [System.Windows.Forms.Clipboard]::GetText()
$requestbody = @{
"code"=$authcode
"client_id"=$client_id
"client_secret"=$client_secret
"redirect_uri"='urn:ietf:wg:oauth:2.0:oob'
"grant_type"="authorization_code"
}
$result = Invoke-RestMethod 'https://www.googleapis.com/oauth2/v3/token' -Method Post -Body $requestbody
$global:refresh_token = $result.refresh_token
set-content $global:token_path -Value $global:refresh_token
$global:access_token = $result.access_token
$global:token_expires = $result.expires_in
$global:token_created = get-date
return $true
}else{
# kein access_token vorhanden => neues access_token via refresh holen
if (!$global:access_token){
write-host "Refreshing access_token ..."
$requestbody = @{
"refresh_token"=$global:refresh_token
"client_id"=$client_id
"client_secret"=$client_secret
"grant_type"="refresh_token"
}
Try{
$tokenrequest = Invoke-RestMethod 'https://www.googleapis.com/oauth2/v3/token' -Method Post -Body $requestbody -EA Stop
$global:access_token = $tokenrequest.access_token
$global:token_created = get-date
$global:token_expires = $tokenrequest.expires_in
return $true
}catch{
write-host $_.Exception.Message
return $false
}
}else{
# access_token vorhanden, überprüfe ob es abgelaufen ist
if((((get-date) - $global:token_created).TotalSeconds) -ge $global:token_expires){
# access_token ist abgelaufen => fordere ein neues an
write-host "Access Token has expired ..."
$global:access_token = ""
Auth-Google
}else{
# gültiges access_token vorhanden
return $true
}
}
}
}
<#
------------------------------------
Funktion: Get-GoogleMails
------------------------------------
#>
function Get-GoogleMails([string[]]$labels = @('INBOX','UNREAD'),[switch]$includespamtrash,[string]$query,[switch]$raw,[int]$maxResults = 100000){
if(!(Auth-Google)){
return $false
}
Try{
$param_spam = $(if($includespamtrash.IsPresent){'&includeSpamTrash=true'}else{'&includeSpamTrash=false'})
$param_format = $(if($raw.IsPresent){'&format=raw'}else{'&format=full'})
$param_labels = $(if($labels){'&labelIds=' + $($labels -join '&labelIds=')})
$param_query = $(if($query){"&q=$([System.Net.WebUtility]::UrlEncode($query))"})
$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"
$result = Invoke-RestMethod $uri -Method Get -ErrorAction Stop
$mails = @()
$result.messages.id | %{
$messageId = $_
$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
# UNIX Datum umwandeln
$mail | add-member -MemberType NoteProperty -Name "Date" -Value ([timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddMilliseconds($mail.internalDate)))
# Simplen Body extrahieren
if ($mail.payload.body.data){
$b64data = $mail.payload.body.data.replace('-','+').replace('_','/')
$mail | add-member -MemberType NoteProperty -Name 'Body' -Value ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))
}
# Attachments extrahieren
if ($mail.payload.parts){
$mail | add-member -MemberType NoteProperty -Name "Attachments" -Value @()
$mail.payload.parts | %{
if($_.filename -ne "" -and $_.body.attachmentId -ne $null){
# part ist ein Attachment
$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
# custom attachment object mit den wichtigsten Daten erstellen und Umwandlung der Base64 Daten in Byte-Array
$attachment_object = New-Object PSObject -Property @{'Name'=$_.filename;'Size'=$attachment.Size;'Data'=[convert]::FromBase64String($attachment.data.replace('-','+').replace('_','/'))}
# Methode zum Speichern des Attachments hinzufügen
$attachment_object | add-member -MemberType ScriptMethod -Name SaveAs -Value {param([parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$filepath)[System.IO.File]::WriteAllBytes($filepath,$this.Data)}
$mail.Attachments += $attachment_object
}
}
}
# Header leichter zugänglich machen
if($mail.payload.headers){
$headers = @{}
$mail.payload.headers | %{$headers[$_.name] += @($_.value)}
$mail | add-member -MemberType NoteProperty -Name Headers -Value $headers
}
if($mail.raw){
$b64data = $mail.raw.replace('-','+').replace('_','/') # google benutzt eine andere Base64 Tabelle
$mail | add-member -MemberType NoteProperty -Name "Body" -Value ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($b64data)))
}
# mail zum Array hinzufügen
$mails += $mail
}
return $mails
}catch [System.Net.WebException]{
write-host $_.Exception.Message -F Red
return $false
}
}
<#
----------------------------------------
Funktion: Set-GoogleMailLabels
----------------------------------------
#>
function Set-GoogleMailLabels([string]$messageid,[string[]]$addlabels,[string[]]$removeLabels){
if(!(Auth-Google)){
return $false
}
Try{
$body_labels = @{}
if($removeLabels){$body_labels."removeLabelIds" = $removelabels}
if($addlabels){$body_labels."addLabelIds" = $addlabels}
$body_labels = $body_labels | ConvertTo-JSON
$uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/$($messageid)/modify?access_token=$($global:access_token)"
$result = Invoke-RestMethod $uri -Method POST -ErrorAction Stop -Body $body_labels -ContentType "application/json"
return $result
}catch [System.Net.WebException]{
write-host $_.Exception.Message -F Red
return $false
}
}
<#
----------------------------------------
Funktion: Remove-GoogleMailMessage
----------------------------------------
#>
function Remove-GoogleMailMessage([string]$messageid){
if(!(Auth-Google)){
return $false
}
Try{
$uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/$($messageid)?access_token=$($global:access_token)"
return irm $uri -Method Delete -ErrorAction Stop
}catch [System.Net.WebException]{
write-host $_.Exception.Message -F Red
return $false
}
}
<#
----------------------------------------
Funktion: Send-GoogleMailMessage
----------------------------------------
#>
function Send-GoogleMailMessage([string]$from = $global:gmail_email,[string[]]$to,[string[]]$cc,[string[]]$bcc,[string]$subject,[string]$body,[switch]$IsHtml,[string[]]$attachments){
if(!(Auth-Google)){
return $false
}
Try{
$mail = new-Object System.Net.Mail.MailMessage
$mail.From = $from
$to | %{$mail.to.Add($_)}
if($cc){$cc | %{$mail.cc.Add($_)}}
if($bcc){$bcc | %{$mail.Bcc.Add($_)}}
if($attachments){$attachments | %{$mail.Attachments.Add($_)}}
$mail.Subject = $subject
$mail.Body = $body
$mail.IsBodyHtml = $(if($IsHtml.IsPresent){$true}else{$false})
$mail.BodyEncoding = [System.Text.Encoding]::UTF8
$mail.BodyTransferEncoding = [System.Net.Mime.TransferEncoding]::Base64
$flags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic
$MailWriter = [System.Net.Mail.SmtpClient].Assembly.GetType("System.Net.Mail.MailWriter")
$MailWriterConstructor = $MailWriter.GetConstructor($flags,$null,([System.IO.Stream]),$null)
$sendMethod = [System.Net.Mail.MailMessage].GetMethod("Send",$flags)
$closeMethod = [System.Net.Mail.MailMessage].GetMethod("Close",$flags)
$result = New-Object System.IO.MemoryStream
$writer = $MailWriterConstructor.Invoke($result)
$sendMethod.Invoke($mail,$flags,$null,@($writer,$true,$true),$null)
$b64String = [System.Convert]::ToBase64String($result.toArray())
$result.Close(); $result.Dispose()
$body = @{
"raw" = $b64String
} | ConvertTo-Json
$uri = "https://www.googleapis.com/gmail/v1/users/$([System.Net.WebUtility]::UrlEncode($global:gmail_email))/messages/send?access_token=$($global:access_token)"
$result = Invoke-RestMethod $uri -Method POST -ErrorAction Stop -Body $body -ContentType "application/json"
return $result
}catch [System.Net.WebException]{
write-host $_.Exception.Message -F Red
return $false
}
}
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önnenParameter | Beschreibung |
---|---|
[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) |
Alle verfügbaren Eigenschaften könnt Ihr euch ja einfach per get-member anzeigen lassen.
[int]$maxResults=100000 | Maximale 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
$mails = Get-GoogleMails -labels @("INBOX")
$mails = Get-GoogleMails -query 'has:attachment' -labels @("INBOX")
$mails | %{
write-host "Mail: $($_.Headers.Subject)" -F Green
$_.Attachments
}
$mails = Get-GoogleMails -query 'has:attachment' -labels @("INBOX")
$mails | %{
write-host "Mail: $($_.Headers.Subject)" -F Green
$_.Attachments | %{
$_.SaveAs("<PFAD für das ATTACHMENT>")
}
}
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
Parameter | Beschreibung |
---|---|
[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 |
Exemplarischer Aufruf um die erste Mail welche wir oben mit Get-GoogleMails abgerufen haben als gelesen zu markieren
Set-GoogleMailLabels -messageid $mails.id -removelabels "UNREAD"
5.4 Remove-GoogleMailMessage
Die Funktion macht was ? Natürlich leicht zu erraten, sie löscht Mails.Parameter
Parameter | Beschreibung |
---|---|
[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.id
5.5 Send-GoogleMailMessage
Die Funktion sendet eine Mail über das GMail-System.Parameter
Parameter | Beschreibung |
---|---|
[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
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 |
---|---|
20.07.2019 | Anpassung der Funktion Get-Googlemails. |
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 |
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 291531
Url: https://administrator.de/contentid/291531
Ausgedruckt am: 14.11.2024 um 09:11 Uhr
9 Kommentare
Neuester Kommentar
@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...
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...
Google benötigt offenbar Zeit zur Prüfung, um die Authorisierung wirklich per Powershell zuzulassen.
Vorher kann man jedoch im sich öffnenden Browser das eigene Projekt (als unsicher) zulassen und kriegt einen (in meinem Fall 57-Zeichen) Code, den man in der App eingeben soll.
Allerdings erfrägt der Powershell Code keinen solchen Autorisierungs-Code (der sich bei jedem Versuch ändert!).
Das Script meldet einen Fehler:
Was kann ich tun, damit die Authorisierung funktioniert?
Vorher kann man jedoch im sich öffnenden Browser das eigene Projekt (als unsicher) zulassen und kriegt einen (in meinem Fall 57-Zeichen) Code, den man in der App eingeben soll.
Allerdings erfrägt der Powershell Code keinen solchen Autorisierungs-Code (der sich bei jedem Versuch ändert!).
Das Script meldet einen Fehler:
Invoke-RestMethod : Der Remoteserver hat einen Fehler zurückgegeben: (401) Nicht autorisiert.
In D:\Dokumente\G-Mail Attachments\Get-GMailAttachments.ps1:53 Zeichen:19
+ ... $result = Invoke-RestMethod 'https://www.googleapis.com/oauth2/v3/t ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Hallo Colinardo,
besten Dank für deinen Code - er behandelt genau was ich suche: alle Mail Attachments von Gmail herunterladen.
Gerne versuche ich mich an die Nettiquette zu halten - danke für den Hinweis!
Nach Befolgung deines Hinweises erscheint zumindest kein Authentisierungs-Fehler mehr.
Allerdings kommt eine andere Fehlermeldung (siehe unten).
Kann das daran liegen, dass ich den Scope auf READONLY gesetzt habe?
besten Dank für deinen Code - er behandelt genau was ich suche: alle Mail Attachments von Gmail herunterladen.
Gerne versuche ich mich an die Nettiquette zu halten - danke für den Hinweis!
Nach Befolgung deines Hinweises erscheint zumindest kein Authentisierungs-Fehler mehr.
Allerdings kommt eine andere Fehlermeldung (siehe unten).
Kann das daran liegen, dass ich den Scope auf READONLY gesetzt habe?
$global:scopes = @('https://www.googleapis.com/auth/gmail.readonly')
Fehlermeldung:
% : Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In D:\Dokumente\G-Mail Attachments\Get-GMailAttachments.ps1:133 Zeichen:36
+ $_.parts | %{
+ ~~
+ CategoryInfo : InvalidOperation: (:) [ForEach-Object], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand
Funktioniert wunderbar.
Herzlichen Dank!
Ein Hinweis:
da der Dateinamen zum Abspeichern von Attachments unter anderem aus dem Mail Subject gebildet wird, kann der Dateiname schon mal zu lang werden, und einen Fehler ausgeben - man sollte den Output in der PS Konsole auf rote Einträge prüfen:
... "Ein Teil des Pfades "..." konnte nicht gefunden werden."
(bricht über mehrere Zeile um)
Herzlichen Dank!
Ein Hinweis:
da der Dateinamen zum Abspeichern von Attachments unter anderem aus dem Mail Subject gebildet wird, kann der Dateiname schon mal zu lang werden, und einen Fehler ausgeben - man sollte den Output in der PS Konsole auf rote Einträge prüfen:
... "Ein Teil des Pfades "..." konnte nicht gefunden werden."
(bricht über mehrere Zeile um)