#requires -version 2.0 <# .Synopsis Create System Report .Description Create a system status report with information gathered from WMI. The default output to the pipeline is a collection of custom objects. You can also use -TEXT to write a formatted text report, suitable for sending to a file or printer, or -HTML to create HTML code. You will need to pipe the results to Out-File if you want to save either the text or html output. NOTE: If you specify alternate credentials then any remote computers must have PowerShell remoting enabled. .Parameter Computername The name of the computer to query. The default is the localhost. .Parameter Credential The name of an alternate credential, or a saved credential object. .Parameter Quick Run a quick report which means no event logs queries. This speeds up the report generation. .Parameter ReportTitle The title for your report. This parameter has an alias of 'Title'. .Parameter Hours The number of hours to search for errors and warnings. The default is 24. .Parameter HTML Create HTML report. You must pipe to Out-File to save the results. .Parameter Text Create a formatted text report. You must pipe to Out-File to save the results. .Example PS C:\Scripts\> .\MorningReport | Export-Clixml ("c:\work\{0:yyyy-MM-dd}_{1}.xml" -f (get-date),$env:computername) Preparing morning report for SERENITY ...Operating System ...Computer System ...Services ...Logical Disks ...Network Adapters ...System Event Log Error/Warning since 01/09/2013 09:47:26 ...Application Event Log Error/Warning since 01/09/2013 09:47:26 Run a morning report and export it to an XML file with a date stamped file name. .Example PS C:\Scripts\> .\MorningReport Quark -Text | Out-file c:\work\quark-report.txt Run a morning report for a remote computer and save the results to an text file. .Example PS C:\Scripts\> .\MorningReport -html -hours 30 | Out-file C:\work\MyReport.htm Run a morning report for the local computer and get last 30 hours of event log information. Save as an HTML report. .Example PS C:\Scripts\> get-content computers.txt | .\Morningreport -quick -html | out-file c:\work\morningreport.htm Get the list of computers and create a single HTML report without the event log information. .Link http://jdhitsolutions.com/blog/2013/02/powershell-morning-report-with-credentials .Link Get-WMIObject Get-EventLog ConvertTo-HTML .Inputs String .Outputs Custom object, text or HTML code .Notes Version : 2.0 Last Updated: 02/21/2013 Author : Jeffery Hicks (@JeffHicks) Read PowerShell: Learn Windows PowerShell 3 in a Month of Lunches Learn PowerShell Toolmaking in a Month of Lunches PowerShell in Depth: An Administrator's Guide **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** #> [cmdletbinding(DefaultParameterSetName="object")] Param( [Parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [ValidateNotNullOrEmpty()] [string]$Computername=$env:computername, [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty, [ValidateNotNullOrEmpty()] [alias("title")] [string]$ReportTitle="Morning System Report", [ValidateScript({$_ -ge 1})] [int]$Hours=24, [switch]$Quick, [Parameter(ParameterSetName="HTML")] [switch]$HTML, [Parameter(ParameterSetName="TEXT")] [switch]$Text ) Begin { #script internal version number used in output [string]$reportVersion="2.0" <# define some HTML style here's a source for HTML color codes http://www.immigration-usa.com/html_colors.html the code must be left justified #> #region define html head $head = @" $ReportTitle Zazu

The Morning Report

$(Get-Date -DisplayHint Date | out-string)


"@ #endregion #prepare HTML code $fragments=@() } #Begin Process { #region ping test #set a default value for the ping test $ok=$False If ($computername -eq $env:computername) { #local computer so no ping test is necessary $OK=$True } elseIf (($computername -ne $env:computername) -AND (Test-Connection -ComputerName $computername -quiet -Count 2)) { #not local computer and it can be pinged so proceed $OK=$True } #endregion #region define a parameter hashtable $paramhash=@{ Classname="Win32_OperatingSystem" Computername=$Computername ErrorAction="Stop" } if ($credential) { $paramhash.Add("Credential",$Credential) } #endregion If ($OK) { Try { #get Operating system information from WMI $os=Get-WmiObject @paramhash #set a variable to indicate WMI can be reached $wmi=$True } Catch { Write-Warning "WMI failed to connect to $($computername.ToUpper())" } if ($wmi) { Write-Host "Preparing morning report for $($os.CSname)" -ForegroundColor Cyan #region OS Summary Write-Host "...Operating System" -ForegroundColor Cyan $osdata=$os | Select @{Name="Computername";Expression={$_.CSName}}, @{Name="OS";Expression={$_.Caption}}, @{Name="ServicePack";Expression={$_.CSDVersion}}, free*memory,totalv*,NumberOfProcesses, @{Name="LastBoot";Expression={$_.ConvertToDateTime($_.LastBootupTime)}}, @{Name="Uptime";Expression={(Get-Date) - ($_.ConvertToDateTime($_.LastBootupTime))}} #endregion #region Computer system Write-Host "...Computer System" -ForegroundColor Cyan $paramhash.Classname="Win32_ComputerSystem" $cs=Get-WmiObject @paramhash $csdata=$cs | Select Status,Manufacturer,Model,SystemType,Number* #endregion #region Get Service information Write-Host "...Services" -ForegroundColor Cyan #get services via WMI and group into a hash table $paramhash.Classname="Win32_Service" $wmiservices=Get-WmiObject @paramhash $services=$wmiservices | Group State -AsHashTable #get services set to auto start that are not running $failedAutoStart=$wmiservices | Where { ($_.startmode -eq "Auto") -AND ($_.state -ne "Running")} #endregion #region Disk Utilization Write-Host "...Logical Disks" -ForegroundColor Cyan $paramhash.Classname="Win32_LogicalDisk" $paramhash.Add("Filter","Drivetype=3") $disks=Get-WmiObject @paramhash $diskData=$disks | Select DeviceID, @{Name="SizeGB";Expression={$_.size/1GB -as [int]}}, @{Name="FreeGB";Expression={"{0:N2}" -f ($_.Freespace/1GB)}}, @{Name="PercentFree";Expression={"{0:P2}" -f ($_.Freespace/$_.Size)}} #endregion #region NetworkAdapters Write-Host "...Network Adapters" -ForegroundColor Cyan $paramhash.classname="Win32_NetworkAdapter" $paramhash.filter="MACAddress Like '%'" #get NICS that have a MAC address only $nics=Get-WmiObject @paramhash $nicdata=$nics | Foreach { $tempHash=@{Name=$_.Name;DeviceID=$_.DeviceID;AdapterType=$_.AdapterType;MACAddress=$_.MACAddress} #get related configuation information $config=$_.GetRelated() | where {$_.__CLASS -eq "Win32_NetworkadapterConfiguration"} #add to temporary hash $tempHash.Add("IPAddress",$config.IPAddress) $tempHash.Add("IPSubnet",$config.IPSubnet) $tempHash.Add("DefaultGateway",$config.DefaultIPGateway) $tempHash.Add("DHCP",$config.DHCPEnabled) #convert lease information if found if ($config.DHCPEnabled -AND $config.DHCPLeaseObtained) { $tempHash.Add("DHCPLeaseExpires",($config.ConvertToDateTime($config.DHCPLeaseExpires))) $tempHash.Add("DHCPLeaseObtained",($config.ConvertToDateTime($config.DHCPLeaseObtained))) $tempHash.Add("DHCPServer",$config.DHCPServer) } New-Object -TypeName PSObject -Property $tempHash } #endregion If ($Quick) { Write-Verbose "Skipping event log queries" } #region Event log queries else { #Event log errors and warnings in the last $Hours hours $last=(Get-Date).AddHours(-$Hours) #define a hash table of parameters to splat to Get-Eventlog $GetEventLogParam = @{ LogName="System" EntryType="Error","Warning" After=$last} #System Log Write-Host "...System Event Log Error/Warning since $last" -ForegroundColor Cyan #hashtable of optional parameters for Invoke-Command $InvokeCommandParam = @{ Computername=$Computername ArgumentList=$GetEventLogParam ScriptBlock = {Param ($params) Get-EventLog @params } } if ($Credential) { $InvokeCommandParam.Add("Credential",$Credential) } $syslog = Invoke-Command @InvokeCommandParam $syslogdata = $syslog | Select TimeGenerated,EventID,Source,Message #Application Log Write-Host "...Application Event Log Error/Warning since $last" -ForegroundColor Cyan #update the hashtable $GetEventLogParam.LogName="Application" #update invoke-command parameters $InvokeCommandParam.ArgumentList = $GetEventLogParam $applog = Invoke-Command @InvokeCommandParam $applogdata = $applog | Select TimeGenerated,EventID,Source,Message } #endregion } #if wmi is ok #write results depending on parameter set $footer="Report v{3} run {0} by {1}\{2}" -f (Get-Date),$env:USERDOMAIN,$env:USERNAME,$reportVersion #region Create HTML if ($HTML) { #add each computer to a navigation menu in the header $head+=("{0} " -f $computername.ToUpper()) $fragments+=("

{0}: System Summary

" -f $computername.ToUpper()) $fragments+=$osdata | ConvertTo-Html -as List -Fragment $fragments+=$csdata | ConvertTo-Html -as List -Fragment #insert navigation bookmarks $nav=@"
{0} Services {0} Failed Auto Start {0} Disks {0} Network {0} System Log {0} Application Log
"@ -f $Computername.ToUpper() #add a link to the document top $nav+="`nTop" $fragments+=$nav $fragments+="
" $fragments+=ConvertTo-Html -Fragment -PreContent ("

{0}: Services

" -f $computername.ToUpper()) $services.keys | foreach { $fragments+= ConvertTo-Html -Fragment -PreContent "

$_

" $fragments+=$services.$_ | Select Name,Displayname,StartMode| ConvertTo-HTML -Fragment #insert navigation link after each section $fragments+=$nav } $fragments+=$failedAutoStart | Select Name,Displayname,StartMode,State | ConvertTo-Html -Fragment -PreContent ("

{0}: Failed Auto Start

" -f $computername.ToUpper()) $fragments+=$nav $fragments+=$diskdata | ConvertTo-HTML -Fragment -PreContent ("

{0}: Disk Utilization

" -f $computername.ToUpper()) $fragments+=$nav #convert nested object array properties to strings $fragments+=$nicdata | Select Name,DeviceID,DHCP*,AdapterType,MACAddress, @{Name="IPAddress";Expression={$_.IPAddress | Out-String}}, @{Name="IPSubnet";Expression={$_.IPSubnet | Out-String}}, @{Name="IPGateway";Expression={$_.DefaultGateway | Out-String}} | ConvertTo-HTML -Fragment -PreContent ("

{0}: Network Adapters

" -f $computername.ToUpper()) $fragments+=$nav $fragments+=$syslogData | ConvertTo-HTML -Fragment -PreContent ("

{0}: System Event Log Summary

" -f $computername.toUpper()) $fragments+=$nav $fragments+=$applogData | ConvertTo-HTML -Fragment -PreContent ("

{0}: Application Event Log Summary

" -f $computername.toUpper()) $fragments+=$nav } #endregion #region Create TEXT elseif ($TEXT) { #prepare formatted text $ReportTitle "-"*($ReportTitle.Length) "System Summary" $osdata | Out-String $csdata | format-List | Out-String Write "Services" $services.keys | foreach { $services.$_ | Select Name,Displayname,StartMode,State } | Format-List | Out-String Write "Failed Autostart Services" $failedAutoStart | Select Name,Displayname,StartMode,State Write "Disk Utilization" $diskdata | Format-table -AutoSize | Out-String Write "Network Adapters" $nicdata | Format-List | Out-String Write "System Event Log Summary" $syslogdata | Format-List | Out-String Write "Application Event Log Summary" $applogdata | Format-List | Out-String Write $Footer } #endregion #region Create custom object else { #Write data to the pipeline as part of a custom object New-Object -TypeName PSObject -Property @{ OperatingSystem=$osdata ComputerSystem=$csdata Services=$services.keys | foreach {$services.$_ | Select Name,Displayname,StartMode,State} FailedAutoStart=$failedAutoStart | Select Name,Displayname,StartMode,State Disks=$diskData Network=$nicData SystemLog=$syslogdata ApplicationLog=$applogdata ReportVersion=$reportVersion RunDate=Get-Date RunBy="$env:USERDOMAIN\$env:USERNAME" } } #endregion } #if OK else { #can't ping computer so fail Write-Warning "Failed to ping $computername" } } #process End { #if HTML finish the report here so that if piping in #computer names we get one report for all computers If ($HTML) { #copying fragments to clipboard for troubleshooting #Write $fragments | clip $head+="


" ConvertTo-Html -Head $head -Title $ReportTitle -PreContent ($fragments | out-String) -PostContent "
$footer" } Write-Host "Finished!" -ForegroundColor Green } #end of script