In Part 1 of this short series, I showed you how many admins approach text-based report creation in PowerShell. The emphasis there is on "text-based:" While PowerShell can do a decent job of manipulating text, that isn't where its true power lies. If you're going to use a tool, it's best to use it properly: Your job will be easier, and the results will be better and more flexible.
My sample report has two scenarios. The first is when I need to display some data that comes from two different places, such as two WMI classes, and want to do so in a single element like a table or list. The second is when the information I need in a particular section can be obtained from a single place, like just one WMI class.
[CmdletBinding()] param ( [Parameter(Mandatory=$True)] [string]$computername ) function CSInfo { param($computername) $cs = Get-WmiObject -Class Win32_ComputerSystem -computername $computername $bios = Get-WmiObject -class Win32_BIOS -computername $computername $props = @{'Computer'=$cs.name; 'Manufacturer'=$cs.manufacturer; 'Model'=$cs.model; 'BIOSSerial'=$bios.serialnumber} $obj = New-Object -TypeName PSObject -Property $props Write-Output $obj } Write-Output "----- COMPUTERSYSTEM" CSInfo -computername $computername | Format-List Write-Output "------ OPERATING SYSTEM" Get-WmiObject -Class Win32_OperatingSystem -computername $computername | Select-Object -Property Version,BuildNumber,ServicePackMajorVersion,OSArchitecture | Format-List Write-Output "------ PROCESSORS" Get-WmiObject -class Win32_Processor -computername $computername | Select-Object -Property AddressWidth,MaxClockSpeed -First 1 | Format-List Write-Output "------ DISKS" Get-WmiObject -class Win32_LogicalDisk -filter "drivetype=3" -computername $computername | Select-Object -Property DeviceID,Size,FreeSpace | Format-List
That makes me clench my teeth marginally less than the original version. This can now be piped to Out-File successfully. There are three main changes:
- I'm using PowerShell to mark the parameter as mandatory, rather than using Read-Host as a prompt. PowerShell will prompt on its own if the parameter isn't included.
- I'm using Write-Output to put output into the pipeline, and consistently formatting all of my data as lists.
- For instances where I need to combine info from two places, I've written an internal "helper function" that produces a combined object. So no more formatting text - I'm letting the shell do it.
This is still far from ideal, and in the final part of this short series, I'm going to really make this look awesome.