Ajouter Powershell sortie vers un fichier Excel
Je suis en train d'écrire un script powershell qui permettra de recueillir des informations à partir de disques Durs externes, je suis à l'archivage au travail (connecté via un disque dur USB dock), et je voudrais avoir le script ajouter cette info dans un fichier Excel en tant que l'une des dernières étapes. Je suis un peu familier avec Powershell, mais pas tellement sur le travail avec des fichiers Excel avec Powershell.
En gros, le script doit être en mesure de déterminer la première ligne vide de la feuille, puis coller des informations dans les colonnes A, B, C, etc de cette ligne. J'ai trouvé un couple de façons différentes de le faire, mais pour une raison quelconque la variable contenant le numéro de ligne pour ajouter des informations à semble toujours être vide. Je ne suis pas sûr si je fais quelque chose de mal, donc, tous les conseils seront très appréciés.
C'est un peu long, mais voici mon script dans son état actuel. Le bas 2 sections (portant la mention "Ajouter des informations dans un document excel...") sont les exemples de script que j'ai trouvé (et liens) qui soi-disant est ce que je suis en train de faire.
Merci d'avance pour l'aide.
cls ($null = reg.exe décharger HKLM\EXTERNES) 2> $null #IF ($AdminCred -eq $null) {New-Variable-Name AdminCred -Valeur (Get-Credential -nom d'utilisateur de l'Administrateur -Message "Entrez le mot de passe pour le compte admin") -Portée Mondiale -Force} $null = reg.exe charge HKLM\ " EXTERNAL D:\Windows\System32\Config\SYSTEMsi ($LASTEXITCODE -eq 0) { #Trouver le nom d'hôte New-Variable -Nom Nom d'hôte -Value ((Get-ItemProperty -Path HKLM:\EXTERNAL\ControlSet001\Control\ComputerName\ComputerName).ComputerName) -Portée Global -Force [GC]::Collecter() SI ($LASTEXITCODE -ne 0) {Write-Accueil LastExitCode est $LASTEXITCODE} $null = reg.exe décharger HKLM\EXTERNES
#Find the serial number Clear-Variable -Name SerialNumber -Scope Global -Force New-Variable -Name SerialNumber -Value (Read-Host "Please enter the HDD's serial number.") -Scope Global -Force # I was originally trying to programatically gather the serial number of the HDD, but that is an issue for another post. # $Disks = Get-WMIObject -class win32_PhysicalMedia # $SerialNumber = foreach($Disk in $Disks) {IF ($Disk.SerialNumber -ne ' WD-WCC2EAV91692') {Write-Host $Disk.SerialNumber}} #Find usernames $Win7 = Test-Path D:\Users $WinXP = Test-Path 'D:\Documents and Settings' IF ($Win7 -eq 'True') {$Win7Users = (Get-ItemProperty -Path D:\Users\* -Exclude ADMINI~1,Administrator,Public,TEMP,UpdatusUser,'All Users',User).name} IF ($WinXP -eq 'True') {$WinXPUsers = (Get-ItemProperty -Path 'D:\Documents and Settings\*' -Exclude ADMINI~1,Administrator,Public,TEMP,UpdatusUser,'All Users',User).name} #Display Hostname and Usernames Write-Host Hostname: -ForegroundColor Green $hostname Write-Host Write-Host Serial Number: -ForegroundColor Green $SerialNumber Write-Host Write-Host User List: -ForegroundColor Green $Win7Users $WinXPUsers #Print the output Out-File -FilePath C:\HDDinfo.txt -InputObject (New-Object -TypeName String -ArgumentList "Hostname:") Out-File -FilePath C:\HDDinfo.txt -InputObject $Hostname -Append Add-Content -Path C:\HDDinfo.txt `n Out-File -FilePath C:\HDDinfo.txt -InputObject (New-Object -TypeName String -ArgumentList "Serial Number:") -Append Out-File -FilePath C:\HDDinfo.txt -InputObject $SerialNumber -Append Add-Content -Path C:\HDDinfo.txt `n Out-File -FilePath C:\HDDinfo.txt -InputObject (New-Object -TypeName String -ArgumentList "User List:") -Append Out-File -FilePath C:\HDDinfo.txt -InputObject $Win7Users -Append Out-File -FilePath C:\HDDinfo.txt -InputObject $WinXPUsers -Append Out-Printer \\servername\printername -InputObject (Get-Content C:\HDDinfo.txt) #Append the info to an Excel document - Possible method 1 # http://stackoverflow.com/questions/8452408/using-powershell-to-append-a-table-to-the-end-of-an-excel-file-the-last-row $ExcelPath = "C:\HDDInfo.xlsx" $xldown = -4121 # see: http://msdn.microsoft.com/en-us/library/bb241212(v=office.12).aspx $xlup = -4162 $Excel = New-Object -ComObject Excel.Application $Excel.Visible = $False $ExcelWorkBook = $Excel.Workbooks.Open($ExcelPath) $ExcelWorkSheet = $Excel.WorkSheets.item("Sheet1") $ExcelWorkSheet.activate() # Find the last used cell {$lastRow = $ExcelWorkSheet.Cells.Range("A1048576").End($xlup).row $nextRow = $lastRow + 1 $range = $ExcelWorkSheet.Range("A$nextRow") $ExcelWorkSheet.Paste($range)} # Append info to the spreadsheet $ExcelWorkSheet.Cells.Item($row,1) = 'COLUMN 1 Text' $ExcelWorkSheet.Cells.Item($row,2) = 'COLUMN 2 Text' $ExcelWorkSheet.Cells.Item($row,3) = 'COLUMN 3 Text' $ExcelWorkSheet.Cells.Item($row,4) = 'COLUMN 4 Text' $ExcelWorkSheet.Cells.Item($row,5) = 'COLUMN 5 Text' # Save and close $ExcelWorkBook.Save() $ExcelWorkBook.Close() $Excel.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel) Stop-Process -Name EXCEL -Force #Append the info to an Excel document - Possible method 2 # http://www.adamtheautomator.com/powershell-excel-worksheet/ $excel_file_path = 'C:\HDDInfo.xlsx' # Instantiate the COM object $Excel = New-Object -ComObject Excel.Application $ExcelWorkBook = $Excel.Workbooks.Open($excel_file_path) $ExcelWorkSheet = $Excel.WorkSheets.item("sheet1") $ExcelWorkSheet.activate() # Find the first row where the first 7 columns are empty $row = ($ExcelWorkSheet.UsedRange.Rows | Where-Object { ($_.Value2 | Where-Object {$_ -eq $null}).Count -eq 7 } | select -first 1).Row $ExcelWorkSheet.Cells.Item($row,1) = 'COLUMN 1 Text' $ExcelWorkSheet.Cells.Item($row,2) = 'COLUMN 2 Text' $ExcelWorkSheet.Cells.Item($row,3) = 'COLUMN 3 Text' $ExcelWorkSheet.Cells.Item($row,4) = 'COLUMN 4 Text' $ExcelWorkSheet.Cells.Item($row,5) = 'COLUMN 5 Text' # Save and close $ExcelWorkBook.Save() $ExcelWorkBook.Close() $Excel.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel) Stop-Process -Name EXCEL -Force }
- Avez-vous besoin pour utiliser le fichier Excel ComObject? Pouvez-vous utiliser le
Export-Csv
applet de commande? CSV fichier peut être ouvert par Excel. - D'accord avec romellem. Je ne vois rien ici qui nécessite vraiment l'objet com. Juste de champ de base de remplissage. À l'aide d'objets
Export-CSV
serait ce une tonne plus facile. - Eh bien, je préfère avoir le fichier en tant que .xslx format, comme d'autres personnes que moi (et d'autres à l'extérieur) sont plus enclins à ouvrir le fichier. J'ai pu exporter vers un fichier csv, mais je vais tout de même besoin d'avoir le fichier xlsx, donc j'aurais besoin de transférer manuellement les données périodiquement. Il serait faire le travail, mais je voudrais éviter un effort manuel supplémentaire si possible.
Vous devez vous connecter pour publier un commentaire.
Ok, CSV est ok, mais lors de la présentation des données, ou le partage avec les autres, c'est juste pas assez, donc je suis totalement d'obtenir de vouloir vider les données vers Excel. Pour ajouter des données dans une feuille Excel, je vous suggère fortement d'avoir un tableau d'objets pour commencer, et ensuite, à l'aide de la
ConvertTo-CSV
applet de commande,Clip
, et les coller dans Excel.Vous n'avez pas vraiment l'état de ce que vous voulez coller dans Excel, mais je vais supposer nom d'hôte, numéro de Série, et les utilisateurs. Depuis la liste des utilisateurs est un tableau, je vais le rejoindre dans une chaîne afin qu'Excel n'est pas paniquer à ce sujet, et coller une tonne de lignes vides.
Donc, nous allons obtenir cette information dans un objet. Il ya quelques façons de le faire, mais celui que je préfère (devrait fonctionner sur PS v3 et plus) est de le lancer en tant que tel:
Maintenant, si nous la pipe que pour
ConvertTo-Csv
et de le rendre délimités par des tabulations avec le-NoTypeInformation
interrupteur il sort quelque chose comme ceci:Maintenant, si vous ne voulez pas la ligne d'en-tête collée dans votre fichier Excel à chaque fois que nous la pipe que pour
Select -Skip 1
et qui permet de résoudre cela. Mais pour l'instant nous allons l'inclure. Voici le code que je voudrais utiliser pour obtenir cette information dans Excel.Maintenant, vous pourriez avoir à changer l'objet personnalisé, mais qui ne devrait faire ce que vous voulez. Si votre script processus de plus d'un élément à la fois, vous pouvez faire un tableau d'objets, et de les coller dans Excel à la fois de cette façon.
Edit: Ok, là où d'ignorer l'en-tête et coller des noms dans leurs propres cellules...
Comme je l'ai dit, vous pipe:
en
|Select -Skip 1
. Cela pourrait être source de confusion, je suppose, parce que je courante dans| Clip
, mais si vous considérez la façon dont le pipeline fonctionne, et comment chaque pipe prend la sortie du segment précédent, alors vous pipeConvertTo-CSV
enSelect -Skip 1
de sorte qu'il ignore la première ligne (qui est l'endroit où les en-têtes), puis la pipe àClip
de copier le résultat dans le presse-papiers... Il fait sens quand vous le briser. La commande devrait ressembler à ceci:Maintenant, pour le collage de chaque utilisateur dans leur propre cellule, vous devez être plus précis. Voulez-vous durée de cellules horizontalement ou verticalement? Si vous voulez étendre horizontalement puis les choses se compliquent. Fondamentalement, ce que nous aimerions faire est de créer l'objet, puis utilisez
Add-Member
pour ajouter des propriétés à l'objet, pour chacun des utilisateurs.Qui permettrait de créer une entrée de type ce (en-têtes de gauche pour référence, ils n'apparaissent pas dans Excel):
Si vous voulez la liste de chaque utilisateur à la verticale, vous pourriez faire quelque chose comme la réalisation d'un objet pour chaque utilisateur, mais seulement, y compris l'Hôte et S/N sur la première.
Cela donnerait quelque chose comme ceci (en-têtes de gauche pour référence, ils n'apparaissent pas dans Excel):
Select -Skip 1
afin de coller les données uniquement et pas d'en-tête? J'ai essayé quelques endroits, mais il ne semble pas fonctionner. Aussi, est-il un moyen pour elle de coller chaque nom dans une cellule? Je ne suis pas sûr de ce qui serait plus efficace, mais il est actuellement le collage de l'ensemble de la liste des noms dans une seule cellule.