[英]Powershell - Export CSV file correctly
我希望有人能幫我解決這個問題。 我們想看看哪些計算機有 HDD 和 SDD。 我有一個 excel.csv 的計算機。 我進口電腦。 但是當我導出它們時,我從未看到 csv 或其不完整的。 你能告訴我腳本的哪一部分是不正確的。 謝謝
$computers = Import-csv -path "C:\Temp\MediaType\Computers.csv"
foreach ($computer in $computers) {
Write-Host "`nPulling Physical Drive(s) for $computer"
if((Test-Connection -BufferSize 32 -Count 1 -ComputerName $computer -Quiet)){
Invoke-Command -ComputerName $computer -ScriptBlock {
Get-WmiObject -Class MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage | Select-Object sort -Property PSComputerName, Model, SerialNumber, MediaType
Export-Csv C:\Temp\devices.csv
}
}
}
繼續我的評論。 . . 照原樣,您會將結果導出到遠程機器。 那是如果它被正確地管道。 您當前在Export-Csv
之前缺少管道 ( |
)。
此外,無需調用該命令,因為Get-WMIObject
具有用於遠程計算機的參數: -ComputerName
。 它也是一個已棄用的 cmdlet,已被Get-CimInstance取代。
$ExportTo = "C:\Temp\devices.csv"
$computers = Import-csv -path "C:\Temp\MediaType\Computers.csv"
foreach ($computer in $computers)
{
Write-Host "`nPulling Physical Drive(s) for $computer"
if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $computer -Quiet) {
Get-CimInstance -ClassName MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage -ComputerName $computer |
Select-Object -Property PSComputerName, Model, SerialNumber, MediaType |
Export-Csv -Path $ExportTo -Append -NoTypeInformation
}
}
旁注: Get-CimInstance
接受字符串數組,這意味着你可以整體通過$Computers
給它。 這應該允許它並行執行查詢,而不是串行(一次一個):
$ExportTo = "C:\Temp\devices.csv"
$computers = Import-csv -path "C:\Temp\MediaType\Computers.csv"
Get-CimInstance -ClassName MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage -ComputerName $computers -ErrorAction SilentlyContinue |
Select-Object -Property PSComputerName, Model, SerialNumber, MediaType |
Export-Csv -Path $ExportTo -Append -NoTypeInformation
一次執行一個查詢並不一定意味着它很糟糕。 實際上,您可以更好地控制腳本的流程。
具體回答這個問題:
Export-Csv
)? 您可能想閱讀有關PowerShell 管道和PowerShell cmdlet 的信息。
基本上,cmdlet 是參與 PowerShell 管道語義的單個命令。 為流水線中間實現了一個寫得很好的 cmdlet ,這意味着它處理(“流”)從前一個 cmdlet 接收到的每個單獨的項目,並立即將其傳遞給下一個 cmdlet(類似於在裝配線上處理項目的方式)您可以將每個裝配站作為一個 cmdlet 進行比較)。
為了更好地展示這一點,我創建了一個更簡單、完整且可驗證的示例 (MVCE),並替換了您的遠程命令 ( Invoke-Command ...
),它只是一個假的[pscustomobject]@{ ... }
對象。
接着就,隨即;
Get-Content
ratingr 然后Import-Csv
作為您的示例表明Computers.csv
實際上是一個文本文件,其中包含計算機列表,而不是一個需要(例如Name
)標頭和相應使用此屬性的Csv
文件(例如Computer.Name
.名稱)。ForEach-Object
cmdlet而不是foreach
語句,后者 [通常更快] 考慮更快,但這里可能不是這種情況,因為foreach
語句需要加載所有$Computers
到內存中,編寫良好的管道將立即開始(遠程)處理第一台計算機。現在,回到問題“我如何正確導出 CSV 文件”,可以更好地理解管道,您可以將它放在這里:
Get-Content .\Computers.txt |ForEach-Object {
[pscustomobject]@{
PSComputerName = $_
Model = "Model"
SerialNumber = '{0:000000}' -f (Get-Random 999999)
MediaType = "MydiaType"
} |Export-Csv .\Devices.csv -Append
}
正如@lit所評論的那樣,這將需要-Append
開關,這可能是不需要的,因為每次重新運行腳本時,這會將結果附加到.\\Devices.csv
文件。
相反,您可能實際上想要這樣做:
Get-Content .\Computers.txt |ForEach-Object {
[pscustomobject]@{
PSComputerName = $_
Model = "Model"
SerialNumber = '{0:000000}' -f (Get-Random 999999)
MediaType = "MydiaType"
}
} |Export-Csv .\Devices.csv
請注意不同之處: Export-Csv
被放置在循環之外並且-Append
開關被移除。
解釋
與例如ForEach-Object
cmdlet 一樣, Export-Csv
cmdlet 在內部具有Begin
、 Process
和End
塊。 在Begin
塊中, Export-Csv
cmdlet 准備帶有標題等的csv
文件並覆蓋任何現有文件。 在Process
塊(為從管道接收的每個項目運行)中,它將每一行(數據記錄)添加到文件中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.