Reputation: 105
I am creating a script to get the uptime / last reboot of a group of PCs read in from a text file.
I can output the results to file, but it keeps repeating the column header which I do not want. Basically what I would like is to output the first line for the headers and then each line after for the data the data underneath. The code below repeats the column header to the output file and there are a lot of spaces between the lines. Would an output to CSV be easier to handle?
Here is my code. The first Out-File
command is to overwrite the file if it exists, essentially clearing the file.
$computers = Get-Content "c:\temp\ps\pc.txt"
out-file -FilePath "C:\temp\ps\output.txt"
foreach ($computer in $computers)
{
$Computerobj = "" | select ComputerName, Uptime, LastReboot
$wmi = Get-WmiObject -ComputerName $computer -Query "SELECT LastBootUpTime FROM Win32_OperatingSystem"
$now = Get-Date
$boottime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$uptime = $now - $boottime
$d =$uptime.days
$h =$uptime.hours
$m =$uptime.Minutes
$s = $uptime.Seconds
$Computerobj.ComputerName = $computer
$Computerobj.Uptime = "$d Days $h Hours $m Min $s Sec"
$Computerobj.LastReboot = $boottime
$Computerobj
out-file -FilePath "C:\temp\ps\output.txt" -in $computerobj -append
}
Upvotes: 0
Views: 1169
Reputation: 200493
A pipeline with ForEach-Object
and Export-Csv
would be a better approach:
$now = Get-Date
Get-Content -Path 'C:\temp\ps\pc.txt' | ForEach-Object {
$wmi = Get-WmiObject -ComputerName $_ -Class Win32_OperatingSystem
$boottime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$uptime = $now - $boottime
New-Object -Type PSObject -Property @{
'ComputerName' = $_
'Uptime' = '{0} Days {1} Hours {2} Min {3} Sec' -f $uptime.Days,
$uptime.Hours, $uptime.Minutes, $uptime.Seconds
'LastReboot' = $boottime
}
} | Export-Csv -Path 'C:\temp\ps\output.txt' -NoType
If you need the data both in a file and on the console, you could use ConvertTo-Csv
and Tee-Object
:
Get-Content 'c:\temp\ps\pc.txt' | ForEach-Object {
...
} | ConvertTo-Csv -NoType | Tee-Object -FilePath 'C:\temp\ps\output.txt'
Upvotes: 3
Reputation: 32220
Try this:
$computers = Get-Content "c:\temp\ps\pc.txt"
#Create a report variable as an array to hold all our data
$report = @();
#No longer necessary
#out-file -FilePath "C:\temp\ps\output.txt"
foreach ($computer in $computers)
{
$Computerobj = "" | select ComputerName, Uptime, LastReboot
$wmi = Get-WmiObject -ComputerName $computer -Query "SELECT LastBootUpTime FROM Win32_OperatingSystem"
$now = Get-Date
$boottime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$uptime = $now - $boottime
$d =$uptime.days
$h =$uptime.hours
$m =$uptime.Minutes
$s = $uptime.Seconds
$Computerobj.ComputerName = $computer
$Computerobj.Uptime = "$d Days $h Hours $m Min $s Sec"
$Computerobj.LastReboot = $boottime
#Add the computer to the report array
$report += $Computerobj
}
#Uncomment this if you need to see the report as well as write it to a file
#Write-Output $report
out-file -FilePath "C:\temp\ps\output.txt" -in $report
Now you can manipulate the report as a whole, so you can even add things at the end like $report = $report | Sort-Object -Property ComputerName
to sort the report by computer names, or filter it with Where-Object
.
Upvotes: 0