PSDevSummary.psm1
function Start-TimeLog { [CmdletBinding()] param() [System.Diagnostics.Stopwatch]::StartNew() } function Stop-TimeLog { [CmdletBinding()] param ([Parameter(ValueFromPipeline = $true)][System.Diagnostics.Stopwatch] $Time, [ValidateSet('OneLiner', 'Array')][string] $Option = 'OneLiner', [switch] $Continue) Begin { } Process { if ($Option -eq 'Array') { $TimeToExecute = "$($Time.Elapsed.Days) days", "$($Time.Elapsed.Hours) hours", "$($Time.Elapsed.Minutes) minutes", "$($Time.Elapsed.Seconds) seconds", "$($Time.Elapsed.Milliseconds) milliseconds" } else { $TimeToExecute = "$($Time.Elapsed.Days) days, $($Time.Elapsed.Hours) hours, $($Time.Elapsed.Minutes) minutes, $($Time.Elapsed.Seconds) seconds, $($Time.Elapsed.Milliseconds) milliseconds" } } End { if (-not $Continue) { $Time.Stop() } return $TimeToExecute } } function Write-Color { <# .SYNOPSIS Write-Color is a wrapper around Write-Host. It provides: - Easy manipulation of colors, - Logging output to file (log) - Nice formatting options out of the box. .DESCRIPTION Author: przemyslaw.klys at evotec.pl Project website: https://evotec.xyz/hub/scripts/write-color-ps1/ Project support: https://github.com/EvotecIT/PSWriteColor Original idea: Josh (https://stackoverflow.com/users/81769/josh) .EXAMPLE Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1 .EXAMPLE Write-Color "1. ", "Option 1" -Color Yellow, Green Write-Color "2. ", "Option 2" -Color Yellow, Green Write-Color "3. ", "Option 3" -Color Yellow, Green Write-Color "4. ", "Option 4" -Color Yellow, Green Write-Color "9. ", "Press 9 to exit" -Color Yellow, Gray -LinesBefore 1 .EXAMPLE Write-Color -LinesBefore 2 -Text "This little ","message is ", "written to log ", "file as well." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" -TimeFormat "yyyy-MM-dd HH:mm:ss" Write-Color -Text "This can get ","handy if ", "want to display things, and log actions to file ", "at the same time." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" .EXAMPLE # Added in 0.5 Write-Color -T "My text", " is ", "all colorful" -C Yellow, Red, Green -B Green, Green, Yellow wc -t "my text" -c yellow -b green wc -text "my text" -c red .NOTES CHANGELOG Version 0.5 (25th April 2018) ----------- - Added backgroundcolor - Added aliases T/B/C to shorter code - Added alias to function (can be used with "WC") - Fixes to module publishing Version 0.4.0-0.4.9 (25th April 2018) ------------------- - Published as module - Fixed small issues Version 0.31 (20th April 2018) ------------ - Added Try/Catch for Write-Output (might need some additional work) - Small change to parameters Version 0.3 (9th April 2018) ----------- - Added -ShowTime - Added -NoNewLine - Added function description - Changed some formatting Version 0.2 ----------- - Added logging to file Version 0.1 ----------- - First draft Additional Notes: - TimeFormat https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx #> [alias('Write-Colour')] [CmdletBinding()] param ([alias ('T')] [String[]]$Text, [alias ('C', 'ForegroundColor', 'FGC')] [ConsoleColor[]]$Color = [ConsoleColor]::White, [alias ('B', 'BGC')] [ConsoleColor[]]$BackGroundColor = $null, [alias ('Indent')][int] $StartTab = 0, [int] $LinesBefore = 0, [int] $LinesAfter = 0, [int] $StartSpaces = 0, [alias ('L')] [string] $LogFile = '', [Alias('DateFormat', 'TimeFormat')][string] $DateTimeFormat = 'yyyy-MM-dd HH:mm:ss', [alias ('LogTimeStamp')][bool] $LogTime = $true, [ValidateSet('unknown', 'string', 'unicode', 'bigendianunicode', 'utf8', 'utf7', 'utf32', 'ascii', 'default', 'oem')][string]$Encoding = 'Unicode', [switch] $ShowTime, [switch] $NoNewLine) $DefaultColor = $Color[0] if ($null -ne $BackGroundColor -and $BackGroundColor.Count -ne $Color.Count) { Write-Error "Colors, BackGroundColors parameters count doesn't match. Terminated."; return } if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host -Object "`n" -NoNewline } } if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host -Object "`t" -NoNewLine } } if ($StartSpaces -ne 0) { for ($i = 0; $i -lt $StartSpaces; $i++) { Write-Host -Object ' ' -NoNewLine } } if ($ShowTime) { Write-Host -Object "[$([datetime]::Now.ToString($DateTimeFormat))]" -NoNewline } if ($Text.Count -ne 0) { if ($Color.Count -ge $Text.Count) { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine } } else { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine } } } else { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -NoNewLine } } else { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackGroundColor[0] -NoNewLine } } } } if ($NoNewLine -eq $true) { Write-Host -NoNewline } else { Write-Host } if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host -Object "`n" -NoNewline } } if ($Text.Count -ne 0 -and $LogFile -ne "") { $TextToFile = "" for ($i = 0; $i -lt $Text.Length; $i++) { $TextToFile += $Text[$i] } try { if ($LogTime) { Write-Output -InputObject "[$([datetime]::Now.ToString($DateTimeFormat))]$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append } else { Write-Output -InputObject "$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append } } catch { $_.Exception } } } Function ConvertTo-Markdown { <# .Synopsis Converts a PowerShell object to a Markdown table. .Description Converts a PowerShell object to a Markdown table. .Parameter InputObject PowerShell object to be converted .Example ConvertTo-Markdown -InputObject (Get-Service) Converts a list of running services on the local machine to a Markdown table .Example ConvertTo-Markdown -InputObject (Import-CSV "C:\Scratch\lwsmachines.csv") | Out-File "C:\Scratch\file.markdown" -Encoding "ASCII" Converts a CSV file to a Markdown table .Example Import-CSV "C:\Scratch\lwsmachines.csv" | ConvertTo-Markdown | Out-File "C:\Scratch\file2.markdown" -Encoding "ASCII" Converts a CSV file to a markdown table via the pipeline. .Notes Ben Neise 10/09/14 #> [CmdletBinding()] [OutputType([string])] Param ( [Parameter(Mandatory, Position = 0, ValueFromPipeline)][PSObject[]]$collection ) Begin { $Items = [System.Collections.Generic.List[string]]::new() $columns = [ordered] @{ } } Process { ForEach ($item in $collection) { $items.Add($item) $item.PSObject.Properties | ForEach-Object { if ($null -eq $_.Value) { $_.Value = "" } if (-not $columns.Contains($_.Name) -or $columns[$_.Name] -lt $_.Value.ToString().Length) { $columns[$_.Name] = $_.Value.ToString().Length } } } } End { ForEach ($key in $($columns.Keys)) { $columns[$key] = [Math]::Max($columns[$key], $key.Length) } $header = ForEach ($key in $columns.Keys) { ('{0,-' + $columns[$key] + '}') -f $key } $($header -join ' | ') $separator = ForEach ($key in $columns.Keys) { '-' * $columns[$key] } $($separator -join ' | ') ForEach ($item in $items) { $values = ForEach ($key in $columns.Keys) { ('{0,-' + $columns[$key] + '}') -f $item.($key) } $($values -join ' | ') } } } function Get-DevSummary { [CmdletBinding()] param( [string] $Author, [string] $PathModuleDetails = "$Env:USERPROFILE\Desktop\ModulesDetails.xml", [string] $PathModules = "$Env:USERPROFILE\Desktop\Modules.xml", [string] $PathGitHub = "$Env:USERPROFILE\Desktop\GitHubModules.xml", [string] $PathModulesHTML = "$Env:USERPROFILE\Desktop\MyModules.HTML", [switch] $UseCache, [switch] $UseHTMLLinks, [switch] $UseUrlMarkdown, [switch] $ReturnDetails ) if ($UseCache -and (Test-Path -LiteralPath $PathModules)) { $AllModules = Import-Clixml -LiteralPath $PathModules } else { $AllModules = Find-Module -Verbose if ($UseCache) { $AllModules | Export-Clixml -LiteralPath $PathModules -Depth 5 } } if ($UseCache -and (Test-Path -LiteralPath $PathModuleDetails)) { $AllModulesDetails = Import-Clixml -LiteralPath $PathModuleDetails } else { $AllModulesDetails = [ordered] @{ } } if ($UseCache -and (Test-Path -LiteralPath $PathGitHub)) { $GitHubModules = Import-Clixml -LiteralPath $PathGitHub } else { $GitHubModules = [ordered] @{ } } if ($Author) { [Array] $MyModules = $AllModules | Where-Object { $_.Author -eq $Author } | Sort-Object Name } else { [Array] $MyModules = $AllModules | Sort-Object Name } $Objects = foreach ($_ in $MyModules) { $Time = Start-TimeLog Write-Color -Text "[i] ", "Generating stats for module ", $($_.Name) -NoNewLine -Color Yellow, DarkGray, Yellow if ($null -eq $AllModulesDetails[$_.Name]) { $AllModulesDetails[$_.Name] = Find-Module -Name $_.Name -AllVersions -AllowPrerelease } [Array] $Module = $AllModulesDetails[$_.Name] Write-Color -Text ' [Total Release Count: ', $Module.Count, '] ' -NoNewLine -Color Cyan, DarkGray, Cyan [Array] $InternalModules = foreach ($M in $Module) { $PublishedDate = try { [DateTime] $M.PublishedDate } catch { $M.PublishedDate; Write-Warning "Conversion failed for $($M.PublishedDate)" } [PSCustomObject] @{ Date = $PublishedDate Downloads = $M.AdditionalMetadata.versionDownloadCount } } [DateTime] $CurrentYear = (Get-Date) [int] $Year = $CurrentYear.Year [int] $LastYear = ($CurrentYear).AddYears(-1).Year [int] $PreviousYear = ($CurrentYear).AddYears(-2).Year [Array] $ModuleCurrentYear = $InternalModules | Where-Object { $_.Date.Year -eq $Year } [Array] $ModuleLastYear = $InternalModules | Where-Object { $_.Date.Year -eq $LastYear } [Array] $ModulePreviousYear = $InternalModules | Where-Object { $_.Date.Year -eq $PreviousYear } if ($null -eq $GitHubModules[$_.ProjectUri]) { try { $GitHubModules[$_.ProjectUri] = Get-GitHubRepository -Uri $_.ProjectUri } catch { $GitHubProject = $Null } } $GitHubProject = $GitHubModules[$_.ProjectUri] | Select-Object full_name, Name, Stargazers_Count, forks_count, Open_issues, license, Language, HTML_URL, Fork, Created_At, Updated_At, Pushed_At, Archived if ($UseHTMLLinks) { $Name = "<a href='$($_.ProjectUri)' target='_blank'>$($_.Name)</a>" $PSGalleryURL = "<a href='https://www.powershellgallery.com/packages/$($_.Name)' target='_blank'>https://www.powershellgallery.com/packages/$($_.Name)</a>" $GitHubURL = "<a href='$($_.ProjectUri)' target='_blank'>$($_.ProjectUri)</a>" } elseif ($UseUrlMarkdown) { $Name = "[$($_.Name)]($($_.ProjectUri))" } else { $Name = $_.Name $PSGalleryURL = "https://www.powershellgallery.com/packages/$($_.Name)" $GitHubURL = $_.ProjectUri } $Object = [ordered] @{ 'Name' = $Name 'Type' = $_.Type 'GitHub Stars' = $GitHubProject.Stargazers_Count 'GitHub Forks' = $GitHubProject.forks_count 'GitHub Open Issues' = $GitHubProject.Open_issues 'GitHub Archived' = $GitHubProject.Archived 'GitHub Created' = $GitHubProject.Created_At 'GitHub Updated' = $GitHubProject.Updated_At # This is a bug in Find-Module where without parameters is the same # https://github.com/PowerShell/PowerShellGet/issues/563 'Download CountTotal' = $Module[0].AdditionalMetadata.downloadCount #$_.AdditionalMetadata.downloadCount 'Download CountLast' = $Module[0].AdditionalMetadata.versionDownloadCount #$_.AdditionalMetadata.versionDownloadCount 'Releases Total' = $Module.Count "Releases CurrentYear ($Year)" = $ModuleCurrentYear.Count "Releases LastYear ($LastYear)" = $ModuleLastYear.Count "Releases PreviousYear ($PreviousYear)" = $ModulePreviousYear.Count 'Last Updated' = $_.AdditionalMetadata.published 'PS Gallery Url' = $PSGalleryURL #'Project Url' = $GitHubURL 'Description' = $_.Description } if ($ReturnDetails) { $Object.'Modules' = $Module } $EndTime = Stop-TimeLog -Time $Time -Option OneLiner Write-Color -Text ' [Time to gather data: ', $EndTime, ']' -Color Cyan, DarkGray, Cyan [PSCustomObject] $Object } if ($UseCache) { $AllModulesDetails | Export-Clixml -LiteralPath $PathModuleDetails -Depth 5 $GitHubModules | Export-Clixml -LiteralPath $PathGitHub -Depth 5 } $Objects } function Get-PowerShellGitHubModules { [CmdletBinding()] param( [string] $Owner = 'EvotecIT' ) $GitHubModules = Get-GitHubRepository -OwnerName $Owner #$GitHubModules | Sort-Object Stargazers_Count -Descending | Format-Table full_name, Name, Stargazers_Count, forks_count, Open_issues, license, Language, HTML_URL, Fork, Created_At, Updated_At, Pushed_At, Archived -AutoSize foreach ($_ in $GitHubModules) { [PSCustomObject] @{ 'Name' = $_.Name 'Full Name' = $_.full_name 'Stars' = $_.Stargazers_Count 'Forks' = $_.forks_count 'Issues' = $_.Open_issues 'License' = $_.license.Name 'Language' = $_.Language 'Uri' = $_.HTML_URL 'Is Fork' = $_.Fork 'Created' = $_.Created_At 'Updated' = $_.Updated_At 'Archived' = $_.Archived } } } Export-ModuleMember -Function @('Get-DevSummary', 'Get-PowerShellGitHubModules') -Alias @() |