crashzero
Goto Top

Nextcloud API-Aufruf für Upload und Erstellen einer Freigabe mit Ausgabe

Es geht um eine Nextcloud 22.2.0

Es soll via Powershell von einer Workstation eine Datei in ein angelegtes Verzeichnis kopiert werden und eine Freigabe erstellt werden welche dann ausgegeben wird.

Bei dieser PS bekomme ich folgende Fehlermeldung :

Invoke-RestMethod : Der Remoteserver hat einen Fehler zurückgegeben: (401) Nicht autorisiert.
In Zeile:10 Zeichen:1
+ Invoke-RestMethod -Uri $oc$dav_endpoint$targetname -Method Put -Body  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
 
Invoke-RestMethod : {"ocs":{"meta":{"status":"failure","statuscode":997,"message":"Current user is not logged in","totalitems":"","itemsperpage":""},"data":}}  
In Zeile:22 Zeichen:13
+ $response = Invoke-RestMethod -Uri $oc$sharing_api -Method Post -Head ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Script :
$user = "Username"  
$pass= "PaswortUser"  
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)
# Upload the file
$body = $(get-content c:\scripte\tdh.png -raw)
$targetname = "tdh.png"  
$oc = "https://URL-Zum-Nextcloud.com/"  
$dav_endpoint = "remote.php/dav/files/Username/"  
Invoke-RestMethod -Uri $oc$dav_endpoint$targetname -Method Put -Body $body -Credential $credential

# Create a public share for that file:
$headers = @{"Ocs-APIREQUEST"="true"}  
$sharing_api = "ocs/v1.php/apps/files_sharing/api/v1/shares?format=json"  

# Required parameters to create the share:
$body = @{
    path = "/$($targetname)"  
    shareType = "3"  
}

$response = Invoke-RestMethod -Uri $oc$sharing_api -Method Post -Headers $headers -Body $body -Credential $credential
# Print the public link URL:
echo $response.ocs.data.url

Hat jemand eine Idee ?

Danke
Kommentar vom Moderator colinardo am 23.12.2021 um 17:01:28 Uhr
Codetags hinzugefügt

Content-ID: 1652390240

Url: https://administrator.de/contentid/1652390240

Ausgedruckt am: 17.11.2024 um 03:11 Uhr

aqui
aqui 23.12.2021 um 15:09:03 Uhr
Goto Top
Es wäre sicher für alle sehr hilfreich wenn du Code Tags benutzen würdest !!
Formatierungen in den Beiträgen

So wie oben ist der Code doch völlig unleserlich ! face-sad
(Kann man übrigens mit dem "Bearbeiten" Knopf immer nachträglich korrigieren !)
colinardo
Lösung colinardo 23.12.2021 aktualisiert um 17:02:48 Uhr
Goto Top
Servus,
erstens Passwörter solltest du in Hochkommas statt Anführungszeichen da ansonsten spezielle Zeichen wie das Dollarzeichen etc. zu einer fehlerhaften Authorization führen weil sie von der PS umgewandelt werden. Des weiteren Endpoint minimal anpassen und den Authorization-Header in den Header packen, das hier klappt in einem Test problemlos
$user = 'Username'  
$pass= 'PasswortUser'  
$credential = (new-Object PSCredential($user,(ConvertTo-SecureString $pass -AsPlainText -Force))) 
$body = get-content 'c:\scripte\tdh.png' -raw  
$targetname = "tdh.png"  
$oc = "https://URL-Zum-Nextcloud.com"  

# upload file
Invoke-RestMethod -Uri "$oc/remote.php/dav/files/$user/$targetname" -Method Put -Body $body -Credential $credential  

$headers = @{
    'OCS-APIRequest' = 'true'  
    Authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${user}:${pass}"))))"  
}

# create share
$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body @{path="/$targetname";shareType=3}  
# ... and output sharelink
$response.ocs.data.url


By the way, ich würde dir hier dringend raten nicht die echten Credentials des Users im Skript zu verwenden sondern App-Passwörter für diesen generieren und benutzen. Diese kannst du entweder in den Nextcloud-Security-Settings erstellen:

screenshot

Oder du forderst ein App-Passwort direkt automatisiert mit der Powershell an

# first request  to get webview url
$auth = irm "$endpoint/index.php/login/v2" -Method Post  
# start url with default browser
start $auth.login

$login = $null
# start polling credentials while user logs in with his credentials and grants access to his account
while(!$login){
    try{
        $login = irm $auth.poll.endpoint -Method Post -Body @{token=$auth.poll.token}
    }catch{}
    sleep 2
}
# output Username and App Password
$login.loginName
$login.appPassword

Details zu diesem Vorgang findest du hier
https://docs.nextcloud.com/server/latest/developer_manual/client_apis/Lo ...

Grüße Uwe

Frohes Fest 🎄
Crashzero
Crashzero 24.12.2021 um 06:45:03 Uhr
Goto Top
Zitat von @aqui:

Es wäre sicher für alle sehr hilfreich wenn du Code Tags benutzen würdest !!
Formatierungen in den Beiträgen

So wie oben ist der Code doch völlig unleserlich ! face-sad
(Kann man übrigens mit dem "Bearbeiten" Knopf immer nachträglich korrigieren !)

Ok,sorry.
Crashzero
Crashzero 24.12.2021 um 06:47:12 Uhr
Goto Top
Zitat von @colinardo:

Servus,
erstens Passwörter solltest du in Hochkommas statt Anführungszeichen da ansonsten spezielle Zeichen wie das Dollarzeichen etc. zu einer fehlerhaften Authorization führen weil sie von der PS umgewandelt werden. Des weiteren Endpoint minimal anpassen und den Authorization-Header in den Header packen, das hier klappt in einem Test problemlos
$user = 'Username'  
$pass= 'PasswortUser'  
$credential = (new-Object PSCredential($user,(ConvertTo-SecureString $pass -AsPlainText -Force))) 
$body = get-content 'c:\scripte\tdh.png' -raw  
$targetname = "tdh.png"  
$oc = "https://URL-Zum-Nextcloud.com"  

# upload file
Invoke-RestMethod -Uri "$oc/remote.php/dav/files/$user/$targetname" -Method Put -Body $body -Credential $credential  

$headers = @{
    'OCS-APIRequest '= 'true'  
    Authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${user}:${pass}"))))"  
}

# create share
$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body $body  
# ... and output sharelink
$response.ocs.data.url


By the way, ich würde dir hier dringend raten nicht die echten Credentials des Users im Skript zu verwenden sondern App-Passwörter für diesen generieren und benutzen. Diese kannst du entweder in den Nextcloud-Security-Settings erstellen:

screenshot

Oder du forderst ein App-Passwort direkt automatisiert mit der Powershell an

# first request  to get webview url
$auth = irm "$endpoint/index.php/login/v2" -Method Post  
# start url with default browser
start $auth.login

$login = $null
# start polling credentials while user logs in with his credentials and grants access to his account
while(!$login){
    try{
        $login = irm $auth.poll.endpoint -Method Post -Body @{token=$auth.poll.token}
    }catch{}
    sleep 2
}
# output Username and App Password
$login.loginName
$login.appPassword

Details zu diesem Vorgang findest du hier
https://docs.nextcloud.com/server/latest/developer_manual/client_apis/Lo ...

Grüße Uwe

Frohes Fest 🎄

Danke dir, teste ich gleich am Montag.
Crashzero
Crashzero 27.12.2021 aktualisiert um 14:27:03 Uhr
Goto Top
Moin Colinardo,

ich bekomme beim Ausführen folgende Fehlermeldung :

Zeile 17 :
$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body $body  

Fehlermeldung :
Invoke-RestMethod: C:\scripte\nctest.ps1:17
Line |
  17 |  $response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing …  
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The header name format is invalid.

Die Datei ist allerdings vorhanden nach dem Script.
colinardo
colinardo 27.12.2021 aktualisiert um 15:27:11 Uhr
Goto Top
Da hatte sich ein Leerzeichen am Ende des OCS-Header in den Code geschmuggelt. Ist oben korrigiert.

Grüße Uwe
Crashzero
Crashzero 29.12.2021 aktualisiert um 13:12:24 Uhr
Goto Top
Hmm, ich bekommen nun diese Meldung :

Invoke-RestMethod : Der angegebene Wert besitzt ungültige HTTP-Headerzeichen.
Parametername: name
In Zeile:17 Zeichen:13
+ $response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing ...  
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-RestMethod], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

**Wir reden von diesem Script ?!**


$user = 'Username'  
$pass= 'PasswortUser'  
$credential = (new-Object PSCredential($user,(ConvertTo-SecureString $pass -AsPlainText -Force))) 
$body = get-content 'c:\scripte\tdh.png' -raw  
$targetname = "tdh.png"  
$oc = "https://URL-Zum-Nextcloud.com"  

# upload file
Invoke-RestMethod -Uri "$oc/remote.php/dav/files/$user/$targetname" -Method Put -Body $body -Credential $credential  

$headers = @{
    'OCS-APIRequest '= 'true'  
    Authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${user}:${pass}"))))"  
}

# create share
$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body $body  
# ... and output sharelink
$response.ocs.data.url
colinardo
colinardo 29.12.2021 aktualisiert um 13:20:59 Uhr
Goto Top
Hmm, ich bekommen nun diese Meldung :
Du hast immer noch das Leerzeichen im Header drin (Zeile 23), hatte das oben bereits in meinem Original-Post korrigiert, du hast es aber nicht in den Code übernommen!

Fehlerhafte Version
'OCS-APIRequest '= 'true'  
Korrigierte Version
'OCS-APIRequest' = 'true'  
Du erkennst den Blank am Ende des Header-Names?! face-wink.
Crashzero
Crashzero 29.12.2021 um 13:26:15 Uhr
Goto Top
?Oh, hatte eigentlich Copy&Paste genutzt ....

Bin wohl verwirrt ;)
Crashzero
Crashzero 29.12.2021 aktualisiert um 13:36:19 Uhr
Goto Top
bin am verzweifeln ...

hab nun ...

Invoke-RestMethod : 
 
  failure
  404
  Bitte gib eine Datei oder Ordner-Pfad an
 
 
In Zeile:17 Zeichen:13
+ $response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing ...  
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Hab bei ...

$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body $body  

$response = Invoke-RestMethod -Uri "$oc/ocs/v1.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body $body  

Erhalte dann keine Fehlermeldung allerdings aber auch keine Ausgabe bei :

$response.ocs.data.url
colinardo
colinardo 29.12.2021 aktualisiert um 13:35:53 Uhr
Goto Top
Sorry da hatte ich selbst einen Copy n Paste Fehler von meiner Entwicklungsumgebung drin, der Body ist natürlich falsch beim Erzeugen des Links, ist oben korrigiert.
Crashzero
Crashzero 29.12.2021 um 13:39:33 Uhr
Goto Top
Komme langsam durcheinander , was meinst du mit oben ?

Ist das der korrekte Code :
$user = 'Username'  
$pass= 'PasswortUser'  
$credential = (new-Object PSCredential($user,(ConvertTo-SecureString $pass -AsPlainText -Force))) 
$body = get-content 'c:\scripte\tdh.png' -raw  
$targetname = "tdh.png"  
$oc = "https://URL-Zum-Nextcloud.com"  

# upload file
Invoke-RestMethod -Uri "$oc/remote.php/dav/files/$user/$targetname" -Method Put -Body $body -Credential $credential  

$headers = @{
    'OCS-APIRequest' = 'true'  
    Authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${user}:${pass}"))))"  
}

# create share
$response = Invoke-RestMethod -Uri "$oc/ocs/v2.php/apps/files_sharing/api/v1/shares" -Method Post -Headers $headers -Body @{path="/$targetname";shareType=3}  
# ... and output sharelink
$response.ocs.data.url
Crashzero
Crashzero 29.12.2021 um 13:41:28 Uhr
Goto Top
Sauber colinardo, funktioniert.
Echt klasse, ich danke dir vielmals ......
Crashzero
Crashzero 29.12.2021 um 14:40:25 Uhr
Goto Top
Ein FRage hätte ich da noch, können so auch Verzeichnisse freigegeben werden ?
aqui
aqui 29.12.2021 um 14:55:11 Uhr
Goto Top
Sauber colinardo, funktioniert.
Bitte dann auch nicht vergessen den Thread als gelöst zu schliessen !!
Wie kann ich einen Beitrag als gelöst markieren?
colinardo
colinardo 29.12.2021 aktualisiert um 15:14:21 Uhr
Goto Top
Zitat von @Crashzero:
Sauber colinardo, funktioniert.
Echt klasse, ich danke dir vielmals ......>
Immer gerne.
Ein FRage hätte ich da noch, können so auch Verzeichnisse freigegeben werden ?
Ja klar. Einfach nur den Pfad (path) auf den Ordner statt einer Datei zeigen lassen. Also im Body des Share-Aufrufs den Pfad angeben
@{path="/pfad/zum/ordner";shareType=3}  

Referenz fürs Sharing ist wie immer hier nachzulesen
https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OC ...

Grüße und guten Rutsch
Uwe
Crashzero
Crashzero 29.12.2021 um 15:20:59 Uhr
Goto Top
Klasse,

vielen Dank.
Getestet mit password, permissions und expireDate - Funktioniert tadellos.