簡體   English   中英

Powershell - 正確導出 CSV 文件

[英]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

一次執行一個查詢並不一定意味着它很糟糕。 實際上,您可以更好地控制腳本的流程

具體回答這個問題:

如何正確導出 CSV 文件(使用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 在內部具有BeginProcessEnd Begin塊中, Export-Csv cmdlet 准備帶有標題等的csv文件覆蓋任何現有文件。 Process塊(為從管道接收的每個項目運行)中,它將每一行(數據記錄)添加到文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM