You are not logged in.

Announcement

 Téléchargez la dernière version stable de GLPI      -     Et vous, que pouvez vous faire pour le projet GLPI ? :  Contribuer
 Download last stable version of GLPI                      -     What can you do for GLPI ? :  Contribute

#26 2021-04-14 00:57:11

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Je vais tester ça.
Ce serait super que j'arrive à l'intégrer et que ce soit complet...
Merci pour le feedback !

Offline

#27 2021-04-14 20:23:41

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Pas de quoi j'essaie de trouver tout ce qui pourrait nous aider sad

Et de notre côté, mon collègue Malory qui essaie de me proposer toutes syntaxes qui s'en rapproche tongue

Ex la il fait dans un fichier :

{

    "files": {
        "filename[0]": "c:\\temp1\\clear.png"
    },
    "data": {
        "uploadManifest": "{\"input\": {\"name\": \"Uploaded document\", \"tickets_id\": \"161\", \"_filename\" : [\"clear.png\"]}};type"
    }
}

$json = (Get-Content "C:\temp1\json.txt").replace("c:\\temp1\\clear.png",$FileContent)

Mais  message d'erreur :  Surcharge introuvable pour « GetBytes » et le nombre d'arguments « 1 ».

Offline

#28 2021-04-17 12:25:06

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Hello,

je pêche toujours sad, il n'y aurait pas un développeur de GLPI dans le coin qui pourrait nous aider big_smile big_smile ?

En attendant, je pense déjà que dans ta fonction tu peux changer le content-type par multipart/form-data (Si j'ai bien compris ce bout de code dans /inc/api/apirest.class.php)

 else if (strpos($content_type, "multipart/form-data") !== false) {
         if (count($_FILES) <= 0) {
            // likely uploaded files is too big so $_REQUEST will be empty also.
            // see http://us.php.net/manual/en/ini.core.php#ini.post-max-size
            $this->returnError("The file seems too big", 400,
                               "ERROR_UPLOAD_FILE_TOO_BIG_POST_MAX_SIZE", false);
         }

         // with this content_type, php://input is empty... (see http://php.net/manual/en/wrappers.php.php)
         if (!$uploadManifest = json_decode(stripcslashes($_REQUEST['uploadManifest']))) {
            $this->returnError("JSON payload seems not valid", 400, "ERROR_JSON_PAYLOAD_INVALID",
                               false);
         }
         foreach ($uploadManifest as $field => $value) {
            $parameters[$field] = $value;
         }
         $this->format = "json";

         // move files into _tmp folder
         $parameters['upload_result'] = [];
         $parameters['input']->_filename = [];
         $parameters['input']->_prefix_filename = [];

      } 

Et par ailleurs si on obtient l'erreur ERROR_UPLOAD_FILE_TOO_BIG_POST_MAX_SIZE","The file seems too big ça voudrait dire que c'est la variable contenant le nbr de fichier qui ne passe pas sad genre la

filename= @($FileContent)

Offline

#29 2021-04-17 23:04:18

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Grâce à Mecmav j'ai pu remarquer que sans le boundary ça ne peux pas passer. Du coup je pense que dans ta fonction en plus du multipart/data à remplacer il faudra :

Déclarer le boundary :

$boundary = [System.Guid]::NewGuid().ToString();

Puis dans le invoke :

-ContentType "multipart/form-data; boundary=$boundary"

concernant le reste (et bien je pêche toujours)


Car dans postman, dans le body il faut 2 KEY :

KEY :  uploadManifest
La valeur : {"input":{"name": "Uploading a document","_filename":["test.txt"]}}

KEY : filename
La valeur (bon la on explore le disque pour récupérer le fichier)


Du coup j'ai essayé sans succès :

$File = "C:\Users\Dead-Red\test.txt"
$FileContent = [System.IO.File]::ReadAllBytes("$File ")
$fileEnc = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($FileContent);

$json1=@{}
$json1.uploadManifest= ('{"input":{"name": "Uploading a document","_filename":["test.txt"]}}')

Avec

$file= @{file=(Get-ChildItem $File)}

ou

$file= @{file=($fileEnc)}

ou

$file= @{file=($FileContent)}

ou

$file= @{file=($fileEnc)}

Suite :

$json1.filename=$file

Et aussi avec ces différents body :

$json = $json1

ou

$json = $json1 | ConvertTo-Json

ou

$json = @($json1 | ConvertTo-Json)

Et ces différentes commandes :

Invoke-RestMethod "$AppURL/$($SubItemType)" -Method Post -Headers @{"session-token"=$SessionToken.session_token;  "content-type"="multipart/form-data"; "App-Token" = $AppToken; "Accept"='*/*'} -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) -ContentType "multipart/form-data; boundary=$boundary"
Invoke-RestMethod "$AppURL/$($SubItemType)" -Method Post -Headers @{"session-token"=$SessionToken.session_token;  "content-type"="multipart/form-data"; "App-Token" = $AppToken; "Accept"='*/*'} -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) -ContentType "multipart/form-data; boundary=$boundary"
Invoke-RestMethod "$AppURL/$($SubItemType)" -Method Post -Headers @{"session-token"=$SessionToken.session_token;  "content-type"="multipart/form-data"; "App-Token" = $AppToken; "Accept"='*/*'} -Body ([System.Text.Encoding]::UTF8.GetBytes($json))
Invoke-RestMethod "$AppURL/$($SubItemType)" -Method Post -Headers @{"session-token"=$SessionToken.session_token;  "content-type"="multipart/form-data"; "App-Token" = $AppToken; "Accept"='*/*'} -Body ($json) -ContentType  "multipart/form-data; boundary=$boundary"

Offline

#30 2021-04-17 23:40:42

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Je n'arrive pas à le faire fonctionner, mais le code envoyé par Postman (qui lui envoi bien le fichier sur le glpi) peut être transformé en powershell.

Même si moi ça ne marche pas peut être que ... :

Voici le code :

Add-Type -AssemblyName System.Net.Http

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("App-Token", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
$headers.Add("session-token", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
$headers.Add("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")

$multipartContent = [System.Net.Http.MultipartFormDataContent]::new()
$stringHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$stringHeader.Name = "uploadManifest"
$stringContent = [System.Net.Http.StringContent]::new("{`"input`":{`"name`": `"Uploading a document`",`"_filename`":[`"test.txt`"]}}")
$stringContent.Headers.ContentDisposition = $stringHeader
$multipartContent.Add($stringContent)

$multipartFile = 'C:\Users\Dead-Red\test.txt'
$FileStream = [System.IO.FileStream]::new($multipartFile, [System.IO.FileMode]::Open)
$fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$fileHeader.Name = "filename"
$fileHeader.FileName = ""
$fileContent = [System.Net.Http.StreamContent]::new($FileStream)
$fileContent.Headers.ContentDisposition = $fileHeader
$multipartContent.Add($fileContent)

$body = $multipartContent

$response = Invoke-RestMethod 'XXXXXXX/apirest.php/Document/' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json

$filestream.Close()

Peut être en powershell v7 (si quelqu'un passe par là) ? (je préfère rester en 5.1 pour ma part, afin d'être au plus proche des utilisateurs)

Last edited by Dead-Red (2021-04-20 13:34:32)

Offline

#31 2021-04-19 12:31:01

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Je reçois un vilain "ERROR_BAD_ARRAY" en utilisant le code fourni par PostMan :-(

Offline

#32 2021-04-20 10:23:11

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Pareil.

Et le support de GLPI ne sont pas d'une grande aide.

Hi,

If it works using Postman, then there is no bug on GLPI side.

To get support, you can ask for community support on forum or get a subscription for a professionnal support.

I close this issue as it is not a bug.

Regards

Source : GITHUB/glpi-project/glpi/issues/8967

Alors qu'ils ont bien plus de compétences pour savoir ce qui est erroné dans la donnée attendue. ;(

Offline

#33 2021-04-20 10:52:07

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Je ne suis pas surpris :-)

Offline

#34 2021-04-20 13:29:42

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Ce serait possible d'avoir la config de PostMan, que je puisse reproduire l'upload ici ?

Offline

#35 2021-04-20 13:37:27

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Yes, je vais récup les infos de mecmav (pour permettre le copier-coller) + les screens

Last edited by Dead-Red (2021-04-20 13:37:37)

Offline

#36 2021-04-20 13:50:46

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Alors pour permettre de faire depuis postman :

Perso directement dans le Projet, j'ai créé mes variables avec leur valeur respective :

GLPI_App-Token
GLPI_UserToken
GLPI_AppURL
GLPI_SessionToken

Puis ensuite j'ai créé une requête GET (nomée initSession) qui vient mettre à jour la variable GLPI_SessionToken

La requête GET :

Dans le Headers j'ai :

App-Token =  {{GLPI_App-Token}}
Authorization = user_token {{GLPI_UserToken}}

Puis après dans la rubrique Tests j'ai ajouté :

pm.test('Status code is 200', function () {
    pm.response.to.have.status(200); 
});

var jsonBody = pm.response.json();

pm.collectionVariables.set("GLPI_SessionToken",jsonBody.session_token);

Ce qui fait  qu'avant de commencer à faire d'autres requêtes, je lance celle-ci, elle vient mettre à jour la variable "d'environnement" et j'utilise la variable d'env dans mes autres requêtes.

Donc pour la requête de POST de fichier dans le header :

Il faut faire afficher les headers masqué. Il ne faut que les headers App-Token & session-token à rentrer à la mano (bien que je crois que le APP-TOKEN n'est pas utile)

Postman-01.png

Ensuite dans body :

Postman-02.png

il faut créer la KEY : uploadManifest et saisir le code suivant :

{"input":{"name": "Uploading a document","_filename":["test.txt"]}}

la deuxième KEY il faut remplacer le "format" text par file et allez chercher le fichier.


Merci à MecMav / Thank's you MecMav wink

Last edited by Dead-Red (2021-04-20 13:59:59)

Offline

#37 2021-04-20 14:10:47

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Je vais tester ça. Merci à vous deux smile

Offline

#38 2023-02-01 14:49:36

romVsen
Member
Registered: 2023-01-25
Posts: 13

Re: Powershell module available

Salut!
Puis-je utiliser ce module pour ajouter plusieurs ProjectTask pour un Project donné ?
Merci

Offline

#39 2023-05-03 16:53:26

Jean-Christophe
Moderator
Registered: 2007-08-22
Posts: 734

Re: Powershell module available

Bonjour,

Oui, il n'y a pas de raison :-)

Offline

#40 2023-05-16 11:57:31

bastien
Member
Registered: 2008-09-07
Posts: 30

Re: Powershell module available

Bonsoir,
j'ai eu le même problème d'upload de document via PowerApps et le secret est de convertir le document en base64 voici un exemple qui fonctionne :
{
  "$content-type": "multipart/form-data",
  "$multipart": [
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"uploadManifest\""
      },
      "body": {
        "$content": {
          "input": {
            "name": "test.pdf",
            "_filename": [
              "test.pdf"
            ]
          }
        }
      }
    },
    {
      "body": {
        "$content": "JVBERi0xLjQKJdP0zOE ------ LE DOCUMENT EN BASE 64 ICI ------ OQolJUVPRgo=",
        "$content-type": "application/pdf"
      },
      "headers": {
        "Content-Disposition": "form-data; name=\"file\"; filename=\"test.pdf\""
      }
    }
  ]
}

Offline

#41 2023-05-16 11:59:48

bastien
Member
Registered: 2008-09-07
Posts: 30

Re: Powershell module available

en python cela donnerai ceci :

import requests

url = 'https://domaine.com/apirest.php/Document/'  # Remplacez par l'URL de votre choix

# Définissez le contenu du manifeste
manifest_content = {
    "input": {
        "name": "test.pdf",
        "_filename": [
            "test.pdf"
        ]
    }
}

# Définissez le contenu du fichier
file_content = "JVBERi0xLjQKJdP0zOE ------ LE DOCUMENT EN BASE 64 ICI ------ OQolJUVPRgo="  # Remplacez par le contenu de votre fichier en base64

# Créez les données multipart
multipart_data = {
    'uploadManifest': ('manifest.json', json.dumps(manifest_content), 'application/json'),
    'file': ('test.pdf', base64.b64decode(file_content), 'application/pdf'),
}

response = requests.post(url, files=multipart_data)

# Vérifiez la réponse
if response.status_code == 200:
    print("Le fichier a été téléchargé avec succès.")
else:
    print(f"Erreur lors du téléchargement du fichier: {response.status_code}")

Offline

#42 2023-05-31 17:14:46

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Bonjour Bastien,

merci de ton retour et de ton aide. Mais je n'arrive pas pour autant à faire fonctionner.

Aurais-tu le code powershell complet qui upload un document ?

Merci par avance

Offline

#43 2023-06-01 13:43:16

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Bonjour à tous smile !

J'ai enfin réussi à trouver le code nécessaire pour l'upload de fichier vers GLPI.

J'épure mon fichier de test (qui est très très à vomir), je remet en forme et je publie le code wink

Offline

#44 2023-06-01 15:24:43

Jorje
Member
Registered: 2023-06-01
Posts: 1

Re: Powershell module available

Bonjour à tous,

@Dead-Red ça fait depuis le début de semaine que je m'arrache les cheveux pour uploader des fichiers sur GLPI via l'API, j'ai suivi toutes tes recherches !
J'ai finalement réussi bêtement en exportant le code de Postman dans une session Powershell 7, mais je suis curieux de savoir comment toi tu as réussi (si c'est en version 5)

function Upload-GLPI-File{
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("session-token", "SESSION TOKEN")
$headers.Add("app-token", "APP TOKEN")

$multipartContent = [System.Net.Http.MultipartFormDataContent]::new()
$stringHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$stringHeader.Name = "uploadManifest"
$stringContent = [System.Net.Http.StringContent]::new("{`"input`":{`"_filename`":`"[NOM DU FICHIER]`",`"name`":`"NOM DU FICHIER`"}}")
$stringContent.Headers.ContentDisposition = $stringHeader
$multipartContent.Add($stringContent)

$multipartFile = "CHEMIN DU FICHIER"
$FileStream = [System.IO.FileStream]::new($multipartFile, [System.IO.FileMode]::Open)
$fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$fileHeader.Name = "filename"
$fileHeader.FileName = "CHEMIN DU FICHIER"
$fileContent = [System.Net.Http.StreamContent]::new($FileStream)
$fileContent.Headers.ContentDisposition = $fileHeader
$multipartContent.Add($fileContent)

$body = $multipartContent

$global:glpifileid = Invoke-RestMethod '**URLGLPI**/Document' -Method 'POST' -Headers $headers -Body $body
$filestream.close()

En bonus ci-dessous pour assigner le document au ticket :

function Attach-DocumentToTicket{

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("session-token", "SESSION TOKEN")
$headers.Add("app-token", "APP TOKEN")
$headers.Add("Content-Type", "application/json")

$body = @"
{
   
`"input`":{
       
    `"documents_id`": `"ID DOCUMENT`", 
       
    `"items_id`": `"ID TICKET`", 
       
    `"itemtype`": `"Ticket`"
   
    }

}
"@

Invoke-RestMethod '**GLPI URL**/Document/1/Document_Item/' -Method 'POST' -Headers $headers -Body $body

}

@++

Offline

#45 2023-06-01 16:52:10

Dead-Red
Member
From: France - Aisne - 02
Registered: 2021-04-10
Posts: 20

Re: Powershell module available

Effectivement je voulais absolument que ça fonctionne sur la version 5.1 (d'ailleurs si tu sais tester sur la 7 et me dire big_smile)

Voici le code
(Il faut encore l'épurer et le rendre plus propre mais au moins il marche) :

$AppToken = "XXXXXXXXXXXXXXXXXXXXX"
$session_token = "XXXXXXXXXXXXXXXXXXXXX"

# Chemin du fichier à uploader
$FilePath = "C:\TEMP\GLPI_DOCS\test2.pdf"
$fileName = $FilePath.Split('\')[-1]

# Définition de l'URL de l'API GLPI
$url = "https://URL-GLPI/apirest.php/Document/"  # Remplacez par l'URL de votre choix

# Lecture du contenu du fichier et conversion en base64

$TheFile = [System.IO.File]::ReadAllBytes($FilePath)
$fileContentBase64 = [System.Text.Encoding]::GetEncoding('iso-8859-1').GetString($TheFile)


# Définition du contenu du manifeste
$manifestContent = @{
    "input" = @{
        "name" = $fileName
        "_filename" = @($fileName)
        "entities_id" = 32
    }
} | ConvertTo-Json

# Création des données multipart
$boundary = [System.Guid]::NewGuid().ToString()
$multipartData = @"
--$boundary
Content-Disposition: form-data; name="uploadManifest"

$manifestContent
--$boundary
Content-Disposition: form-data; name="filename[0]"; filename="$fileName"
Content-Type: application/octet-stream

$fileContentBase64
--$boundary--
"@

# Définition des en-têtes de la requête
$headers = @{
    "App-Token" = $AppToken
    "session-token" = $session_token
}

Invoke-RestMethod -Uri $url -Method POST -Headers $headers -ContentType "multipart/form-data; boundary=$boundary" -Body $multipartData

Offline

Board footer

Powered by FluxBB