├── Media ├── e2_events.png ├── e1_process.png ├── scom_plain.png ├── scom_spicy.png ├── pester_simple.PNG ├── pester_simple.png ├── pester_advanced.PNG └── pester_advanced.png ├── appveyor.yml ├── PSHTMLTable ├── PSHTMLTable.psm1 ├── en-US │ └── about_PSHTMLTable.help.txt ├── PSHTMLTable.psd1 └── Public │ ├── Close-HTML.ps1 │ ├── New-HTMLHead.ps1 │ ├── New-HTMLTable.ps1 │ ├── ConvertTo-PropertyValue.ps1 │ └── Add-HTMLTableColor.ps1 ├── deploy.psdeploy.ps1 ├── Tests └── PSHTMLTable.Tests.ps1 ├── LICENSE ├── psake.ps1 └── README.md /Media/e2_events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/e2_events.png -------------------------------------------------------------------------------- /Media/e1_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/e1_process.png -------------------------------------------------------------------------------- /Media/scom_plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/scom_plain.png -------------------------------------------------------------------------------- /Media/scom_spicy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/scom_spicy.png -------------------------------------------------------------------------------- /Media/pester_simple.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/pester_simple.PNG -------------------------------------------------------------------------------- /Media/pester_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/pester_simple.png -------------------------------------------------------------------------------- /Media/pester_advanced.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/pester_advanced.PNG -------------------------------------------------------------------------------- /Media/pester_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamblingCookieMonster/PSHTMLTable/HEAD/Media/pester_advanced.png -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # See http://www.appveyor.com/docs/appveyor-yml for many more options 2 | 3 | #Publish to PowerShell Gallery with this key 4 | environment: 5 | NuGetApiKey: 6 | secure: oqMFzG8F65K5l572V7VzlZIWU7xnSYDLtSXECJAAURrXe8M2+BAp9vHLT+1h1lR0 7 | 8 | # Allow WMF5 (i.e. PowerShellGallery functionality) 9 | os: WMF 5 10 | 11 | # Skip on updates to the readme. 12 | # We can force this by adding [skip ci] or [ci skip] anywhere in commit message 13 | skip_commits: 14 | message: /updated readme.*|update readme.*s/ 15 | 16 | build: false 17 | 18 | #Kick off the CI/CD pipeline 19 | test_script: 20 | - ps: . .\build.ps1 -------------------------------------------------------------------------------- /PSHTMLTable/PSHTMLTable.psm1: -------------------------------------------------------------------------------- 1 | #handle PS2 2 | if(-not $PSScriptRoot) 3 | { 4 | $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 5 | } 6 | #Get public and private function definition files. 7 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) 8 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) 9 | 10 | #Dot source the files 11 | Foreach($import in @($Public + $Private)) 12 | { 13 | Try 14 | { 15 | . $import.fullname 16 | } 17 | Catch 18 | { 19 | Write-Error -Message "Failed to import function $($import.fullname): $_" 20 | } 21 | } 22 | 23 | Export-ModuleMember -Function ($Public | Select -ExpandProperty BaseName) 24 | -------------------------------------------------------------------------------- /deploy.psdeploy.ps1: -------------------------------------------------------------------------------- 1 | # Generic module deployment. 2 | # This stuff should be moved to psake for a cleaner deployment view 3 | 4 | # ASSUMPTIONS: 5 | 6 | # folder structure of: 7 | # - RepoFolder 8 | # - This PSDeploy file 9 | # - ModuleName 10 | # - ModuleName.psd1 11 | 12 | # Nuget key in $ENV:NugetApiKey 13 | 14 | # Set-BuildEnvironment from BuildHelpers module has populated ENV:BHProjectName 15 | 16 | # find a folder that has psd1 of same name... 17 | 18 | if($ENV:BHProjectName -and $ENV:BHProjectName.Count -eq 1) 19 | { 20 | Deploy Module { 21 | By PSGalleryModule { 22 | FromSource $ENV:BHProjectName 23 | To PSGallery 24 | WithOptions @{ 25 | ApiKey = $ENV:NugetApiKey 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Tests/PSHTMLTable.Tests.ps1: -------------------------------------------------------------------------------- 1 | $PSVersion = $PSVersionTable.PSVersion.Major 2 | $ModuleName = $ENV:BHProjectName 3 | 4 | # Verbose output for non-master builds on appveyor 5 | # Handy for troubleshooting. 6 | # Splat @Verbose against commands as needed (here or in pester tests) 7 | $Verbose = @{} 8 | if($ENV:BHBranchName -notlike "master" -or $env:BHCommitMessage -match "!verbose") 9 | { 10 | $Verbose.add("Verbose",$True) 11 | } 12 | 13 | Import-Module $PSScriptRoot\..\$ModuleName -Force 14 | 15 | Describe "$ModuleName PS$PSVersion" { 16 | Context 'Strict mode' { 17 | 18 | Set-StrictMode -Version latest 19 | 20 | It 'Should load' { 21 | $Module = Get-Module $ModuleName 22 | $Module.Name | Should be $ModuleName 23 | $Commands = $Module.ExportedCommands.Keys 24 | $Commands -contains 'Add-HTMLTableColor' | Should Be $True 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Warren F. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PSHTMLTable/en-US/about_PSHTMLTable.help.txt: -------------------------------------------------------------------------------- 1 | PSTOPIC 2 | about_PSHTMLTable 3 | 4 | SHORT DESCRIPTION 5 | This is a set of functions used to generate HTML tables, and highlight cells within them on demand. 6 | 7 | DETAILED DESCRIPTION 8 | This is a set of functions used to generate HTML tables, and highlight cells within them on demand. 9 | 10 | You can use and combine several functions to create HTML pages: 11 | 12 | * New-HTMLHead - Starts building HTML including internal style sheet (leaves body, html tags open) 13 | * New-HTMLTable - Create an HTML table from one or more objects 14 | * Add-HTMLTableColor - Colorize cells or rows in an HTML table, or add other inline CSS 15 | * CloseHTML - Close out the body and html tags 16 | * ConvertTo-PropertyValue - Convert an object with various properties into an array of property,value pairs 17 | 18 | Note that these should work together. New-HTMLTable just creates a table, not the full HTML around it, thus allowing you to build multiple tables per page. 19 | 20 | See Get-Help New-HTMLHead -Full to see a variety of examples, including the use of all functions together. 21 | 22 | LINK 23 | https://github.com/RamblingCookieMonster/PSHTMLTable 24 | -------------------------------------------------------------------------------- /psake.ps1: -------------------------------------------------------------------------------- 1 | # PSake makes variables declared here available in other scriptblocks 2 | # Init some things 3 | Properties { 4 | # Find the build folder based on build system 5 | $ProjectRoot = $ENV:BHProjectPath 6 | if(-not $ProjectRoot) 7 | { 8 | $ProjectRoot = $PSScriptRoot 9 | } 10 | 11 | $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" 12 | $PSVersion = $PSVersionTable.PSVersion.Major 13 | $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" 14 | $lines = '----------------------------------------------------------------------' 15 | 16 | $Verbose = @{} 17 | if($ENV:BHCommitMessage -match "!verbose") 18 | { 19 | $Verbose = @{Verbose = $True} 20 | } 21 | } 22 | 23 | Task Default -Depends Deploy 24 | 25 | Task Init { 26 | $lines 27 | Set-Location $ProjectRoot 28 | "Build System Details:" 29 | Get-Item ENV:BH* 30 | "`n" 31 | } 32 | 33 | Task Test -Depends Init { 34 | $lines 35 | "`n`tSTATUS: Testing with PowerShell $PSVersion" 36 | 37 | # Gather test results. Store them in a variable and file 38 | $TestResults = Invoke-Pester -Path $ProjectRoot\Tests -PassThru -OutputFormat NUnitXml -OutputFile "$ProjectRoot\$TestFile" 39 | 40 | # In Appveyor? Upload our tests! #Abstract this into a function? 41 | If($ENV:BHBuildSystem -eq 'AppVeyor') 42 | { 43 | (New-Object 'System.Net.WebClient').UploadFile( 44 | "https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", 45 | "$ProjectRoot\$TestFile" ) 46 | } 47 | 48 | Remove-Item "$ProjectRoot\$TestFile" -Force -ErrorAction SilentlyContinue 49 | 50 | # Failed tests? 51 | # Need to tell psake or it will proceed to the deployment. Danger! 52 | if($TestResults.FailedCount -gt 0) 53 | { 54 | Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" 55 | } 56 | "`n" 57 | } 58 | 59 | Task Build -Depends Test { 60 | $lines 61 | 62 | # Load the module, read the exported functions, update the psd1 FunctionsToExport 63 | Set-ModuleFunctions 64 | 65 | # Bump the module version 66 | $Version = Get-NextPSGalleryVersion -Name $env:BHProjectName 67 | Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $Version 68 | } 69 | 70 | Task Deploy -Depends Build { 71 | $lines 72 | 73 | # Gate deployment 74 | if( 75 | $ENV:BHBuildSystem -ne 'Unknown' -and 76 | $ENV:BHBranchName -eq "master" -and 77 | $ENV:BHCommitMessage -match '!deploy' 78 | ) 79 | { 80 | $Params = @{ 81 | Path = $ProjectRoot 82 | Force = $true 83 | } 84 | 85 | Invoke-PSDeploy @Verbose @Params 86 | } 87 | else 88 | { 89 | "Skipping deployment: To deploy, ensure that...`n" + 90 | "`t* You are in a known build system (Current: $ENV:BHBuildSystem)`n" + 91 | "`t* You are committing to the master branch (Current: $ENV:BHBranchName) `n" + 92 | "`t* Your commit message includes !deploy (Current: $ENV:BHCommitMessage)" 93 | } 94 | } -------------------------------------------------------------------------------- /PSHTMLTable/PSHTMLTable.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # Script module or binary module file associated with this manifest. 4 | RootModule = 'PSHTMLTable.psm1' 5 | 6 | # Version number of this module. 7 | ModuleVersion = '0.0.1' 8 | 9 | # ID used to uniquely identify this module 10 | GUID = 'ce5f0fbd-d393-4095-aee6-61259a2e0fb4' 11 | 12 | # Author of this module 13 | Author = 'Warren Frame' 14 | 15 | # Company or vendor of this module 16 | #CompanyName = 'Unknown' 17 | 18 | # Copyright statement for this module 19 | Copyright = '(c) 2016 Warren F. All rights reserved.' 20 | 21 | # Description of the functionality provided by this module 22 | Description = 'Simplify creating HTML tables' 23 | 24 | # Minimum version of the Windows PowerShell engine required by this module 25 | PowerShellVersion = '2.0' 26 | 27 | # Name of the Windows PowerShell host required by this module 28 | # PowerShellHostName = '' 29 | 30 | # Minimum version of the Windows PowerShell host required by this module 31 | # PowerShellHostVersion = '' 32 | 33 | # Minimum version of Microsoft .NET Framework required by this module 34 | # DotNetFrameworkVersion = '' 35 | 36 | # Minimum version of the common language runtime (CLR) required by this module 37 | # CLRVersion = '' 38 | 39 | # Processor architecture (None, X86, Amd64) required by this module 40 | # ProcessorArchitecture = '' 41 | 42 | # Modules that must be imported into the global environment prior to importing this module 43 | # RequiredModules = @() 44 | 45 | # Assemblies that must be loaded prior to importing this module 46 | # RequiredAssemblies = @() 47 | 48 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 49 | # ScriptsToProcess = @() 50 | 51 | # Type files (.ps1xml) to be loaded when importing this module 52 | # TypesToProcess = @() 53 | 54 | # Format files (.ps1xml) to be loaded when importing this module 55 | #FormatsToProcess = '.Format.ps1xml' 56 | 57 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 58 | # NestedModules = @() 59 | 60 | # Functions to export from this module 61 | FunctionsToExport = '*' 62 | 63 | # Cmdlets to export from this module 64 | CmdletsToExport = '*' 65 | 66 | # Variables to export from this module 67 | VariablesToExport = '*' 68 | 69 | # Aliases to export from this module 70 | AliasesToExport = '*' 71 | 72 | # DSC resources to export from this module 73 | # DscResourcesToExport = @() 74 | 75 | # List of all modules packaged with this module 76 | # ModuleList = @() 77 | 78 | # List of all files packaged with this module 79 | # FileList = @() 80 | 81 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 82 | PrivateData = @{ 83 | 84 | PSData = @{ 85 | 86 | # Tags applied to this module. These help with module discovery in online galleries. 87 | Tags = @('HTML', 'Table', 'Color', 'Mail', 'Report', 'Webpage') 88 | 89 | # A URL to the license for this module. 90 | LicenseUri = 'https://github.com/RamblingCookieMonster/PSHTMLTable/blob/master/LICENSE' 91 | 92 | # A URL to the main website for this project. 93 | ProjectUri = 'https://github.com/RamblingCookieMonster/PSHTMLTable/' 94 | 95 | # A URL to an icon representing this module. 96 | # IconUri = '' 97 | 98 | # ReleaseNotes of this module 99 | # ReleaseNotes = '' 100 | 101 | } # End of PSData hashtable 102 | 103 | } # End of PrivateData hashtable 104 | 105 | # HelpInfo URI of this module 106 | # HelpInfoURI = '' 107 | 108 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 109 | # DefaultCommandPrefix = '' 110 | 111 | } 112 | -------------------------------------------------------------------------------- /PSHTMLTable/Public/Close-HTML.ps1: -------------------------------------------------------------------------------- 1 | function Close-HTML { 2 | <# 3 | .SYNOPSIS 4 | Close out the body and html tags 5 | 6 | .DESCRIPTION 7 | Close out the body and html tags 8 | 9 | .PARAMETER HTML 10 | HTML string to work with 11 | 12 | .PARAMETER Decode 13 | If specified, run HTML string through HtmlDecode 14 | 15 | .EXAMPLE 16 | #This example requires and demonstrates using the New-HTMLHead, New-HTMLTable, Add-HTMLTableColor, ConvertTo-PropertyValue and Close-HTML functions. 17 | 18 | #get processes to work with 19 | $processes = Get-Process 20 | 21 | #Build HTML header 22 | $HTML = New-HTMLHead -title "Process details" 23 | 24 | #Add CPU time section with top 10 PrivateMemorySize processes. This example does not highlight any particular cells 25 | $HTML += "

Process Private Memory Size

" 26 | $HTML += New-HTMLTable -inputObject $($processes | sort PrivateMemorySize -Descending | select name, PrivateMemorySize -first 10) 27 | 28 | #Add Handles section with top 10 Handle usage. 29 | $handleHTML = New-HTMLTable -inputObject $($processes | sort handles -descending | select Name, Handles -first 10) 30 | 31 | #Add highlighted colors for Handle count 32 | 33 | #build hash table with parameters for Add-HTMLTableColor. Argument and AttrValue will be modified each time we run this. 34 | $params = @{ 35 | Column = "Handles" #I'm looking for cells in the Handles column 36 | ScriptBlock = {[double]$args[0] -gt [double]$args[1]} #I want to highlight if the cell (args 0) is greater than the argument parameter (arg 1) 37 | Attr = "Style" #This is the default, don't need to actually specify it here 38 | } 39 | 40 | #Add yellow, orange and red shading 41 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 1500 -attrValue "background-color:#FFFF99;" @params 42 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 2000 -attrValue "background-color:#FFCC66;" @params 43 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 3000 -attrValue "background-color:#FFCC99;" @params 44 | 45 | #Add title and table 46 | $HTML += "

Process Handles

" 47 | $HTML += $handleHTML 48 | 49 | #Add process list containing first 10 processes listed by get-process. This example does not highlight any particular cells 50 | $HTML += New-HTMLTable -inputObject $($processes | select name -first 10 ) -listTableHead "Random Process Names" 51 | 52 | #Add property value table showing details for PowerShell ISE 53 | $HTML += "

PowerShell Process Details PropertyValue table

" 54 | $processDetails = Get-process powershell_ise | select name, id, cpu, handles, workingset, PrivateMemorySize, Path -first 1 55 | $HTML += New-HTMLTable -inputObject $(ConvertTo-PropertyValue -inputObject $processDetails) 56 | 57 | #Add same PowerShell ISE details but not in property value form. Close the HTML 58 | $HTML += "

PowerShell Process Details object

" 59 | $HTML += New-HTMLTable -inputObject $processDetails | Close-HTML 60 | 61 | #write the HTML to a file and open it up for viewing 62 | set-content C:\test.htm $HTML 63 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 64 | 65 | .FUNCTIONALITY 66 | General Command 67 | #> 68 | 69 | [cmdletbinding()] 70 | param( 71 | [Parameter( Mandatory=$true, 72 | ValueFromPipeline=$true, 73 | ValueFromPipelineByPropertyName=$false)] 74 | [string]$HTML, 75 | 76 | [switch]$Decode 77 | ) 78 | #Thanks to ‏@ashyoungblood! 79 | if($Decode) 80 | { 81 | Add-Type -AssemblyName System.Web 82 | $HTML = [System.Web.HttpUtility]::HtmlDecode($HTML) 83 | } 84 | "$HTML " 85 | } 86 | -------------------------------------------------------------------------------- /PSHTMLTable/Public/New-HTMLHead.ps1: -------------------------------------------------------------------------------- 1 | function New-HTMLHead { 2 | <# 3 | .SYNOPSIS 4 | Returns HTML including internal style sheet 5 | 6 | .DESCRIPTION 7 | Returns HTML including internal style sheet 8 | 9 | .PARAMETER cssPath 10 | If specified, contents of this file are embedded in an internal style sheet via ", 108 | 109 | [string]$title = $null 110 | ) 111 | 112 | #add css from file if specified 113 | if($cssPath){$style = ""} 114 | 115 | #Return HTML 116 | @" 117 | 118 | 119 | 120 | $(if($title){"$title"}) 121 | $style 122 | 123 | 124 | 125 | "@ 126 | 127 | } -------------------------------------------------------------------------------- /PSHTMLTable/Public/New-HTMLTable.ps1: -------------------------------------------------------------------------------- 1 | function New-HTMLTable { 2 | <# 3 | .SYNOPSIS 4 | Create an HTML table from an input object 5 | 6 | .DESCRIPTION 7 | Create an HTML table from an input object 8 | 9 | .PARAMETER InputObject 10 | One or more objects (ie. (Get-process | select Name,Company) 11 | 12 | .PARAMETER Properties 13 | If specified, limit table to these specific properties in the order specified. 14 | 15 | .PARAMETER setAlternating 16 | Add CSS class = odd or even to each row. True by default. Be sure your CSS includes odd and even definitions 17 | 18 | .PARAMETER listTableHead 19 | If a list is provided, use this parameter to specify the list header (PowerShell uses * by default) 20 | 21 | .EXAMPLE 22 | #This example requires and demonstrates using the New-HTMLHead, New-HTMLTable, Add-HTMLTableColor, ConvertTo-PropertyValue and Close-HTML functions. 23 | 24 | #get processes to work with 25 | $processes = Get-Process 26 | 27 | #Build HTML header 28 | $HTML = New-HTMLHead -title "Process details" 29 | 30 | #Add CPU time section with top 10 PrivateMemorySize processes. This example does not highlight any particular cells 31 | $HTML += "

Process Private Memory Size

" 32 | $HTML += New-HTMLTable -inputObject $($processes | sort PrivateMemorySize -Descending | select name, PrivateMemorySize -first 10) 33 | 34 | #Add Handles section with top 10 Handle usage. 35 | $handleHTML = New-HTMLTable -inputObject $($processes | sort handles -descending | select Name, Handles -first 10) 36 | 37 | #Add highlighted colors for Handle count 38 | 39 | #build hash table with parameters for Add-HTMLTableColor. Argument and AttrValue will be modified each time we run this. 40 | $params = @{ 41 | Column = "Handles" #I'm looking for cells in the Handles column 42 | ScriptBlock = {[double]$args[0] -gt [double]$args[1]} #I want to highlight if the cell (args 0) is greater than the argument parameter (arg 1) 43 | Attr = "Style" #This is the default, don't need to actually specify it here 44 | } 45 | 46 | #Add yellow, orange and red shading 47 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 1500 -attrValue "background-color:#FFFF99;" @params 48 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 2000 -attrValue "background-color:#FFCC66;" @params 49 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 3000 -attrValue "background-color:#FFCC99;" @params 50 | 51 | #Add title and table 52 | $HTML += "

Process Handles

" 53 | $HTML += $handleHTML 54 | 55 | #Add process list containing first 10 processes listed by get-process. This example does not highlight any particular cells 56 | $HTML += New-HTMLTable -inputObject $($processes | select name -first 10 ) -listTableHead "Random Process Names" 57 | 58 | #Add property value table showing details for PowerShell ISE 59 | $HTML += "

PowerShell Process Details PropertyValue table

" 60 | $processDetails = Get-process powershell_ise | select name, id, cpu, handles, workingset, PrivateMemorySize, Path -first 1 61 | $HTML += New-HTMLTable -inputObject $(ConvertTo-PropertyValue -inputObject $processDetails) 62 | 63 | #Add same PowerShell ISE details but not in property value form. Close the HTML 64 | $HTML += "

PowerShell Process Details object

" 65 | $HTML += New-HTMLTable -inputObject $processDetails | Close-HTML 66 | 67 | #write the HTML to a file and open it up for viewing 68 | set-content C:\test.htm $HTML 69 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 70 | 71 | .NOTES 72 | Props to Zachary Loeber for the idea: http://gallery.technet.microsoft.com/scriptcenter/Colorize-HTML-Table-Cells-2ea63acd 73 | 74 | I believe that .Net 3.5 is a requirement for using the Linq libraries 75 | 76 | .FUNCTIONALITY 77 | General Command 78 | #> 79 | [CmdletBinding()] 80 | param ( 81 | [Parameter( Position=0, 82 | Mandatory=$true, 83 | ValueFromPipeline=$true)] 84 | [PSObject[]]$InputObject, 85 | 86 | [Parameter( Mandatory=$false, 87 | ValueFromPipeline=$false)] 88 | [string[]]$Properties, 89 | 90 | [Parameter( Mandatory=$false, 91 | ValueFromPipeline=$false)] 92 | [bool]$setAlternating = $true, 93 | 94 | [Parameter( Mandatory=$false, 95 | ValueFromPipeline=$false)] 96 | [string]$listTableHead = $null 97 | 98 | ) 99 | 100 | BEGIN { 101 | #requires -version 2.0 102 | add-type -AssemblyName System.xml.linq | out-null 103 | $Objects = New-Object System.Collections.ArrayList 104 | } 105 | 106 | PROCESS { 107 | 108 | #Loop through inputObject, add to collection. Filter properties if specified. 109 | foreach($object in $inputObject){ 110 | if($Properties){ [void]$Objects.add(($object | Select $Properties)) } 111 | else{ [void]$Objects.add( $object )} 112 | } 113 | 114 | } 115 | 116 | END { 117 | 118 | # Convert our data to x(ht)ml 119 | $xml = [System.Xml.Linq.XDocument]::Parse("$($Objects | ConvertTo-Html -Fragment)") 120 | 121 | #replace * as table head if specified. Note, this should only be done for a list... 122 | if($listTableHead){ 123 | $xml = [System.Xml.Linq.XDocument]::parse( $xml.Document.ToString().replace("*","$listTableHead") ) 124 | } 125 | 126 | if($setAlternating){ 127 | #loop through descendents. If their index is even mark with class even, odd with class odd. 128 | foreach($descendent in $($xml.Descendants("tr"))){ 129 | if(($descendent.NodesBeforeSelf() | Measure-Object).count % 2 -eq 0){ 130 | $descendent.SetAttributeValue("class", "even") 131 | } 132 | else{ 133 | $descendent.SetAttributeValue("class", "odd") 134 | } 135 | } 136 | } 137 | #Provide full HTML or just the table depending on param 138 | $xml.Document.ToString() 139 | } 140 | } -------------------------------------------------------------------------------- /PSHTMLTable/Public/ConvertTo-PropertyValue.ps1: -------------------------------------------------------------------------------- 1 | function ConvertTo-PropertyValue { 2 | <# 3 | .SYNOPSIS 4 | Convert an object with various properties into an array of property, value pairs 5 | 6 | .DESCRIPTION 7 | Convert an object with various properties into an array of property, value pairs 8 | 9 | If you output reports or other formats where a table with one long row is poorly formatted, this is a quick way to create a table of property value pairs. 10 | 11 | There are other ways you could do this. For example, I could list all noteproperties from Get-Member results and return them. 12 | This function will keep properties in the same order they are provided, which can often be helpful for readability of results. 13 | 14 | .PARAMETER inputObject 15 | A single object to convert to an array of property value pairs. 16 | 17 | .PARAMETER leftheader 18 | Header for the left column. Default: Property 19 | 20 | .PARAMETER rightHeader 21 | Header for the right column. Default: Value 22 | 23 | .PARAMETER memberType 24 | Return only object members of this membertype. Default: Property, NoteProperty, ScriptProperty 25 | 26 | .EXAMPLE 27 | get-process powershell_ise | convertto-propertyvalue 28 | 29 | I want details on the powershell_ise process. 30 | With this command, if I output this to a table, a csv, etc. I will get a nice vertical listing of properties and their values 31 | Without this command, I get a long row with the same info 32 | 33 | .EXAMPLE 34 | #This example requires and demonstrates using the New-HTMLHead, New-HTMLTable, Add-HTMLTableColor, ConvertTo-PropertyValue and Close-HTML functions. 35 | 36 | #get processes to work with 37 | $processes = Get-Process 38 | 39 | #Build HTML header 40 | $HTML = New-HTMLHead -title "Process details" 41 | 42 | #Add CPU time section with top 10 PrivateMemorySize processes. This example does not highlight any particular cells 43 | $HTML += "

Process Private Memory Size

" 44 | $HTML += New-HTMLTable -inputObject $($processes | sort PrivateMemorySize -Descending | select name, PrivateMemorySize -first 10) 45 | 46 | #Add Handles section with top 10 Handle usage. 47 | $handleHTML = New-HTMLTable -inputObject $($processes | sort handles -descending | select Name, Handles -first 10) 48 | 49 | #Add highlighted colors for Handle count 50 | 51 | #build hash table with parameters for Add-HTMLTableColor. Argument and AttrValue will be modified each time we run this. 52 | $params = @{ 53 | Column = "Handles" #I'm looking for cells in the Handles column 54 | ScriptBlock = {[double]$args[0] -gt [double]$args[1]} #I want to highlight if the cell (args 0) is greater than the argument parameter (arg 1) 55 | Attr = "Style" #This is the default, don't need to actually specify it here 56 | } 57 | 58 | #Add yellow, orange and red shading 59 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 1500 -attrValue "background-color:#FFFF99;" @params 60 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 2000 -attrValue "background-color:#FFCC66;" @params 61 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 3000 -attrValue "background-color:#FFCC99;" @params 62 | 63 | #Add title and table 64 | $HTML += "

Process Handles

" 65 | $HTML += $handleHTML 66 | 67 | #Add process list containing first 10 processes listed by get-process. This example does not highlight any particular cells 68 | $HTML += New-HTMLTable -inputObject $($processes | select name -first 10 ) -listTableHead "Random Process Names" 69 | 70 | #Add property value table showing details for PowerShell ISE 71 | $HTML += "

PowerShell Process Details PropertyValue table

" 72 | $processDetails = Get-process powershell_ise | select name, id, cpu, handles, workingset, PrivateMemorySize, Path -first 1 73 | $HTML += New-HTMLTable -inputObject $(ConvertTo-PropertyValue -inputObject $processDetails) 74 | 75 | #Add same PowerShell ISE details but not in property value form. Close the HTML 76 | $HTML += "

PowerShell Process Details object

" 77 | $HTML += New-HTMLTable -inputObject $processDetails | Close-HTML 78 | 79 | #write the HTML to a file and open it up for viewing 80 | set-content C:\test.htm $HTML 81 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 82 | 83 | .FUNCTIONALITY 84 | General Command 85 | #> 86 | [cmdletbinding()] 87 | param( 88 | [Parameter(Mandatory=$true, 89 | ValueFromPipeline=$true, 90 | ValueFromRemainingArguments=$false)] 91 | [PSObject]$InputObject, 92 | 93 | [validateset("AliasProperty", "CodeProperty", "Property", "NoteProperty", "ScriptProperty", 94 | "Properties", "PropertySet", "Method", "CodeMethod", "ScriptMethod", "Methods", 95 | "ParameterizedProperty", "MemberSet", "Event", "Dynamic", "All")] 96 | [string[]]$memberType = @( "NoteProperty", "Property", "ScriptProperty" ), 97 | 98 | [string]$leftHeader = "Property", 99 | 100 | [string]$rightHeader = "Value" 101 | ) 102 | 103 | begin{ 104 | #init array to dump all objects into 105 | $allObjects = New-Object System.Collections.ArrayList 106 | 107 | } 108 | process{ 109 | #if we're taking from pipeline and get more than one object, this will build up an array 110 | [void]$allObjects.add($inputObject) 111 | } 112 | 113 | end{ 114 | #use only the first object provided 115 | $allObjects = $allObjects[0] 116 | 117 | #Get properties. Filter by memberType. 118 | $properties = $allObjects.psobject.properties | ?{$memberType -contains $_.memberType} | select -ExpandProperty Name 119 | 120 | #loop through properties and display property value pairs 121 | foreach($property in $properties){ 122 | 123 | #Create object with property and value 124 | $temp = "" | select $leftHeader, $rightHeader 125 | $temp.$leftHeader = $property.replace('"',"") 126 | $temp.$rightHeader = try { $allObjects | select -ExpandProperty $temp.$leftHeader -erroraction SilentlyContinue } catch { $null } 127 | $temp 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PSHTMLTable 2 | ============== 3 | 4 | This is an old set of functions used to generate HTML tables, and highlight cells within them on demand. 5 | 6 | One of PowerShell�s major strong points is its ability to interface with a variety of technologies and data sources. This makes it a great candidate for sending ad hoc notifications or generating HTML based reports. The attached functions can be used to spice up various notifications, reports, or other HTML generated by PowerShell. 7 | 8 | A quick example showing a standard SCOM alert, and a SCOM alert generated using PSHTMLTable functions. The latter is a bit more helpful! 9 | 10 | **Plain SCOM Alert**: 11 | 12 | [![plain alert](/Media/scom_plain.png)](/Media/scom_plain.png) 13 | 14 | **PSHTMLTable SCOM Alert**: 15 | 16 | [![scom spicy](/Media/scom_spicy.png)](/Media/scom_spicy.png) 17 | 18 | ## Instructions 19 | 20 | ```powershell 21 | # One time setup 22 | # Download the repository 23 | # Unblock the zip 24 | # Extract the PSHTMLTable folder to a module path (e.g. $env:USERPROFILE\Documents\WindowsPowerShell\Modules\) 25 | 26 | #Simple alternative, if you have PowerShell 5, or the PowerShellGet module: 27 | Install-Module PSHTMLTable 28 | 29 | # Import the module. 30 | Import-Module PSHTMLTable #Alternatively, Import-Module \\Path\To\PSHTMLTable 31 | 32 | # Get commands in the module 33 | Get-Command -Module PSHTMLTable 34 | ``` 35 | 36 | ## Examples 37 | 38 | ### Simple Example 39 | 40 | This illustrates creating a webpage with several Process related stats, using all of the functions in PSHTMLTable 41 | 42 | ```powershell 43 | #gather 20 events from the system log and pick out a few properties 44 | $events = Get-EventLog -LogName System -Newest 20 | select TimeGenerated, Index, EntryType, UserName, Message 45 | 46 | #Create the HTML table without alternating rows, colorize Warning and Error messages, highlighting the whole row. 47 | $eventTable = $events | New-HTMLTable -setAlternating $false | 48 | Add-HTMLTableColor -Argument "Warning" -Column "EntryType" -AttrValue "background-color:#FFCC66;" -WholeRow | 49 | Add-HTMLTableColor -Argument "Error" -Column "EntryType" -AttrValue "background-color:#FFCC99;" -WholeRow 50 | 51 | #Build the HTML head, add an h3 header, add the event table, and close out the HTML 52 | $HTML = New-HTMLHead 53 | $HTML += "

Last 20 System Events

" 54 | $HTML += $eventTable | Close-HTML 55 | 56 | #test it out 57 | set-content C:\test.htm $HTML 58 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 59 | ``` 60 | 61 | [![example output](/Media/e2_events.png)](/Media/e2_events.png) 62 | 63 | ### Complex Example 64 | 65 | This illustrates creating a webpage with several Process related stats, using all of the functions in PSHTMLTable 66 | 67 | ```powershell 68 | #This example demonstrates using the New-HTMLHead, New-HTMLTable, Add-HTMLTableColor, ConvertTo-PropertyValue and Close-HTML functions 69 | 70 | #get processes to work with 71 | $processes = Get-Process 72 | 73 | #Build HTML header 74 | $HTML = New-HTMLHead -title "Process details" 75 | 76 | #Add CPU time section with top 10 PrivateMemorySize processes. This example does not highlight any particular cells 77 | $HTML += "

Process Private Memory Size

" 78 | $HTML += New-HTMLTable -inputObject $($processes | sort PrivateMemorySize -Descending | select name, PrivateMemorySize -first 10) 79 | 80 | #Add Handles section with top 10 Handle usage. 81 | $handleHTML = New-HTMLTable -inputObject $($processes | sort handles -descending | select Name, Handles -first 10) 82 | 83 | #Add highlighted colors for Handle count 84 | 85 | #build hash table with parameters for Add-HTMLTableColor. Argument and AttrValue will be modified each time we run this. 86 | $params = @{ 87 | Column = "Handles" #I'm looking for cells in the Handles column 88 | ScriptBlock = {[double]$args[0] -gt [double]$args[1]} #I want to highlight if the cell (args 0) is greater than the argument parameter (arg 1) 89 | Attr = "Style" #This is the default, don't need to actually specify it here 90 | } 91 | 92 | #Add yellow, orange and red shading 93 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 1500 -attrValue "background-color:#FFFF99;" @params 94 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 2000 -attrValue "background-color:#FFCC66;" @params 95 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 3000 -attrValue "background-color:#FFCC99;" @params 96 | 97 | #Add title and table 98 | $HTML += "

Process Handles

" 99 | $HTML += $handleHTML 100 | 101 | #Add process list containing first 10 processes listed by get-process. This example does not highlight any particular cells 102 | $HTML += New-HTMLTable -inputObject $($processes | select name -first 10 ) -listTableHead "Random Process Names" 103 | 104 | #Add property value table showing details for PowerShell ISE 105 | $HTML += "

PowerShell Process Details PropertyValue table

" 106 | $processDetails = Get-process powershell_ise | select name, id, cpu, handles, workingset, PrivateMemorySize, Path -first 1 107 | $HTML += New-HTMLTable -inputObject $(ConvertTo-PropertyValue -inputObject $processDetails) 108 | 109 | #Add same PowerShell ISE details but not in property value form. Close the HTML 110 | $HTML += "

PowerShell Process Details object

" 111 | $HTML += New-HTMLTable -inputObject $processDetails | Close-HTML 112 | 113 | #write the HTML to a file and open it up for viewing 114 | set-content C:\test.htm $HTML 115 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 116 | ``` 117 | 118 | [![example output](/Media/e1_process.png)](/Media/e1_process.png) 119 | 120 | 121 | ### Pester Example 122 | ```powershell 123 | # Invoke pester and store the results so that they can be referenced multiple times 124 | $results = Invoke-Pester -show none -passthru 125 | 126 | # Format cells where the value is greater than 0 127 | $params = @{ 128 | ScriptBlock = {$args[0] -gt 0} 129 | } 130 | 131 | # Create a summary table and add spaces into the column names for asthetics, adding colours for passed and failed tests 132 | $summaryTable = $results | Select-Object ` 133 | @{Name="Passed Count";Expression={$_.PassedCount}}, 134 | @{Name="Failed Count";Expression={$_.FailedCount}}, 135 | @{Name="Skipped Count";Expression={$_.SkippedCount}}, 136 | @{Name="Pending Count";Expression={$_.PendingCount}}, 137 | @{Name="Total Count";Expression={$_.TotalCount}} | New-HtmlTable | 138 | Add-HTMLTableColor -Argument "Failed" -Column "Failed Count" -AttrValue "background-color:#ffb3b3;" @params | 139 | Add-HTMLTableColor -Argument "Passed" -Column "Passed Count" -AttrValue "background-color:#c6ffb3;" @params 140 | 141 | #Compose the html adding headers 142 | $HTML = New-HTMLHead 143 | $HTML += "

Post Build Test Summary

" 144 | $HTML += $summaryTable 145 | $HTML += "

Post Build Test Results

" 146 | 147 | # Create a seperate table for each describe block 148 | foreach ($section in ($results |Select-Object -ExpandProperty TestResult | Select-Object Describe -Unique)) { 149 | # Add a title based on the descibe block 150 | $HTML += ("

{0}

" -f $section.Describe) 151 | $HTML += $results | Select-Object -ExpandProperty TestResult | Where-Object -FilterScript { $_.Describe -eq $section.Describe } | 152 | Select-Object Context, Name, Result | 153 | New-HtmlTable | 154 | Add-HTMLTableColor -Argument "Failed" -Column "Result" -AttrValue "background-color:#ffb3b3;" | 155 | Add-HTMLTableColor -Argument "Passed" -Column "Result" -AttrValue "background-color:#c6ffb3;" 156 | } 157 | 158 | $HTML += "" | Close-HTML 159 | 160 | #test it out 161 | set-content C:\test.html $HTML 162 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.html 163 | ``` 164 | 165 | [![example output](/Media/pester_advanced.png)](/Media/pester_advanced.png) 166 | 167 | ## Functions 168 | 169 | PSHTMLTable includes several functions: 170 | 171 | * ConvertTo-PropertyValue - Convert an object with various properties into an array of property,value pairs 172 | * New-HTMLHead - Starts building HTML including internal style sheet (leaves body, html tags open) 173 | * New-HTMLTable - Create an HTML table from one or more objects 174 | * Add-HTMLTableColor - Colorize cells or rows in an HTML table, or add other inline CSS 175 | * CloseHTML - Close out the body and html tags 176 | 177 | ## Notes 178 | 179 | This was written during my early days with PowerShell - pull requests would be welcome! 180 | 181 | For more details, stop by [the old blog post](http://ramblingcookiemonster.wordpress.com/2013/08/06/powershell-and-tables/) on this! -------------------------------------------------------------------------------- /PSHTMLTable/Public/Add-HTMLTableColor.ps1: -------------------------------------------------------------------------------- 1 | function Add-HTMLTableColor { 2 | <# 3 | .SYNOPSIS 4 | Colorize cells or rows in an HTML table, or add other inline CSS 5 | 6 | .DESCRIPTION 7 | Colorize cells or rows in an HTML table, or add other inline CSS 8 | 9 | .PARAMETER HTML 10 | HTML string to work with 11 | 12 | .PARAMETER Column 13 | If specified, the column you want to modify. This is case sensitive 14 | 15 | .PARAMETER Argument 16 | If Column is specified, this argument can be used to compare with current cell. 17 | 18 | .PARAMETER ScriptBlock 19 | If Column is specified, used to evaluate whether to colorize a cell. If the scriptblock returns $true the cell will be colorized. 20 | 21 | $args[0] is the existing cell value in the table 22 | $args[1] is your Argument parameter 23 | 24 | Examples: 25 | {[string]$args[0] -eq [string]$args[1]} #existing cell value equals Argument. This is the default 26 | {[double]$args[0] -gt [double]$args[1]} #existing cell value is greater than Argument. 27 | 28 | Use strong typesetting if possible. 29 | 30 | .PARAMETER Attr 31 | If Column is specified, the attribute to change should ColumnValue be found in the Column specified or if the ScriptBlock is true. Default: Style 32 | 33 | .PARAMETER AttrValue 34 | If Column is specified, the attribute value to set when the ColumnValue is found in the Column specified or if the ScriptBlock is true. 35 | 36 | Example: "background-color:#FFCC99;" 37 | 38 | .PARAMETER WholeRow 39 | If specified, and Column is specified, set the Attr and AttrValue for the entire row, not just a cell. 40 | 41 | .EXAMPLE 42 | #This example requires and demonstrates using the New-HTMLHead, New-HTMLTable, Add-HTMLTableColor, ConvertTo-PropertyValue and Close-HTML functions. 43 | 44 | #get processes to work with 45 | $processes = Get-Process 46 | 47 | #Build HTML header 48 | $HTML = New-HTMLHead -title "Process details" 49 | 50 | #Add CPU time section with top 10 PrivateMemorySize processes. This example does not highlight any particular cells 51 | $HTML += "

Process Private Memory Size

" 52 | $HTML += New-HTMLTable -inputObject $($processes | sort PrivateMemorySize -Descending | select name, PrivateMemorySize -first 10) 53 | 54 | #Add Handles section with top 10 Handle usage. 55 | $handleHTML = New-HTMLTable -inputObject $($processes | sort handles -descending | select Name, Handles -first 10) 56 | 57 | #Add highlighted colors for Handle count 58 | 59 | #build hash table with parameters for Add-HTMLTableColor. Argument and AttrValue will be modified each time we run this. 60 | $params = @{ 61 | Column = "Handles" #I'm looking for cells in the Handles column 62 | ScriptBlock = {[double]$args[0] -gt [double]$args[1]} #I want to highlight if the cell (args 0) is greater than the argument parameter (arg 1) 63 | Attr = "Style" #This is the default, don't need to actually specify it here 64 | } 65 | 66 | #Add yellow, orange and red shading 67 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 1500 -attrValue "background-color:#FFFF99;" @params 68 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 2000 -attrValue "background-color:#FFCC66;" @params 69 | $handleHTML = Add-HTMLTableColor -HTML $handleHTML -Argument 3000 -attrValue "background-color:#FFCC99;" @params 70 | 71 | #Add title and table 72 | $HTML += "

Process Handles

" 73 | $HTML += $handleHTML 74 | 75 | #Add process list containing first 10 processes listed by get-process. This example does not highlight any particular cells 76 | $HTML += New-HTMLTable -inputObject $($processes | select name -first 10 ) -listTableHead "Random Process Names" 77 | 78 | #Add property value table showing details for PowerShell ISE 79 | $HTML += "

PowerShell Process Details PropertyValue table

" 80 | $processDetails = Get-process powershell_ise | select name, id, cpu, handles, workingset, PrivateMemorySize, Path -first 1 81 | $HTML += New-HTMLTable -inputObject $(ConvertTo-PropertyValue -inputObject $processDetails) 82 | 83 | #Add same PowerShell ISE details but not in property value form. Close the HTML 84 | $HTML += "

PowerShell Process Details object

" 85 | $HTML += New-HTMLTable -inputObject $processDetails | Close-HTML 86 | 87 | #write the HTML to a file and open it up for viewing 88 | set-content C:\test.htm $HTML 89 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 90 | 91 | .EXAMPLE 92 | # Table with the 20 most recent events, highlighting error and warning rows 93 | 94 | #gather 20 events from the system log and pick out a few properties 95 | $events = Get-EventLog -LogName System -Newest 20 | select TimeGenerated, Index, EntryType, UserName, Message 96 | 97 | #Create the HTML table without alternating rows, colorize Warning and Error messages, highlighting the whole row. 98 | $eventTable = $events | New-HTMLTable -setAlternating $false | 99 | Add-HTMLTableColor -Argument "Warning" -Column "EntryType" -AttrValue "background-color:#FFCC66;" -WholeRow | 100 | Add-HTMLTableColor -Argument "Error" -Column "EntryType" -AttrValue "background-color:#FFCC99;" -WholeRow 101 | 102 | #Build the HTML head, add an h3 header, add the event table, and close out the HTML 103 | $HTML = New-HTMLHead 104 | $HTML += "

Last 20 System Events

" 105 | $HTML += $eventTable | Close-HTML 106 | 107 | #test it out 108 | set-content C:\test.htm $HTML 109 | & 'C:\Program Files\Internet Explorer\iexplore.exe' C:\test.htm 110 | 111 | .NOTES 112 | Props to Zachary Loeber and Jaykul for the idea and help: 113 | http://gallery.technet.microsoft.com/scriptcenter/Colorize-HTML-Table-Cells-2ea63acd 114 | http://stackoverflow.com/questions/4559233/technique-for-selectively-formatting-data-in-a-powershell-pipeline-and-output-as 115 | 116 | I believe that .Net 3.5 is a requirement for using the Linq libraries 117 | 118 | .FUNCTIONALITY 119 | General Command 120 | #> 121 | [CmdletBinding()] 122 | param ( 123 | [Parameter( Mandatory=$true, 124 | ValueFromPipeline=$true, 125 | ValueFromPipelineByPropertyName=$false)] 126 | [string]$HTML, 127 | 128 | [Parameter( Mandatory=$false, 129 | ValueFromPipeline=$false)] 130 | [String]$Column="Name", 131 | 132 | [Parameter( Mandatory=$false, 133 | ValueFromPipeline=$false)] 134 | $Argument=0, 135 | 136 | [Parameter( ValueFromPipeline=$false)] 137 | [ScriptBlock]$ScriptBlock = {[string]$args[0] -eq [string]$args[1]}, 138 | 139 | [Parameter( ValueFromPipeline=$false)] 140 | [String]$Attr = "style", 141 | 142 | [Parameter( Mandatory=$true, 143 | ValueFromPipeline=$false)] 144 | [String]$AttrValue, 145 | 146 | [Parameter( Mandatory=$false, 147 | ValueFromPipeline=$false)] 148 | [switch]$WholeRow=$false 149 | 150 | ) 151 | 152 | #requires -version 2.0 153 | add-type -AssemblyName System.xml.linq | out-null 154 | 155 | # Convert our data to x(ht)ml 156 | $xml = [System.Xml.Linq.XDocument]::Parse($HTML) 157 | 158 | #Get column index. try th with no namespace first, then default namespace provided by convertto-html 159 | try{ 160 | $columnIndex = (($xml.Descendants("th") | Where-Object { $_.Value -eq $Column }).NodesBeforeSelf() | Measure-Object).Count 161 | } 162 | catch { 163 | Try { 164 | $columnIndex = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq $Column }).NodesBeforeSelf() | Measure-Object).Count 165 | } 166 | Catch { 167 | Throw "Error: Namespace incorrect." 168 | } 169 | } 170 | 171 | #if we got the column index... 172 | if($columnIndex -as [double] -ge 0){ 173 | 174 | #take action on td descendents matching that index 175 | switch($xml.Descendants("td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $columnIndex }) 176 | { 177 | #run the script block. If it is true, set attributes 178 | {$(Invoke-Command $ScriptBlock -ArgumentList @($_.Value, $Argument))} { 179 | 180 | #mark the whole row or just a cell depending on param 181 | if ($WholeRow) { 182 | $_.Parent.SetAttributeValue($Attr, $AttrValue) 183 | } 184 | else { 185 | $_.SetAttributeValue($Attr, $AttrValue) 186 | } 187 | } 188 | } 189 | } 190 | 191 | #return the XML 192 | $xml.Document.ToString() 193 | } --------------------------------------------------------------------------------