Nov 15 2018 04:02 AM
(I'm new to PowerShell and my understanding is limited so I would appreciate a brief explanation as well as a solution if possible)
I've got the following code running successfully to query a list of computers and return various data about them in a table. However, the data from the various commands run against a particular computer is not appearing on the same row. Can anyone suggest a way to combine the results for one machine onto a single table row?
$hostnames = Get-Content "allpcs.txt"
$output = foreach ($hostname in $hostnames) {
if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {
Invoke-Command -ComputerName $hostname -ScriptBlock {
Get-WmiObject Win32_ComputerSystem | Select-Object -ExcludeProperty name;
(Get-ItemProperty -Path "c:\windows\system32\hal.dll").VersionInfo.FileVersion;
(Get-ItemProperty -Path "C:\Program Files (x86)\Microsoft Office\root\Office16\ONENOTE.EXE").VersionInfo.FileVersion;
gcim Win32_OperatingSystem | select InstallDate,LastBootupTime;
Get-PSDrive C | select Free;
}
}
else {
write-host $hostname "not connected"
}
}
$output | Format-Table Name,OSver,O365ver,InstallDate,LastBootupTime,Free | Out-File -filepath allpcs.csv -Append
Example output:
Name OSver O365ver InstallDate LastBootupTime Free
---- ----- ------- ----------- -------------- ----
comp1
10.0.16299.371 (WinBuild.160101.0800)
16.0.8431.2110
05/10/2018 16:18:59 14/11/2018 09:48:33
40862683136
comp2
10.0.16299.371 (WinBuild.160101.0800)
16.0.9126.2259
13/08/2018 15:49:28 09/11/2018 07:46:41
436695408640
Dec 20 2018 07:55 AM - edited Dec 21 2018 03:50 AM
Sorry, I didn't have a chance to thoroughly test this yet.
What you want is a PowerShell custom object to format the data the way you want. See below.
You may find this reference useful: A PowerShell Object Lesson: Part 3
---------------------------------------------------------------------------------------------------
$hostnames = Get-Content "allpcs.txt"
# create a custom PowerShell object to store specific information
$ComputerInfoObj = [PSCustomObject]@{
Name = ""
OSVer = ""
O365ver = ""
InstallDate = ""
LastBootUpTime = ""
Free = ""
}
$output = foreach ($hostname in $hostnames) {
if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {
Invoke-Command -ComputerName $hostname -ScriptBlock {
$ComputerInfoObj.Name = (Get-WmiObject Win32_ComputerSystem).Name
$ComputerInfoObj.OSVer = (Get-ItemProperty -Path "c:\windows\system32\hal.dll").VersionInfo.FileVersion
$ComputerInfoObj.O365ver = (Get-ItemProperty -Path "C:\Program Files (x86)\Microsoft Office\Office16\ONENOTE.EXE").VersionInfo.FileVersion
$ComputerInfoobj.Free = "$([int64]((Get-PSDrive C).Free / 1GB)) GB"
$ComputerInfoObj.InstallDate = (Get-CimInstance Win32_OperatingSystem).InstallDate
$ComputerInfoObj.LastBootUpTime = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
}
}
else {
write-host $hostname "not connected"
}
}
Write-OutPut $ComputerInfoObj | Format-Table
Write-Output $ComputerInfoObj | ConvertTo-Csv | Out-File allpcs.csv -Append
Jan 23 2019 04:14 AM
Thank you, @Darrick the A PowerShell Object Lesson: Part 3 article was helpful.
I managed to tweak the code slightly to get my table by putting each new object into an array. That array could then be presented as a table (and exported to csv).
Here is the final, working script:
$hostnames = Get-Content 'allpcs.txt'
$allpcs = @()
foreach ($hostname in $hostnames) {
if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {
$OS = Get-WmiObject -Class Win32_OperatingSystem -Computer $hostname
$pcinfo = [PSCustomObject]@{
Name = $OS.PSComputerName
OSVer = (Get-ItemProperty -Path '\\$hostname\c$\windows\system32\hal.dll').VersionInfo.FileVersion
O365ver = (Get-ItemProperty -Path '\\$hostname\c$\Program Files (x86)\Microsoft Office\root\Office16\ONENOTE.EXE').VersionInfo.FileVersion;
Free = Invoke-Command -ComputerName $hostname {[math]::Round((Get-PSDrive -Name C | Select-Object -ExpandProperty Free)/1GB,2)}
InstallDate = $OS.ConvertToDateTime($OS.Installdate)
LastBootUpTime = $OS.ConvertToDateTime($OS.LastBootUpTime)
}
$allpcs += $pcinfo
}
else {
write-host $hostname "not connected"
}
}
Write-Output $allpcs | Format-Table
Write-Output $allpcs | ConvertTo-Csv | Out-File -filepath 'allpcs.csv'