Question
Export vers XLS
- bordin
- Auteur du sujet
- Hors Ligne
- Membre premium
-
- Messages : 88
- Remerciements reçus 0
Ok, je comprends: ce que tu veux, c'est exporter en CSV une version modifiée des données, c'est-à-dire avec des noms de champs personnalisés et des valeurs calculées à la volée, bref tout ce qu'on peut faire avec format-table.
Sauf que format-table émet des objets de type FormatEntryData et que ces objets ne contiennent plus les données d'origine, ou alors sous une forme qui ne se prête pas facilement à l'exportation. Le but de toute commandelette format-* est de produire un résultat final valable pour un affichage, pas pour un traitement ultérieur.
La solution s'appelle select-object (ou select de son petit nom). Select permet d'extraire une partie des objets qu'on lui passe et de faire certaines manipulations avec. Entre autres, on peut modifier la présentation des propriétés d'une façon très proche de celle qu'on connaît avec format-table:
[code:1]PS> gwmi win32_logicaldisk |
>> select @{n=\"Nom\";e={$_.__Server}},
>> @{n=\"Volume\";e={$_.DevideID}},
>> @{n=\"Total (Mo)\";e={[math]::round($_.Size/1MB )}},
>> @{n=\"Libre (Mo)\";e={[math]::round($_.FreeSpace/1MB )}}
>>[/code:1]
Dans cet exemple, les deux principales différences avec format-table sont:
- le remplacement de l=\"nom\" par n=\"nom\". Dans format-table, \"l\" est un raccourci pour \"label\", ici le \"n\" est un raccourci pour \"name\".
- la suppression de -a à la fin. Select n'est pas fait pour formatter mais pour présenter les données, donc la notion de formattage \"auto\" n'a pas de sens.
Le résultat de la commande ci-dessus devrait être très proche de ce que tu obtiens avec format-table. La grosse différence, c'est que ce résultat-là est exportable dans un fichier CSV:
[code:1]PS> gwmi win32_logicaldisk |
>> select @{n=\"Nom\";e={$_.__Server}},
>> @{n=\"Volume\";e={$_.DevideID}},
>> @{n=\"Total (Mo)\";e={[math]::round($_.Size/1MB )}},
>> @{n=\"Libre (Mo)\";e={[math]::round($_.FreeSpace/1MB )}} |
>> export-csv LogicalDisks.csv -notype
>>[/code:1]Est-ce que c'est bien ce que tu cherches à faire?
Janel
Bonjour Janel,
C'est exactement çà! Oufff!
J'avais essayer avec select-object, mais sans résultat.
O Janel !!! (pour les connaisseurs signifie Grand Janel)
Arnaud: je veux bien connaitre la manip pour word, un jour çà servira j'en suis sur!
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
- Messages : 576
- Remerciements reçus 0
Voici un petit exemple de pilotage de Word à partir de PowerShell:
[code:1]
$word = new-object -com word.application
$word.visible = $true
$doc = $word.documents.add()
$doc.content.text = get-process | out-string
$doc.content.font.name = \"Courier New\"
$doc.content.font.size = 10
$doc.saveas([ref]\"c:\mesdocs\mes process.doc\"«»)[/code:1]Toute la doc sur le sujet est ici:
msdn2.microsoft.com/fr-fr/library/micros...rop.word(VS.80).aspx
Janel
Connexion ou Créer un compte pour participer à la conversation.
- bordin
- Auteur du sujet
- Hors Ligne
- Membre premium
-
- Messages : 88
- Remerciements reçus 0
Je profite encore pour une petit pb que je n'arrive pas à solutionner qui me fait tourner en bourique.
Dans le code suivant tout fonctionne jusqu'à qu'au moment ou je rajoute le pipe pour l'export!!!!
[code:1]param ($file)
$SortieCheckServices=\"c:\Check-Services.txt\"
$array=@{}
get-content $file | foreach {
$server, $array.$server = $_.split(\",\"«») | foreach {$_.trim()}
}
foreach ($elsrv in $array.keys) {
foreach ( $elsvc in $array.$elsrv){get-wmiobject win32_service -computer $elsrv | where {$_.name -eq $elsvc} | select @{n=\"Nom Serveur\";e={$_.__Server}},@{n=\"Nom
Service\";e={$_.displayname}},@{n=\"Etat\";e={$_.State}},@{n=\"Status\";e={$_.status}}}} | export-csv $SortieCheckServices -notype -force[/code:1]
Erreur de frappe ou grosse erreur de code?
Merci<br><br>Message édité par: Arnaud, à: 2/08/07 17:45
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
- Messages : 576
- Remerciements reçus 0
En tâtonnant un peu j'ai pu trouver une façon de s'en sortir. En fait deux, mais une seule permet de travailler comme tu le souhaites:
1. Retirer l'export-csv du script et le faire à partir de la ligne de commande:
[code:1]PS> check-services | export-csv c:\check-services.txt -notype -force[/code:1]
Solution pas très viable, mais au moins ça marche...
2. Modifier la structure foreach utilisée:
[code:1]
param ($file)
$SortieCheckServices=\"c:\Check-Services.txt\"
$array=@{}
get-content $file | foreach {
$server, $array.$server = $_.split(\",\"«») | foreach {$_.trim()}
}
$array.keys | foreach {
$elsrv = $_
$array.$elsrv | foreach {
$elsvc = $_
get-wmiobject win32_service -computer $elsrv | where {$_.name -eq $elsvc} |
select @{n=\"Nom Serveur\";e={$_.__Server}},
@{n=\"Nom Service\";e={$_.displayname}},
@{n=\"Etat\";e={$_.State}},
@{n=\"Status\";e={$_.status}}
}
} | export-csv $SortieCheckServices -notype -force[/code:1]
Dans ce cas, ça marche comme tu le souhaites. Du moins dans mes tests à moi, à confirmer
Le problème semble donc venir de l'usage de la structure foreach ($item in $collection) {...}. Cette structure fonctionne de manière autonome, en circuit fermé. Les objets qu'elle émet ne sont pas directement récupérables dans un pipe en sortie de la boucle.
A l'inverse, la structure $collection | foreach {...} permet de passer ses résultats à une autre série d'instructions, en l'occurrence export-csv.
Ce n'est pas super satisfaisant, car comment se fait-il qu'avec la première formule on peut exporter le résultat du script et ne pas le faire dans le corps directement?... Je creuserai le sujet, comme je le disais au début, ce problème est intéressant...
A propos de get-wmiobject, tu aurais intérêt pour des raisons de performance, à construire ta requête ainsi:
[code:1]gwmi -query (\"select * from win32_service where Name = '\"+$elsvc+\"'\"«») -comp $elsrv[/code:1]
Cette requête s'exécute entièrement sur le serveur distant et ne retourne que le service souhaité, alors que ta requête retourne tous les services du serveur distant et fait ensuite le filtrage pour le service souhaité.
Janel
Connexion ou Créer un compte pour participer à la conversation.
- bordin
- Auteur du sujet
- Hors Ligne
- Membre premium
-
- Messages : 88
- Remerciements reçus 0
Merci Janel! Ca marche aussi pour moi.
Par contre après l'export du .txt vers excel, j'aimerai l'enregistrer en .xls
$var=$nomfichiertxt.split(\".\")
$nomfichierxls=$var[0]+\".xls\"
$csv = $excel.workbooks.opentext($nomfichiertxt, $missing, $StartRow, $xlDelimited, $xlTextQualifierNone, $missing, $missing, $missing, $true, $missing, $missing, $missing, $missing, $missing,
$missing, $missing, $missing, $missing)
$ClasseurControlExploit = $excel.activeWorkbook
$ClasseurControlExploit.SaveAs($nomfichierxls)
$excel.Quit()
le fichier est bien enregistré mais il me demande à chaque fois de confirmer les modifications?
Au final c'est d'ouvrir tous les doc dans un seul classeur xls.
Aurais tu une astuce?
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
- Messages : 576
- Remerciements reçus 0
Pour bien faire, il faudrait donc utiliser $classeur.SaveAs(...) mais là il faut passer 12 paramètres, et j'ai fait un essai rapide qui n'a pas abouti.
Une autre solution qui, je te rassure tout de suite, marche très bien, consiste à dire à Excel que le classeur a bien été sauvegardé. On peut le faire en mettant sa propriété Saved à $true. On peut ensuite fermer Excel sans qu'il demande d'enregistrer le fichier.
[code:1]
$classeur.saved = $true
$excel.quit()[/code:1]
Sinon, une petite astuce à propos du renommage du fichier de mon.fichier.txt en mon.fichier.xls : tel que tu l'as fait, ça marchera nickel sauf si le fichier a un point dans son nom (comme dans mon exemple). En effet, ton split(\".\") suivi de $var[0] récupère la première partie du nom, donc uniquement \"mon\" dans mon exemple.
Deux techniques de remplacement qui, elles, devraient marcher à tous les coups
[code:1]# \"à la mimine\", utilisation de l'opérateur -replace avec une expression régulière:
$nomfichierxls = \"$($nomfichiertxt -replace '\.txt$').xls\"
# utilisation de la classe .NET idoine:
$nomfichierxls = [System.IO.Path]::ChangeExtension($nomfichiertxt, \".xls\"«»)[/code:1]
Bon week-end,
Janel
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Export vers XLS