Formatting multiple result sets together in powershell - 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

Related

Not able to format output as CSV [duplicate]

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
}

How to imbricate a command inside another command?

I have the following PowerShell script which allows me to collect information about disks & volumes on Windows servers of the domain where the script is launched:
$ErrorActionPreference = 'SilentlyContinue'
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties * |
Select-Object Name |
ForEach-Object {
if (Test-Connection $_.Name -Count 1) {
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object PSComputerName, DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.Size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.Freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
} else {
Write-Nost $_.Name " Connection Error"
}
} |
sort PSComputerName |
Format-Table -AutoSize
I get the following result:
SRV01 Connection Error
SRV02 Connection Error
PSComputerName DeviceID Size /GB Free /GB Free %
-------------- -------- ------------ --------- -------
SERVER03 C: 125,51 105,59 84,1
SERVER04 C: 24,83 7,38 29,7
SERVER05 E: 14,65 7,36 50,2
SERVER06 C: 49,66 29,28 59
I want to add an additional column with the OS for each server.
I would like this column to be in second position, after the "PSComputerName" column. How can I get this result?
I think I use a nested command by adding a Get-WmiObject Win32_OperatingSystem | Select-Object caption in the Get-WmiObject -Class Win32_LogicalDisk ..., but I don't know which syntax to use and how to imbricate a command in another command.
Don't use -properties *... it's going to retrieve every single populated property which you don't need in this script.
Get-ADComputer has an operatingsystem property.
Not tested:
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties OperatingSystem | ForEach-Object {
$OS = $_.OperatingSystem
If (Test-Connection $_.Name -Count 1 -Quiet){
Get-WmiObject -Class win32_logicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object pscomputername, #{Name="OS";Expression={$OS}} ,DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
}
else {
Write-host $_.Name " Connection Error"
}
} | sort pscomputername | Format-Table -AutoSize

How to fix this Powershell script using Get-WmiObject?

I have this piece of code that gets the information from the computers in the domain and outputs to a csv file. I tried to add a new line of code to also grab t he Disk information for the computers but I can't get it working as expected.
# Get the list of all computer names and export to CSV file
Get-ADComputer -Filter * | select Name | Export-Csv -Path 'C:\temp\computers.csv' -NoTypeInformation
# Import the computer names from CSV file and get the system information
$computers = Import-Csv “C:\Temp\computers.csv” | ForEach {
$computerSystem = Get-WmiObject Win32_ComputerSystem -ComputerName $_.Name
$computerOS = Get-WmiObject Win32_OperatingSystem -ComputerName $_.Name
$computerCPU = Get-WmiObject Win32_Processor -ComputerName $_.Name
$computerSN = Get-WmiObject Win32_bios -ComputerName $_.Name | Select-Object SerialNumber
$computerDisk = Get-WmiObject win32_logicaldisk -ComputerName $_.Name | Select-Object DeviceId
[PSCustomObject]#{
'PCName' = $computerSystem.Name
'Model' = $computerSystem.Model
'RAM' = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB)
'CPU' = $computerCPU.Name
'OS' = $computerOS.caption
'SN' = $computerSN.SerialNumber
'User' = $computerSystem.UserName
'Disk' = $computerDisk.DeviceId | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
}
} | Export-Csv 'C:\Temp\system-info.csv' -NoTypeInformation
This is the line of codes for disk.
$computerDisk = Get-WmiObject win32_logicaldisk -ComputerName $_.Name | Select-Object DeviceId
And...
'Disk' = $computerDisk.DeviceId | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
The other parameters work but only the disk info section isn't working. the output is: System.Object[] instead of displaying the info .
This has worked or me somewhat but it only grabs the info for the first drive. Also, the free space is larger than the Disk size which is weird.
$Computers = Import-Csv 'C:\Temp\computers.csv'
$Computers | ForEach {
$computerSystem = Get-WmiObject Win32_ComputerSystem -ComputerName $_.Name
$computerOS = Get-WmiObject Win32_OperatingSystem -ComputerName $_.Name
$computerCPU = Get-WmiObject Win32_Processor -ComputerName $_.Name
$computerSN = Get-WmiObject Win32_bios -ComputerName $_.Name | Select-Object SerialNumber
$computerDisk = Get-WmiObject win32_logicaldisk -ComputerName $_.Name | Select-Object DeviceId, Size, FreeSpace
[PSCustomObject]#{
'PCName' = $computerSystem.Name
'Model' = $computerSystem.Model
'RAM' = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB)
'CPU' = $computerCPU.Name
'OS' = $computerOS.caption
'SN' = $computerSN.SerialNumber
'User' = $computerSystem.UserName
'Disk' = $computerDisk.DeviceId | Format-Table | Out-String
'Size' = $computerDisk.Size | Format-Table | Out-String
'Free Space' = $computerDisk.FreeSpace | Format-Table | Out-String
}
} | Export-Csv 'C:\Temp\system-info.csv' -NoTypeInformation
You can do this to get the result I think you're after:
$Computers = Import-Csv 'C:\Temp\computers.csv'
$Computers | ForEach {
$computerSystem = Get-WmiObject Win32_ComputerSystem -ComputerName $_.Name
$computerOS = Get-WmiObject Win32_OperatingSystem -ComputerName $_.Name
$computerCPU = Get-WmiObject Win32_Processor -ComputerName $_.Name
$computerSN = Get-WmiObject Win32_bios -ComputerName $_.Name | Select-Object SerialNumber
$computerDisk = Get-WmiObject win32_logicaldisk -ComputerName $_.Name | Select-Object DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
[PSCustomObject]#{
'PCName' = $computerSystem.Name
'Model' = $computerSystem.Model
'RAM' = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB)
'CPU' = $computerCPU.Name
'OS' = $computerOS.caption
'SN' = $computerSN.SerialNumber
'User' = $computerSystem.UserName
'Disk' = $computerDisk | Format-Table | Out-String
}
} | Export-Csv 'C:\Temp\system-info.csv' -NoTypeInformation
The first problem was that in the $computerDisk = line you were using Select-Object to return only the DeviceID property, but then were later trying to use the other properties.
The second problem was that you need to pipe Format-Table to Out-String when you output it to convert it to string format so that Export-CSV doesn't treat it as an object.

How to format the output so that they are all aligned in the .log file?

I am working on a script for my college assignment that basically gathers your computer information and outputs it to a .log file. I've written the script already but when it outputs the information to the .log file, the Installed Software Names, Installed Software GUIDs, and the name of all users in the computer are listed like this:
But I want it to look like this:
Anyway I can edit my script to make it like this? Here's my script:
#Checking For Log File
$LogLocation = "$Home\Desktop\"
$LogFile = "Baabbasi.log"
$TestPathResult = Test-Path $Home\Desktop\Baabbasi.log
If ($TestPathResult -eq "False") {New-Item -Path $LogLocation -Name $LogFile -ItemType File}
#The Process After
Clear-Host
$TodaysDate = Get-Date
$ComputerName = $env:ComputerName
$BiosName = Get-WMIObject Win32_BIOS | Select-Object -ExpandProperty Name
$BiosVersion = Get-WMIObject Win32_BIOS | Select-Object -ExpandProperty Version
$HDSizes = Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" | Select-Object #{Name="size(GB)";Expression={"{0:N2}" -f($_.size/1gb)}}
$TotalHDSize = ($HDSizes | Measure-Object "size(GB)" -Sum).Sum
$PhysicalMemory = (Get-WMIObject Win32_PhysicalMemory).Capacity
$PhysicalMemoryinGB = $PhysicalMemory/1gb
$OSVersion = (Get-WmiObject -Class Win32_OperatingSystem).Version
$OSName = $env:OS
$InstalledSoftwareNames = Get-WMIObject Win32_Product | Select-Object -ExpandProperty Name | Out-String
$InstalledSoftwareGUID = Get-WMIObject Win32_Product | Select-Object -ExpandProperty IdentifyingNumber| Out-String
$LatestHotfix = Get-Hotfix | select-object HotFixID,InstalledOn | Sort-Object InstalledON -descending | Select -first 1 | Select-Object -ExpandProperty HotfixID
$UserAccount = [Environment]::UserName
$AllUserAccounts = Get-WmiObject Win32_UserAccount | Select-Object -ExpandProperty Name | Out-String
Add-Content $Home\Desktop\Baabbasi.log "
Date: $TodaysDate
======================================================================
Computer Name: $ComputerName
================ ======================================================
BIOS Name: $BiosName
BIOS Version: $BiosVersion
HD Size: $TotalHDSize GB
RAM Size: $PhysicalMemoryinGB GB
Operating System: $OSName
Operating System Version: $OSVersion
Installed Software Name:
$InstalledSoftwareNames
Installed Software GUID:
$InstalledSoftwareGUID
Last Installed Hot Fix: $LatestHotfix
Name of Registered System User: $UserAccount
Names of All Registered System Users on the System:
$AlluserAccounts
========================================================================
========================================================================
"
Change the statement
$InstalledSoftwareGUID = Get-WMIObject Win32_Product |
Select-Object -ExpandProperty IdentifyingNumber| Out-String
to something like this:
$InstalledSoftwareGUID = Get-WMIObject Win32_Product |
Select-Object -ExpandProperty IdentifyingNumber |
% { (' ' * 20) + $_ } | Out-String
That will prepend each GUID with 20 spaces (adjust the number to your desired indention depth) before converting the list to a single string.

Converting from bytes into gigabytes

I am using following script to get disk space audit in our enterprise environment.
Everything works fine except that I don't know how to get those values presented in GB/MB.
Any idea?
$Computers = Get-Content -Path D:\DISKSPACE_audit\Servers.txt
Get-WmiObject Win32_LogicalDisk -ComputerName $Computers | Where-Object {
$_.DriveType -eq 3
} | Select-Object SystemName,DeviceID,FreeSpace,Size
Divide the value by 1GB (or 1MB):
$Computers = Get-Content "D:\DISKSPACE_audit\Servers.txt"
Get-WmiObject Win32_LogicalDisk -Computer $Computers -Filter 'DriveType = 3' |
Select-Object SystemName, DeviceID,
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='Size';e={[int]($_.Size/1GB)}}