This Script generates a dynamic PC Environment Report. The report can include various information from Configuration Manager and Active Directory depending on your needs. There is an option to send this report as a mail to the specified recipient(s).
The information that can be collected from Configuration Manager is:
- Patch Compliance overview showing a given past number of Software Update Groups (default 3 Groups)
- Application categorization showing the number of applications that are either superseeded, without deployment or expired
- Devices categorization showing the number of devices that are active, inactive, obsolete and without a configuration manager client
- Computer reboot overview showing how many computers that have not been rebooted within a given time period (default 5 days)
The information that can be collected from Active Directory:
- Computer password information – how many computers that have and have not changed their computer password within a given time period (default 90 days)
- Operating system Overview – showing how many different Operating System versions that are present in the domain and how many there are of each
<# .SYNOPSIS Returns a environment status report within the areas that have been selected as parameters running the report .DESCRIPTION Queries the ConfigMgr to get information about applications, devices and software updates. Runs a query towards AD to find information about last computer password change. These information can be included or excluded using the parameters. All the information gathered from SCCM and AD will then ultamately be sent to the recipients specified in the mail section. .PARAMETER runAppScan Scan SCCM for applications to find both used an unused applications .PARAMETER runClientScan Scan SCCM Computer Clients to find out how many inactive clients there are .PARAMETER runPatchCompScan SCCM 3 Month Patch Compliance .PARAMETER runRebootCount Find computers that have not rebooted within the last X days .PARAMETER runOSCount AD Count number of unique Operating Systems in OU specified in $ADSearchBase and Count number of computers within different Operating Systems .PARAMETER runComputerPasswordCount #Find info about when computers last changed Computer password .PARAMETER runComputerPasswordCount #Create the report with everything included .EXAMPLE PCManagementReport -runAppScan $true -runPatchCompScan $true Creates a report including SCCM Application Scan and Path Compliance Graph .EXAMPLE PCManagementReport -runEverything $true Creates a report including everything .NOTES Cmdlet name: PCManagementReport Author: Mikael Blomqvist DateCreated: 2017-04-19 #> [CmdletBinding(SupportsShouldProcess = $True)] param ( [Parameter(Mandatory = $False, HelpMessage = "Scan ConfigMgr Applications (True/False)")] [boolean]$runAppScan = $false, [Parameter(Mandatory = $False, HelpMessage = "Scan ConfigMgr Devices (True/False)")] [boolean]$runClientScan = $false, [Parameter(Mandatory = $False, HelpMessage = "Create Path Compliance Scan (True/False)")] [boolean]$runPatchCompScan = $true, [Parameter(Mandatory = $False, HelpMessage = "Calculate Computer Reboot numbers (True/False)")] [boolean]$runRebootCount = $false, [Parameter(Mandatory = $False, HelpMessage = "Count number of unique Operating Systems and the number of Computers within each Operation Systems (True/False)")] [boolean]$runOSCount = $false, [Parameter(Mandatory = $False, HelpMessage = "Calculate Computer password change numbers (True/False)")] [boolean]$runComputerPasswordCount = $false, [Parameter(Mandatory = $False, HelpMessage = "Run everything (True/False)")] [boolean]$runEverything = $false ) #Load the ActiveDirectory Module $m = Get-Module -List ActiveDirectory if (!$m) { Write-Host "AD Powershell Module is not installed can not continue." Exit } else { Import-Module ActiveDirectory } $CMSiteServerFQDN = 'siteserver.domain.com' #Configuration Manager Site Server FQDN $CMSiteServer = $CMSiteServerFQDN.ToString().split(".") | Select -First 1 #Load Configuration Manager PowerShell Module try { Import-Module "\\$CMSiteServer\d$\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" -ErrorAction Stop } catch { $_.Exception.Message $_.Exception.ItemName Write-Host "Cannot load the Configuration Manager PowerShell Module from the specified location" break #Terminate if the module cannot be loaded } ############################################################################### # #Edit these to the customer specific values and $CMSiteServer above # ############################################################################### #Mail $smtpServer = "smtprelay.domain.com" $mailinfo_to = "recipient1@domain.com", "recipient2@domain.com" $mailinfo_cc = "" $mailinfo_from = "$env:computername@domain.com" $logo = "logo.gif" $Customername = "My Company" $sendMail = $true #Active Directory [string]$ADSearchBase = "OU=ComputersWin10,DC=domain,DC=com" #Win10 [int]$ComputerPasswordAgeDays = 90 [int]$RebootTresholdDays = 5 #SCCM $Collection = "All Windows 10" #Collection in SCCM which should be used as basis for the device count $patchNumberOfMonth = 3 #Number of month contained in the patch compliance overview #Graphic $CorporateColor = "#780000" $BackGroundColor = "#505A55" #Misc $ReportTitle = "System Report" $printToConsole = $true #Write Output to console ############################################################################## # #Variables which should not be edited # ############################################################################## $File_ExpSuperseededApps = "$PSScriptRoot\ExpiredSuperseededApps.csv" $File_CompNotBooted = "$PSScriptRoot\NotRebootedComputers.csv" [string]$Attachments = "$OutFile" #Mail $OutFile = "$PSScriptRoot\StatusReport.html" $subject = "$Customername : Status Report" #AD $OUName = (Get-ADOrganizationalUnit -Filter * -Properties CanonicalName -SearchBase $ADSearchBase -SearchScope Base).Name #SCCM $SiteCode = Get-PSDrive -PSProvider CMSITE #Configuration Manager Site Code $SCCMNameSpace = "root\sms\site_$SiteCode" $head = @" <style> H1{color: #000000} H2{color: #FFFFFF} H3{color: #000000} p{color: $CorporateColor; font-size:70%} TABLE {margin-left:50px;background-color: #FFFFFF;} TR {padding: 0px} TH {padding: 5px;background-color: $CorporateColor} TD {padding: 15px;text-align: Center} BODY {font-family: verdana;background-color: $BackGroundColor} </style> <Title>$ReportTitle</Title> "@ #Build ADSummary table $tbl_ADSummary = New-Object System.Data.DataTable ADSummary $col_ADHeading = New-Object System.Data.DataColumn ADHeading, ([string]) $col_ADData = New-Object System.Data.DataColumn ADData, ([string]) $tbl_ADSummary.columns.Add($col_ADHeading) $tbl_ADSummary.columns.Add($col_ADData) #Build AppsSummary table $tbl_AppsSummary = New-Object System.Data.DataTable AppsSummary $col_AppsHeading = New-Object System.Data.DataColumn AppsHeading, ([string]) $col_AppsData = New-Object System.Data.DataColumn AppsData, ([string]) $tbl_AppsSummary.columns.Add($col_AppsHeading) $tbl_AppsSummary.columns.Add($col_AppsData) #Build DeviceSummary table $tbl_DeviceSummary = New-Object System.Data.DataTable DeviceSummary $col_DeviceHeading = New-Object System.Data.DataColumn DeviceHeading, ([string]) $col_DeviceData = New-Object System.Data.DataColumn DeviceData, ([string]) $tbl_DeviceSummary.columns.Add($col_DeviceHeading) $tbl_DeviceSummary.columns.Add($col_DeviceData) #Build OS Table $tbl_ostable = New-Object System.Data.DataTable OS $Col_OSName = New-Object System.Data.DataColumn OSName, ([string]) $Col_OSCount = New-Object System.Data.DataColumn OSCount, ([string]) $tbl_ostable.Columns.Add($Col_OSName) $tbl_ostable.Columns.Add($Col_OSCount) #create patch table and columns $tbl_Compliance = New-Object System.Data.DataTable Patches $Col_month = New-Object System.Data.DataColumn Month, ([string]) $Col_compliant = New-Object System.Data.DataColumn Compliant, ([decimal]) $Col_noncompliant = New-Object System.Data.DataColumn NonCompliant, ([decimal]) $Col_unknown = New-Object System.Data.DataColumn Unknown, ([decimal]) $tbl_Compliance.columns.Add($Col_month) $tbl_Compliance.columns.Add($Col_compliant) $tbl_Compliance.columns.Add($Col_noncompliant) $tbl_Compliance.columns.Add($Col_unknown) #Build PieChart for Last Computer PW Change $tbl_piechart = New-Object System.Data.DataTable PWChange $Col_category = New-Object System.Data.DataColumn Category, ([string]) $Col_amount = New-Object System.Data.DataColumn Amount, ([string]) $tbl_piechart.columns.Add($Col_category) $tbl_piechart.columns.Add($Col_amount) #Function to add rows to table Function AddTo-Table { $tableName = $args[0] $tableHeading = $args[1] $tableHeadingValue = $args[2] $tableData = $args[3] $tableDataValue = $args[4] $row = $tableName.NewRow(); $row.$tableHeading = $tableHeadingValue; $row.$tableData = $tableDataValue $tableName.Rows.Add($row) If ($printToConsole) { Write-Host $tableHeadingValue ": " $tableDataValue } } #Function to add attachments to Sting that can be added to the mail Function Add-Attachment { [string]$file = $args[0] $Attachments = $Attachments + ',' + $file return $Attachments } #Create a Pie Chart with the supplied information Function CreateChart { $datasource = $args[0] $title = $args[1] $ChartType = $args[2] $xValue = $args[3] $yValue = $args[4] $imagePath = $args[5] $imagewidth = $args[6] $imageheight = $args[7] $displayedinLegend = $args[8] [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") $scriptpath = $PSScriptRoot # chart object $chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart $chart1.Width = $imagewidth $chart1.Height = $imageheight $chart1.BackColor = [System.Drawing.Color]::White # title [void]$chart1.Titles.Add("$title") $chart1.Titles[0].Font = "Verdana,14pt" $chart1.Titles[0].Alignment = "topCenter" $chart1.Titles[0].ForeColor = $CorporateColor # chart area $chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea $chartarea.Name = "ChartArea1" $chartarea.AxisY.MajorGrid.Enabled = $false $chartarea.AxisX.MajorGrid.Enabled = $false $chart1.ChartAreas.Add($chartarea) # legend $legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend $legend.name = "Legend1" $chart1.Legends.Add($legend) # data series [void]$chart1.Series.Add("PWWithin") $chart1.Series["PWWithin"].ChartType = "$ChartType" $chart1.Series["PWWithin"].BorderWidth = 10 $chart1.Series["PWWithin"].IsVisibleInLegend = $displayedinLegend $chart1.Series["PWWithin"].chartarea = "ChartArea1" $chart1.Series["PWWithin"].IsValueShownAsLabel = $true $datasource | ForEach-Object { $chart1.Series["PWWithin"].Points.addxy( $_.$xValue , $_.$yValue) } # save chart $chart1.SaveImage($imagePath, "png") } #Function to Create a stacked patch compliance graph showing the past software update groups Function CreateComplianceChart { $datasource = $args[0] $Pic_PatchComp = "PatchCompliance_Stacked100.png" $Path_PatchComp = "$PSScriptRoot\$Pic_PatchComp" [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") $scriptpath = $PSScriptRoot # chart object $chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart $chart1.Width = 800 $chart1.Height = 600 $chart1.BackColor = [System.Drawing.Color]::White # title [void]$chart1.Titles.Add("Past $patchNumberOfMonth Month Patch Compliance Development") $chart1.Titles[0].Font = "Verdana,20pt" $chart1.Titles[0].Alignment = "topCenter" $chart1.Titles[0].ForeColor = $CorporateColor # chart area $chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea $chartarea.Name = "ChartArea1" $chartarea.AxisY.Title = "Compliance %" $chartarea.AxisX.Title = "Month" $chartarea.AxisY.Interval = 10 $chartarea.AxisX.Interval = 1 $chart1.ChartAreas.Add($chartarea) # legend $legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend $legend.name = "Legend1" $chart1.Legends.Add($legend) # data series [void]$chart1.Series.Add("Compliant") $chart1.Series["Compliant"].ChartType = "StackedColumn100" $chart1.Series["Compliant"].BorderWidth = 10 $chart1.Series["Compliant"].IsVisibleInLegend = $true $chart1.Series["Compliant"].chartarea = "ChartArea1" $chart1.Series["Compliant"].Legend = "Legend1" $chart1.Series["Compliant"].color = "#2ECC71" $chart1.Series["Compliant"].IsValueShownAsLabel = $true $datasource | ForEach-Object { $chart1.Series["Compliant"].Points.addxy( $_.Month , $_.Compliant) } # data series [void]$chart1.Series.Add("NonCompliant") $chart1.Series["NonCompliant"].ChartType = "StackedColumn100" $chart1.Series["NonCompliant"].IsVisibleInLegend = $true $chart1.Series["NonCompliant"].BorderWidth = 10 $chart1.Series["NonCompliant"].chartarea = "ChartArea1" $chart1.Series["NonCompliant"].Legend = "Legend1" $chart1.Series["NonCompliant"].color = "#E74C3C" $chart1.Series["NonCompliant"].IsValueShownAsLabel = $true $datasource | ForEach-Object { $chart1.Series["NonCompliant"].Points.addxy( $_.Month , $_.NonCompliant) } # data series [void]$chart1.Series.Add("Unknown") $chart1.Series["Unknown"].ChartType = "StackedColumn100" $chart1.Series["Unknown"].IsVisibleInLegend = $true $chart1.Series["Unknown"].BorderWidth = 10 $chart1.Series["Unknown"].chartarea = "ChartArea1" $chart1.Series["Unknown"].Legend = "Legend1" $chart1.Series["Unknown"].color = "#CACFD2" $chart1.Series["Unknown"].IsValueShownAsLabel = $true $datasource | ForEach-Object { $chart1.Series["Unknown"].Points.addxy( $_.Month , $_.Unknown) } # save chart $chart1.SaveImage("$PSScriptRoot\PatchCompliance_Stacked100.png", "png") } # This function is used to send the email containing the report and attachments. # The reason this one is used instead of Send-MailMessage is that .NET allows images to be embedded in the email using the cid tag Function SendMail { $mailbody = $args[0] $mailattachments = $args[1] $SmtpClient = New-Object System.Net.Mail.SmtpClient($smtpServer) $MailMessage = New-object System.Net.Mail.MailMessage($mailinfo_from, $mailinfo_to, $Subject, $mailbody) $MailMessage.IsBodyHtml = $true $trimlenght = $PSScriptRoot.Length + 1 #have to add 1 because of the extra / in the path Foreach ($attachment in $mailattachments) { $attachmentID = $attachment.SubString($trimlenght) #This is to use only the actualy filename as ID $obj_attachment = New-Object System.Net.Mail.Attachment($attachment) $obj_attachment.ContentID = $attachmentID $MailMessage.Attachments.Add($obj_attachment) } $SmtpClient.Send($MailMessage) } $Attachments = Add-Attachment "$PSScriptRoot\$logo" #Get all Computers within the specified SearchBase excluding Servers $Computers = Get-ADComputer -SearchBase $ADSearchBase -filter { (OperatingSystem -notlike "*Server*") } -properties Name, DistinguishedName, OperatingSystem, OperatingSystemServicePack, passwordLastSet, LastLogonDate, Description AddTo-Table $tbl_ADSummary "ADHeading" "Number of computers in $OUName" "ADData" $Computers.Count If ($printToConsole) { Write-Host "Overview:" Write-Host "--------------------" Write-Host "Total number of computers: "$Computers.Count } #Count number of unique OS If ($runOSCount -or $runEverything) { #Change variable to UComputers and work with this $UComputers = $Computers | select-object Name, OperatingSystem, OperatingSystemServicePack, passwordLastSet, LastLogonDate, DistinguishedName, CountryOUADvariable $UniqueOS = $UComputers | Select-Object OperatingSystem | Sort OperatingSystem -Descending | Get-Unique -Asstring #Count number of unique OS $NumberofUniqueOS = 0 foreach ($uos in $UniqueOS) { $NumberofUniqueOS++ } #AddTo-Table $tbl_ADSummary "ADHeading" "Number of different Operating Systems" "ADData" $NumberofUniqueOS #Meassure/Count how many computer object of each OS type foreach ($os in $UComputers | Select-Object OperatingSystem | Sort OperatingSystem -Descending | Get-Unique -Asstring) { $count = ($UComputers | where { $_.OperatingSystem.ToString() -eq $os.OperatingSystem } | measure).Count AddTo-Table $tbl_ostable "OSName" ($os.OperatingSystem.ToString()) "OSCount" $count $count = 0 } #CreateOSChart $tbl_ostable CreateChart $tbl_ostable "Operating Systems" "Pie" "OSName" "OSCount" "$PSScriptRoot\OS_Pie.png" "400" "200" $true $Attachments = Add-Attachment "$PSScriptRoot\OS_Pie.png" } CD $SiteCode':' #Finding Computers that are within and outside the treshold of when Computer password was last set If ($runComputerPasswordCount -or $runEverything) { $ComputerStaleDate = (Get-Date).AddDays(-$ComputerPasswordAgeDays) $PWWithin = $Computers | Where { $_.passwordLastSet -ge $ComputerStaleDate } $PWOutside = $Computers | Where { $_.passwordLastSet -le $ComputerStaleDate } AddTo-Table $tbl_piechart "Category" "Within Treshold" "Amount" $PWWithin.Count AddTo-Table $tbl_piechart "Category" "Outside Treshhold" "Amount" $PWOutside.Count If ($printToConsole) { Write-Host "Computer Password:" Write-Host "--------------------" Write-Host "Within Treshold: "$PWWithin.Count Write-Host "Outside Treshhold: "$PWOutside.Count } #CreateComputerPWChart $tbl_piechart CreateChart $tbl_piechart "Computer Password" "Pie" "Category" "Amount" "$PSScriptRoot\ComputerPW_Pie.png" "400" "200" $true $ComputersinSCCM = $PWOutside | Where-Object { $_ -ne $null } | Foreach-Object { Get-CMDevice -Name $_.Name } AddTo-Table $tbl_ADSummary "ADHeading" "In SCCM but havent changed PW within $ComputerPasswordAgeDays days" "ADData" $ComputersinSCCM.Count $Attachments = Add-Attachment "$PSScriptRoot\ComputerPW_Pie.png" } #Count number of computers that havent been rebooted within the number of days specified in $RebootTresholdDays If ($runRebootCount -or $runEverything) { $OUCanonicalName = (Get-ADOrganizationalUnit -Filter * -Properties CanonicalName -SearchBase "$ADSearchBase" -SearchScope Base).CanonicalName $computersNotRebooted = (Get-WmiObject -namespace $SCCMNameSpace -computer $CMSiteServerFQDN -query "SELECT DISTINCT SMS_R_System.Name, SMS_G_System_OPERATING_SYSTEM.LastBootUpTime, SMS_G_System_OPERATING_SYSTEM.Caption FROM SMS_R_System INNER JOIN SMS_G_System_OPERATING_SYSTEM ON SMS_G_System_OPERATING_SYSTEM.ResourceID = SMS_R_System.ResourceId WHERE (DateDiff(day, SMS_G_System_OPERATING_SYSTEM.LastBootUpTime, GetDate()) >$RebootTresholdDays) AND SMS_R_System.SystemOUName = '$OUCanonicalName'").SMS_R_System | Select Name AddTo-Table $tbl_ADSummary "ADHeading" "Not rebooted within the last $RebootTresholdDays days" "ADData" $computersNotRebooted.Count If ($printToConsole) { Write-Host "Computer Reboot:" Write-Host "Computers not rebooted with $RebootTresholdDays : " $computersNotRebooted.Count } } #Get the last 3 SoftwareUpdate Groups If ($runPatchCompScan -or $runEverything) { $SUGs = Get-CMSoftwareUpdateGroup | Sort-Object { $_.datecreated } -Descending | Select -First $patchNumberOfMonth If ($printToConsole) { Write-Host "Software Update Groups:" Write-Host "-----------------------" } Foreach ($sug in $SUGs) { $month = $sug.LocalizedDisplayName $compliant = [math]::Round((($sug.NumCompliant / ($sug.NumTotal)) * 100), 2) $noncompliant = [math]::Round((($sug.NumNonCompliant / ($sug.NumTotal)) * 100), 2) $unknown = [math]::Round((($sug.NumUnknown / $sug.NumTotal) * 100), 2) If ($printToConsole) { Write-Host "Month: $month" Write-Host "-Compliant: $Compliant" Write-Host "-NonCompliant: $noncompliant" Write-Host "-Unknown: $unknown" } $row = $tbl_Compliance.NewRow(); $row.Month = $month; $row.Compliant = $compliant; $row.NonCompliant = $noncompliant; $row.Unknown = $unknown $tbl_Compliance.Rows.Add($row) } CreateComplianceChart $tbl_Compliance $Attachments = Add-Attachment "$PSScriptRoot\PatchCompliance_Stacked100.png" } #Count number of Applications in SCCM If ($runAppScan -or $runEverything) { $AllApps = Get-CMApplication $DeployedSuperseeded = $AllApps | Where-Object { <#($_.IsDeployed -eq $true) -and #>($_.IsSuperseded -eq $true) } $DeployedExpired = $AllApps | Where-Object { <#($_.IsDeployed -eq $true) -and#> ($_.IsExpired -eq $true) } $DeployedWorking = $AllApps | Where-Object { ($_.IsDeployed -eq $true) -and ($_.IsExpired -eq $false) -and ($_.IsSuperseded -eq $false) } $NotDeployed = $AllApps | Where-Object { ($_.IsDeployed -eq $false) } #AddTo-Table $tbl_AppsSummary "AppsHeading" "Total number of Applications in SCCM" "AppsData" $AllApps.Count AddTo-Table $tbl_AppsSummary "AppsHeading" "Superseeded Applications" "AppsData" $DeployedSuperseeded.Count AddTo-Table $tbl_AppsSummary "AppsHeading" "Expired Applications" "AppsData" $DeployedExpired.Count AddTo-Table $tbl_AppsSummary "AppsHeading" "Active Applications" "AppsData" $DeployedWorking.Count AddTo-Table $tbl_AppsSummary "AppsHeading" "Applications without deployment(s)" "AppsData" $NotDeployed.Count CreateChart $tbl_AppsSummary "All Applications" "Pie" "AppsHeading" "AppsData" "$PSScriptRoot\Applications_Pie.png" "400" "200" $true $Attachments = Add-Attachment "$PSScriptRoot\Applications_Pie.png" If ($printToConsole) { Write-Host "Applications:" Write-Host "--------------------" Write-Host "Superseeded Applications: "$DeployedSuperseeded.Count Write-Host "Expired Applications: "$DeployedExpired.Count Write-Host "Active Applications: "$DeployedWorking.Count Write-Host "Applications without deployment(s): "$NotDeployed.Count } } #Count devices in SCCM If ($runClientScan -or $runEverything) { $AllDevicesinSCCM = Get-CMDevice -CollectionName "$Collection" $AciveDevices = $AllDevicesinSCCM | Where-Object { ($_.ClientActiveStatus -eq 1) } $InaciveDevices = $AllDevicesinSCCM | Where-Object { ($_.ClientActiveStatus -eq 0) } $ObsoleteDevices = $AllDevicesinSCCM | Where-Object { ($_.IsObsolete -eq $true) } $NoSCCMClient = $AllDevicesinSCCM | Where-Object { ($_.IsClient -eq $false) } AddTo-Table $tbl_DeviceSummary "DeviceHeading" "Active Devices" "DeviceData" $AciveDevices.Count AddTo-Table $tbl_DeviceSummary "DeviceHeading" "Obsolete devices" "DeviceData" $ObsoleteDevices.Count AddTo-Table $tbl_DeviceSummary "DeviceHeading" "Inactive Devices" "DeviceData" $InaciveDevices.Count AddTo-Table $tbl_DeviceSummary "DeviceHeading" "Devices without Client" "DeviceData" $NoSCCMClient.Count CreateChart $tbl_DeviceSummary "Devices in $Collection" "Pie" "DeviceHeading" "DeviceData" "$PSScriptRoot\Devices_Pie.png" "400" "200" $true $Attachments = Add-Attachment "$PSScriptRoot\Devices_Pie.png" If ($printToConsole) { Write-Host "Devices:" Write-Host "--------------------" Write-Host "Active Devices: "$AciveDevices.Count Write-Host "Obsolete devices: "$ObsoleteDevices.Count Write-Host "Inactive Devices: "$InaciveDevices.Count Write-Host "Devices without Client: "$NoSCCMClient.Count } } CreateChart $tbl_ADSummary "Computer Info" "Bar" "ADHeading" "ADData" "$PSScriptRoot\ComputerInfo_Bar.png" "800" "300" $false $Attachments = Add-Attachment "$PSScriptRoot\ComputerInfo_Bar.png" #Convert All tables to HTML #-------------------------------------------------------- #Convert the ostable to a HTML Fragment that can be inserted into the html document. $osfragment = $tbl_ostable | Select @{Name = "Operating System"; Expression = { $_.OSName } }, @{Name = "Count"; Expression = { $_.OSCount } } | ConvertTo-Html -Fragment $adfragment = $tbl_ADSummary | Select ADHeading, ADData | ConvertTo-Html -Fragment $sccmfragment = $tbl_AppsSummary | Select AppsHeading, AppsData | ConvertTo-Html -Fragment #Write results depending on parameter set $footer = "Report ran from {3} initiated by {1}\{2} at {0}" -f (Get-Date), $env:USERDOMAIN, $env:USERNAME, $env:COMPUTERNAME $fragments = @() #Insert a graphic header $fragments += "<Center><table>" $fragments += "<tr><td><Img src='cid:$logo'></td></tr>" $fragments += "<tr><td><H1>$Customername - Environment Summary</H1></td></tr>" $fragments += "<tr><td ><h3>Computers in: $OUName</h3></td></tr>" #Only show this section if any of the elements in it are choosen to be calculated If ($runRebootCount -or $runComputerPasswordCount -or $runOSCount -or $runEverything) { $fragments += "<tr><th><H2>Active Directory Summary</H2></th></tr>" If ($runRebootCount -or $runEverything) { $fragments += "<tr><td><Img src='cid:ComputerInfo_Bar.png'></td></tr>" } If ($runComputerPasswordCount -or $runOSCount -or $runEverything) { $fragments += "<tr><td>" If ($runOSCount -or $runEverything) { $fragments += "<Img src='cid:OS_Pie.png'>" } If ($runComputerPasswordCount -or $runEverything) { $fragments += "<Img src='cid:ComputerPW_Pie.png'>" } $fragments += "</td></tr>" } } #Only show the SCCM Summary in the report if either runAppScan or runClientScan is enabled. If ($runAppScan -or $runClientScan -or $runEverything) { $fragments += "<tr><th><H2>SCCM Summary</H2></th></tr>" $fragments += "<tr><td>" If ($runAppScan -or $runEverything) { $fragments += "<Img src='cid:Applications_Pie.png'>" } If ($runClientScan -or $runEverything) { $fragments += "<Img src='cid:Devices_Pie.png'>" } $fragments += "</td></tr>" } #Only show the Patch Compliance Overview if runPatchCompScan is enabled If ($runPatchCompScan -or $runEverything) { $fragments += "<tr><th><H2>Patch Compliance Overview</H2></th></tr>" $fragments += "<tr><td><Img src='cid:PatchCompliance_Stacked100.png'></td></tr>" } $fragments += "<tr><td><p>$footer</p></td></tr>" $fragments += "</table></Center>" CD c:\ #Write to Files $DeployedSuperseeded | Select @{Name = "Superseeded Applications"; Expression = { $_.LocalizedDisplayName } } | Out-File $File_ExpSuperseededApps $DeployedExpired | Select @{Name = "Expired Applications"; Expression = { $_.LocalizedDisplayName } } | Out-File $File_ExpSuperseededApps -Append $NotDeployed | Select @{Name = "Applications without Deployments"; Expression = { $_.LocalizedDisplayName } } | Out-File $File_ExpSuperseededApps -Append $computersNotRebooted | Out-File $File_CompNotBooted #Adding files to attachment array if they have been created. If ($runRebootCount) { $Attachments = Add-Attachment $File_CompNotBooted } If ($runAppScan) { $Attachments = Add-Attachment $File_ExpSuperseededApps } $body = ConvertTo-Html -Head $head -Title $ReportTitle -Body $fragments #For the html report the cid is removed so the image src path is correct $report = $fragments -replace "cid:", "" ConvertTo-Html -Head $head -Title $ReportTitle -Body $report | Out-File $OutFile $ArrayAttachment = $Attachments.Split(",") If ($sendMail) { sendmail $body $ArrayAttachment } Else { Write-Host "Send Mail is disabled so no mail were sent." }
Recent Comments