我希望有人能幫我解決這個問題。我們想看看哪些計算機有 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
}
}
}
uj5u.com熱心網友回復:
繼續我的評論。. . 照原樣,您會將結果匯出到遠程機器。那是如果它被正確地管道。您當前缺少管道 ( |) 之前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給它。這應該允許它在執行查詢并行,VS串行(一次一個):
$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
一次執行一個查詢并不一定意味著它很糟糕。實際上,您可以更好地控制腳本的流程。
uj5u.com熱心網友回復:
具體回答這個問題:
如何正確匯出 CSV 檔案(使用Export-Csv)?
您可能想閱讀有關PowerShell 管道和PowerShell cmdlet 的資訊。
基本上,cmdlet 是參與 PowerShell 管道語意的單個命令。為流水線中間實作了一個寫得很好的 cmdlet ,這意味著它處理(“流”)從前一個 cmdlet 接收到的每個單獨的專案,并立即將其傳遞給下一個 cmdlet(類似于在裝配線上處理專案的方式)您可以將每個裝配站作為一個 cmdlet 進行比較)。
為了更好地展示這一點,我創建了一個更簡單、完整且可驗證的示例 (MVCE),并替換了您的遠程命令 ( Invoke-Command ...),它只是一個假[pscustomobject]@{ ... }物件。
接著就,隨即;
- 我已經使用
Get-Content而不是Import-Csv為你的例子表明,Computers.csv實際上是一個文本檔案的計算機的哪個串列和不是一個Csv檔案,這將需要(例如Name)標頭,并相應地使用此屬性(如$Computer.Name)。 - 為了加強管道優勢/理解,我還使用了
ForEach-Objectcmdlet而不是通常被認為更快的foreach陳述句,但這里可能不是這種情況,因為對于需要首先將所有內容加載到記憶體中的陳述句,撰寫良好的管道將立即開始處理每個專案(在您的情況下發生在遠程計算機上),同時仍然從檔案中檢索下一個計算機名稱。foreach$Computers
現在,回到問題“我如何正確匯出 CSV 檔案”,您可以更好地理解管道,您可以將其Export-Csv放在 foreach 回圈中:
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-Objectcmdlet 一樣,該Export-Csvcmdlet 在內部具有Begin,Process和Endblocks。在Begin塊中,Export-Csvcmdlet 準備csv帶有標題行等的檔案并覆寫任何現有檔案。在Process塊(為從管道接收的每個專案運行)中,它將每一行(資料記錄)添加到檔案中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/351181.html
