Not able to format output as CSV [duplicate] - powershell

This question already has an answer here:
Get WMI Data From Multiple Computers and Export to CSV
(1 answer)
Closed 3 years ago.
Am not able to convert PS output to CSV format using echo function. I need to collect hardware information about multiple servers and got this script from internet. I modified it to collect only the necessary information such as Computername,HDD space, CPU details and RAM.
Below is my code:
$ArrComputers = "PC17"
Clear-Host
foreach ($Computer in $ArrComputers) {
$computerSystemRam = Get-WmiObject Win32_ComputerSystem -Computer $Computer |
select #{n="Ram";e={[math]::Round($_.TotalPhysicalMemory/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerCPU = Get-WmiObject Win32_Processor -Computer $Computer |
select Name |
FT -HideTableHeaders
$computerCPUCores = Get-WmiObject Win32_Processor -Computer $Computer |
select NumberOfLogicalProcessors |
FT -HideTableHeaders -AutoSize
$computerC = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'C:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerD = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'D:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerE = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'E:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
echo $computer,$computerC,$computerD,$computerE,$computerSystemRam,$computerCPU,$computerCPUCores
}
and my output is coming as
PC17
99.9
12
537.11
15.98
Intel(R) Xeon(R) CPU E5-2630 0 # 2.30GHz
12
What I need is to get this outputs as a comma separated value like below
PC17,99.9,12,537.11,15.98,Intel(R) Xeon(R) CPU E5-2630 0 # 2.30GHz,12
so that I can open it in Excel. Please let me know what the problem here is? Or any other alternative solution to so as to get the output as .csv.

Remove the Format-Table, use ExpandProperty and choose the right property from the array,
Also, I used -f to format the csv, see the differences:
foreach ($Computer in $ArrComputers)
{
$computerSystemRam = get-wmiobject Win32_ComputerSystem -Computer $Computer | select #{n="Ram";e={[math]::Round($_.TotalPhysicalMemory/1GB,2)}}
$computerCPU = get-wmiobject Win32_Processor -Computer $Computer | select -ExpandProperty Name
$computerCPUCores = get-wmiobject Win32_Processor -Computer $Computer | select -ExpandProperty NumberOfLogicalProcessors
$computerC = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'C:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
$computerD = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'D:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
$computerE = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'E:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
"{0},{1},{2},{3},{4},{5},{6}" -f $computer,$computerC.Size,$computerD.Size,$computerE.Size,$computerSystemRam.Ram,$computerCPU,$computerCPUCores
}

Related

Format output in Powershell

I have a small code in my script that is working well. I'm just annoyed with the output..
My output looks like this:
11.11.111.123
Model
-----
HP ZBook Studio G5
csname : XXXXXXX
LastBootUpTime : 22/Apr/2022 08:10:57
But I want it like this:
IP Address: 11.11.111.123
Model: HP ZBook Studio G5
csname: xxxxx
LastBootUpTime: 22/Apr/2022 08:10:57
This is the script:
Get-WmiObject Win32_NetworkAdapterConfiguration -Computername $pcName |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -like '10.11*' -or $_ -like '10.12*'}
Get-WmiObject -Class Win32_ComputerSystem -Computername $pcName | Select Model
Get-WmiObject win32_operatingsystem -Computername $pcName -ea stop | select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}} | format-list
Since the output is produced by 3 different classes the way around it is create a new object to merge them:
$IPs = Get-CimInstance Win32_NetworkAdapterConfiguration -ComputerName $pcName |
Where-Object { $_.IPAddress -like '10.11*' -or $_.IPAddress -like '10.12*' }
$Model = (Get-CimInstance -Class Win32_ComputerSystem -ComputerName $pcName).Model
$OS = Get-CimInstance win32_operatingsystem -EA Stop -ComputerName $pcName
[pscustomobject]#{
'IP Address' = $IPs.IpAddress -join ', '
Model = $Model
csname = $OS.CSName
LastBootUpTime = $OS.LastBootUpTime.ToString()
}

Formatting multiple result sets together in powershell

Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt") | SELECT-Object PSComputerName, #{Name="Memory (RAM in GB)";Expression={[Math]::Round($_.TotalVisibleMemorySize/1024/1024)}} | Format-Table
Get-WmiObject -Class Win32_logicaldisk -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DriveType, DeviceID, VolumeName, #{Name="Size";Expression={[math]::ceiling($_.Size /1GB)}} , #{Name="FreeSpace";Expression={[math]::ceiling($_.FreeSpace /1GB)}}, Compressed | where DriveType -eq 3 | Format-Table
Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt")| Select-Object PSComputerName, BuildNumber, BuildType, Caption, CodeSet, OSArchitecture, SystemDrive, TotalVisibleMemorySize, Version | Format-Table
Get-WmiObject -Class win32_product -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object Name, Version, Vendor, InstallDate | Format-Table
Get-WmiObject -Class Win32_Service -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DisplayName, StartName, PathName, StartMode| where DisplayName -Like "*xyz*" |Format-Table
I have till now managed to piece together the above to get the information I need from serveral servers, however now I want to format it so that I can collate information for each server in a format that I can display
for eg.
Server : ABC
RAM : 64 GB
Number of Processors : 8
Disk :
Table of disk Sizes Etc
Any pointers would be appreciated
With all these properties, you would get a nested object array, which probably is easiest to view in JSON format.
I have changed all Get-WmiObject into the newer and faster Get-CimInstance cmdlets below
$result = Get-Content "C:\Temp\Servers.txt" | ForEach-Object {
# create an ordered hashtable to store the results for each server
$pcinfo = [ordered]#{}
# System info
$data = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $_
$pcinfo['Computer'] = $data.PSComputerName
$pcinfo['Memory (RAM in GB)'] = '{0:N2}' -f ($data.TotalPhysicalMemory / 1GB)
# OS info
$data = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $_
$pcinfo['BuildNumber'] = $data.BuildNumber
$pcinfo['BuildType'] = $data.BuildType
$pcinfo['Caption'] = $data.Caption
$pcinfo['CodeSet'] = $data.CodeSet
$pcinfo['OSArchitecture'] = $data.OSArchitecture
$pcinfo['SystemDrive'] = $data.SystemDrive
$pcinfo['TotalVisibleMemorySize'] = $data.TotalVisibleMemorySize
$pcinfo['Version'] = $data.Version
# Product info (array of objects)
$pcinfo['Products'] = Get-CimInstance -ClassName Win32_Product -ComputerName $_ |
Select-Object Name, Version, Vendor, InstallDate
# Local fixed disk info (array of objects)
$pcinfo['FixedDrives'] = Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $_ -Filter 'DriveType=3' |
Sort-Object DeviceID |
Select-Object DriveType, DeviceID, VolumeName,
#{Name="Size";Expression={"{0:N2} GB" -f ($_.Size / 1GB)}},
#{Name="FreeSpace";Expression={"{0:N2} GB" -f ($_.FreeSpace / 1GB)}},
Compressed
# Services info (array of objects)
$pcinfo['Services'] = Get-CimInstance -ClassName Win32_Service -ComputerName $_ |
Where-Object { $_.DisplayName -like '*Adobe*' } |
Select-Object DisplayName, StartName, PathName, StartMode
# convert the hashtable to PSObject and output
[PsCustomObject]$pcinfo
}
# output the whole structure as JSON for easier reading and optionally save it to file
$result | ConvertTo-Json -Depth 3 # | Set-Content -Path 'Path\To\Output.json' -Force

Getting System.Object[] output in powershell

I wrote this quick script to retrieve information about a bunch of servers. When I run on my windows 7 (ps v2) host I get all the correct results. However, When I run on Server 2008 r2 (ps v2) I get System.Object[] for all the queries below. I have a bunch of other queries as well but they all work fine, just these ones I am getting this problem. Whats going on?
$ArrComputers = "localhost"
$OutputLog = ".\output.csv"
$NotRespondingLog = ".\notresponding.txt"
$ErrorActionPreference = "Stop"
Clear-Host
$data = ForEach ($Computer in $ArrComputers) {
try{
$ipAdd = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .)| select ipaddress
$MacAdd = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .)| Select MacAddress
$DefGateway = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .)| Select DefaultIPGateway
$DNSServ = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .)| Select DNSServerSearchOrder
$CPUname = (Get-WmiObject –class Win32_processor -ComputerName .)| Select name
$processorinfo = (Get-WmiObject –class Win32_processor -ComputerName .)| Select NumberOfCores
$processorinfo2 = (Get-WmiObject –class Win32_processor -ComputerName .)| Select NumberOfLogicalProcessors
$memory = Get-WMIObject -class Win32_PhysicalMemory -ComputerName $Computer |
Measure-Object -Property capacity -Sum |
select #{N="r"; E={[math]::round(($_.Sum / 1GB),2)}}
}catch{
$Computer | Out-File -FilePath $NotRespondingLog -Append -Encoding UTF8
continue
}
$props = #{
'IPAddress' = $ipAdd
'MacAddress' = $MacAdd
'DefaultIPGateway'= $DefGateway
'DNSServerSearchOrder' = $DNSServ
'cpuName' = $CPUname
'Cores' = $processorinfo
'logicalcores' = $processorinfo2
' Memory' = $memory
}
New-object -type PSCustomObject -Property $Props
}
$Data | export-csv -notypeinformation $outputlog
So the issue what you are facing: Powershell is returning the $data as Key=Value or hashtable format but as an object. So when you are inserting the same as CSV , then it is returning it as Object. So what you can do is you can convert the data to JSON format and you can insert the same. Else you can use Arraylist and insert all the values there. In that case it will accept the key-value pair mapping.
Hope it helps
I have removed the headers from the select query and created an array list with the custom object created in the loop and it will add each details from server to server and will append in the array list separately. I hope this helps you.
$ArrComputers = "localhost"
$OutputLog = ".\output.csv"
$NotRespondingLog = ".\notresponding.txt"
$ErrorActionPreference = "Stop"
Clear-Host
$Global:arraylist= New-Object System.Collections.ArrayList
$data = ForEach ($Computer in $ArrComputers) {
try{
$ipAdd = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName $Computer)| select ipaddress
$MacAdd = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName $Computer)| Select MacAddress
$DefGateway = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName $Computer)| Select DefaultIPGateway
$DNSServ = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName $Computer)| Select DNSServerSearchOrder
$CPUname = (Get-WmiObject –class Win32_processor -ComputerName $Computer)| Select name
$processorinfo = (Get-WmiObject –class Win32_processor -ComputerName $Computer)| Select NumberOfCores
$processorinfo2 = (Get-WmiObject –class Win32_processor -ComputerName $Computer)| Select NumberOfLogicalProcessors
$memory = Get-WMIObject -class Win32_PhysicalMemory -ComputerName $Computer |
Measure-Object -Property capacity -Sum |
select #{N="r"; E={[math]::round(($_.Sum / 1GB),2)}}
$props =[PSCustomObject]#{
'IPAddress' = $ipAdd.ipaddress[0]
'MacAddress' = $MacAdd.MacAddress
'DefaultIPGateway'= $DefGateway.DefaultIPGateway[0]
'DNSServerSearchOrder' = $DNSServ.DNSServerSearchOrder[0]
'cpuName' = $CPUname.name
'Cores' = $processorinfo.NumberOfCores
'logicalcores' = $processorinfo2.NumberOfLogicalProcessors
' Memory' = $memory.r
}
$arraylist.Add($props)
}catch{
$Computer | Out-File -FilePath $NotRespondingLog -Append -Encoding UTF8
continue
}
}
$arraylist | Export-Csv -NoTypeInformation $OutputLog -Force

How do I include computername in output

PS newbe here...
How do I get the remote computer name to appear in the output?
$computer = "PC3090-121","APCD02"
Get-WmiObject Win32_Printer -ComputerName $computer |
Select-Object SystemName,Name,Local |
Format-Table -AutoSize
I've tried including -computername, computername, %computername% in the Select and format-table -properties - no joy...
My searches have come up empty, or I couldn't understand them.
------------------------------ answer:
$computer = "PC3090-121","APCD02"
Get-WmiObject Win32_Printer -ComputerName $computer |
Select-Object __Server, Name, Local |
Format-Table -AutoSize
How about simply
Get-WmiObject Win32_Printer -ComputerName $computer |
Select-Object SystemName,Name,Local |
Format-Table -AutoSize
There is no computername property on the resulting object, nor is there a %computername% property. What exists is SystemName.

Querying partitions/drives on a remote server with WMI

I do the following to check for local drives/partitions on a remote computer:
Get-WmiObject -Class Win32_Share -ComputerName SERVERNAME -Filter "Description='Default share'"
but the command also returns CD-roms etc.
Is there a command to only return disk/partitions?
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
Foreach-Object {$_.DeviceID}
Try this:
Get-WMIObject Win32_DiskPartition -computername remotecomp |
ForEach-Object {
$info = #{}
$info.Disk = $_.DiskIndex
$info.Partition = $_.Index
$info.DriveLetter = $_.psbase.GetRelated('Win32_LogicalDisk') |
Select-Object -ExpandProperty DeviceID
New-Object PSObject -Property $info
}
$info # contains partions number and unit letter as hashtable
Get-WmiObject -query "Select * from Win32_DiskPartition" ... maybe?