Merge pull request #1 from dfinke/master

Update
This commit is contained in:
Wes Stahler
2020-02-11 08:24:41 -05:00
committed by GitHub
336 changed files with 50030 additions and 6458 deletions

11
.gitignore vendored
View File

@@ -2,6 +2,8 @@
Thumbs.db
ehthumbs.db
*.gitignore
# Folder config file
Desktop.ini
@@ -14,6 +16,8 @@ $RECYCLE.BIN/
*.msm
*.msp
*.dll
# Windows shortcuts
*.lnk
@@ -42,6 +46,7 @@ Network Trash Folder
Temporary Items
.apdisk
testExport.xlsx
test.xlsx
test.ps1
testPwd.xlsx
test.csv
@@ -55,4 +60,8 @@ test.xlsx
testCCFMT.ps1
testHide.ps1
ImportExcel.zip
*.xlsx
.vscode/settings.json
~$*
# InstallModule.ps1
# PublishToGallery.ps1

56
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,56 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Pester Tests",
"script": "Import-Module -Name '.\\' -Force ; Invoke-Pester", // Change to '.\\ModuleName.psd1' if Git name different
"args": [""],
"cwd": "${workspaceFolder}"
},
{
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Launch Current File",
"script": "${file}",
"args": [],
"cwd": "${file}"
},
{
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Launch Current File in Temporary Console",
"script": "${file}",
"args": [],
"cwd": "${file}",
"createTemporaryIntegratedConsole": true
},
{
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Launch Current File w/Args Prompt",
"script": "${file}",
"args": [
"${command:SpecifyScriptArgs}"
],
"cwd": "${file}"
},
{
"type": "PowerShell",
"request": "attach",
"name": "PowerShell Attach to Host Process",
"processId": "${command:PickPSHostProcess}",
"runspaceId": 1
},
{
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Interactive Session",
"cwd": ""
}
]
}

37
.vscode/spellright.dict vendored Normal file
View File

@@ -0,0 +1,37 @@
databar
appveyor
SqlDataToExcel
xlsm
jameseholt
params
robinmalik
scriptblock
headsphere
xelsirko
importexcel
Mihalicz
idx
Möller
redoz
dir
pivotables
WorkSheetname
Lachance-Guillemette
ints
pscookiemonster
ps
pwd
Nuget
EPPLus
intellisense
PivtoTableName
New-Excelchart
paypal
dll
enums
Numberformat
ChartDefiniton
hashtables
Agramont
AGramont
Jhoneill

View File

@@ -1,117 +0,0 @@
Function Add-ConditionalFormatting {
<#
.Synopsis
Adds contitional formatting to worksheet
.Example
$excel = $avdata | Export-Excel -Path (Join-path $FilePath "\Machines.XLSX" ) -WorksheetName "Server Anti-Virus" -AutoSize -FreezeTopRow -AutoFilter -PassThru
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "b":b1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "2003"
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "i2:i1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "Disabled"
$excel.Workbook.Worksheets[1].Cells["D1:G1048576"].Style.Numberformat.Format = [cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
$excel.Workbook.Worksheets[1].Row(1).style.font.bold = $true
$excel.Save() ; $excel.Dispose()
Here Export-Excel is called with the -passThru parameter so the Excel Package object is stored in $Excel
The desired worksheet is selected and the then columns B and i are conditially formatted (excluding the top row) to show
Fixed formats are then applied to dates in columns D..G and the top row is formatted
Finally the workbook is saved and the Excel closed.
#>
Param (
#The worksheet where the format is to be applied
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
#The area of the worksheet where the format is to be applied
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[OfficeOpenXml.ExcelAddress]$Range ,
#One or more row(s), Column(s) and/or block(s) of cells to format
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
$Address ,
#One of the standard named rules - Top / Bottom / Less than / Greater than / Contains etc
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 3)]
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress", Position = 3)]
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
#Text colour for matching objects
[Alias("ForeGroundColour")]
[System.Drawing.Color]$ForeGroundColor,
#colour for databar type charts
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
[Alias("DataBarColour")]
[System.Drawing.Color]$DataBarColor,
#One of the three-icon set types (e.g. Traffic Lights)
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting3IconsSetType]$ThreeIconsSet,
#A four-icon set name
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting4IconsSetType]$FourIconsSet,
#A five-icon set name
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
#A value for the condition (e.g. "2000" if the test is 'lessthan 2000')
[string]$ConditionValue,
#A second value for the conditions like between x and Y
[string]$ConditionValue2,
#Background colour for matching items
[System.Drawing.Color]$BackgroundColor,
#Background pattern for matching items
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid,
#Secondary colour when a background pattern requires it
[System.Drawing.Color]$PatternColor,
#Sets the numeric format for matching items
$NumberFormat,
#Put matching items in bold face
[switch]$Bold,
#Put matching items in italic
[switch]$Italic,
#Underline matching items
[switch]$Underline,
#Strikethrough text of matching items
[switch]$StrikeThru
)
#Allow add conditional formatting to work like Set-Format (with single ADDRESS parameter) split it to get worksheet and Range of cells.
If ($Address -and -not $WorkSheet -and -not $Range) {
$WorkSheet = $Address.Worksheet[0]
$Range = $Address.Address
}
If ($ThreeIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Range , $ThreeIconsSet)}
elseif ($FourIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Range , $FourIconsSet) }
elseif ($FiveIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Range , $IconType) }
elseif ($DataBarColor) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Range , $DataBarColor) }
else { $rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Range)}
if ($ConditionValue -and $RuleType -match "Top|Botom") {$rule.Rank = $ConditionValue }
if ($ConditionValue -and $RuleType -match "StdDev") {$rule.StdDev = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Than|Equal|Expression") {$rule.Formula = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Text|With") {$rule.Text = $ConditionValue }
if ($ConditionValue -and
$ConditionValue2 -and $RuleType -match "Between") {
$rule.Formula = $ConditionValue
$rule.Formula2 = $ConditionValue2
}
if ($NumberFormat) {$rule.Style.NumberFormat.Format = $NumberFormat }
if ($Underline) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
if ($Bold) {$rule.Style.Font.Bold = $true}
if ($Italic) {$rule.Style.Font.Italic = $true}
if ($StrikeThru) {$rule.Style.Font.Strike = $true}
if ($ForeGroundColor) {$rule.Style.Font.Color.color = $ForeGroundColor }
if ($BackgroundColor) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
if ($BackgroundPattern) {$rule.Style.Fill.PatternType = $BackgroundPattern }
if ($PatternColor) {$rule.Style.Fill.PatternColor.color = $PatternColor }
}

208
CI/CI.ps1 Normal file
View File

@@ -0,0 +1,208 @@
<#
.SYNOPSIS
Handel Continuous Integration Testing in AppVeyor and Azure DevOps Pipelines.
#>
param
(
# AppVeyor Only - Update AppVeyor build name.
[Switch]$Initialize,
# Installs the module and invoke the Pester tests with the current version of PowerShell.
[Switch]$Test,
# AppVeyor Only - Upload results to AppVeyor "Tests" tab.
[Switch]$Finalize,
# AppVeyor and Azure - Upload module as AppVeyor Artifact.
[Switch]$Artifact,
# Azure - Runs PsScriptAnalyzer against one or more folders and pivots the results to form a report.
[Switch]$Analyzer
)
$ErrorActionPreference = 'Stop'
if ($Initialize) {
$Psd1 = (Get-ChildItem -File -Filter *.psd1 -Name -Path (Split-Path $PSScriptRoot)).PSPath
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path $Psd1 | Out-String)))).ModuleVersion
Update-AppveyorBuild -Version "$ModuleVersion ($env:APPVEYOR_BUILD_NUMBER) $env:APPVEYOR_REPO_BRANCH"
}
if ($Test) {
function Get-EnvironmentInfo {
if ([environment]::OSVersion.Platform -like "win*") {
# Get Windows Version
try {
$WinRelease, $WinVer = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ReleaseId, CurrentMajorVersionNumber, CurrentMinorVersionNumber, CurrentBuildNumber, UBR
$WindowsVersion = "$($WinVer -join '.') ($WinRelease)"
}
catch {
$WindowsVersion = [System.Environment]::OSVersion.Version
}
#TODO FIXME BUG this gets the latest version of the .NET Framework on the machine (ok for powershell.exe), not the version of .NET CORE in use by PWSH.EXE
<#
$VersionFilePath = (Get-Process -Id $PID | Select-Object -ExpandProperty Modules |
Where-Object -Property modulename -eq "clrjit.dll").FileName
if (-not $VersionFilePath) {
$VersionFilePath = [System.Reflection.Assembly]::LoadWithPartialName("System.Core").location
}
(Get-ItemProperty -Path $VersionFilePath).VersionInfo |
Select-Object -Property @{n="Version"; e={$_.ProductName + " " + $_.FileVersion}}, ProductName, FileVersionRaw, FileName
#>
# Get .Net Version
# https://stackoverflow.com/questions/3487265/powershell-script-to-return-versions-of-net-framework-on-a-machine
$Lookup = @{
378389 = [version]'4.5'
378675 = [version]'4.5.1'
378758 = [version]'4.5.1'
379893 = [version]'4.5.2'
393295 = [version]'4.6'
393297 = [version]'4.6'
394254 = [version]'4.6.1'
394271 = [version]'4.6.1'
394802 = [version]'4.6.2'
394806 = [version]'4.6.2'
460798 = [version]'4.7'
460805 = [version]'4.7'
461308 = [version]'4.7.1'
461310 = [version]'4.7.1'
461808 = [version]'4.7.2'
461814 = [version]'4.7.2'
528040 = [version]'4.8'
528049 = [version]'4.8'
}
# For One True framework (latest .NET 4x), change the Where-Object match
# to PSChildName -eq "Full":
$DotNetVersion = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -name Version, Release -EA 0 |
Where-Object { $_.PSChildName -eq "Full" } |
Select-Object @{name = ".NET Framework"; expression = { $_.PSChildName } },
@{name = "Product"; expression = { $Lookup[$_.Release] } },
Version, Release
# Output
[PSCustomObject]($PSVersionTable + @{
ComputerName = $env:Computername
WindowsVersion = $WindowsVersion
'.Net Version' = '{0} (Version: {1}, Release: {2})' -f $DotNetVersion.Product, $DotNetVersion.Version, $DotNetVersion.Release
#EnvironmentPath = $env:Path
})
}
else {
# Output
[PSCustomObject]($PSVersionTable + @{
ComputerName = $env:Computername
#EnvironmentPath = $env:Path
})
}
}
'[Info] Testing On:'
Get-EnvironmentInfo
'[Progress] Installing Module.'
. .\CI\Install.ps1
'[Progress] Invoking Pester.'
Invoke-Pester -OutputFile ('TestResultsPS{0}.xml' -f $PSVersionTable.PSVersion)
}
if ($Finalize) {
'[Progress] Finalizing.'
$Failure = $false
$AppVeyorResultsUri = 'https://ci.appveyor.com/api/testresults/nunit/{0}' -f $env:APPVEYOR_JOB_ID
foreach ($TestResultsFile in Get-ChildItem -Path 'TestResultsPS*.xml') {
$TestResultsFilePath = $TestResultsFile.FullName
"[Info] Uploading Files: $AppVeyorResultsUri, $TestResultsFilePath."
# Add PowerShell version to test results
$PSVersion = $TestResultsFile.Name.Replace('TestResults', '').Replace('.xml', '')
[Xml]$Xml = Get-Content -Path $TestResultsFilePath
Select-Xml -Xml $Xml -XPath '//test-case' | ForEach-Object { $_.Node.name = "$PSVersion " + $_.Node.name }
$Xml.OuterXml | Out-File -FilePath $TestResultsFilePath
#Invoke-RestMethod -Method Post -Uri $AppVeyorResultsUri -Body $Xml
[Net.WebClient]::new().UploadFile($AppVeyorResultsUri, $TestResultsFilePath)
if ($Xml.'test-results'.failures -ne '0') {
$Failure = $true
}
}
if ($Failure) {
throw 'Tests failed.'
}
}
if ($Artifact) {
# Get Module Info
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path (Split-Path $PSScriptRoot)))
$ModulePath = (Get-Module -Name $ModuleName -ListAvailable).ModuleBase | Split-Path
$VersionLocal = ((Get-Module -Name $ModuleName -ListAvailable).Version | Measure-Object -Maximum).Maximum
"[Progress] Artifact Start for Module: $ModuleName, Version: $VersionLocal."
if ($env:APPVEYOR) {
$ZipFileName = "{0} {1} {2} {3:yyyy-MM-dd HH-mm-ss}.zip" -f $ModuleName, $VersionLocal, $env:APPVEYOR_REPO_BRANCH, (Get-Date)
$ZipFileFullPath = Join-Path -Path $PSScriptRoot -ChildPath $ZipFileName
"[Info] Artifact. $ModuleName, ZipFileName: $ZipFileName."
#Compress-Archive -Path $ModulePath -DestinationPath $ZipFileFullPath
[System.IO.Compression.ZipFile]::CreateFromDirectory($ModulePath, $ZipFileFullPath, [System.IO.Compression.CompressionLevel]::Optimal, $true)
Push-AppveyorArtifact $ZipFileFullPath -DeploymentName $ModuleName
}
elseif ($env:AGENT_NAME) {
#Write-Host "##vso[task.setvariable variable=ModuleName]$ModuleName"
Copy-Item -Path $ModulePath -Destination $env:Build_ArtifactStagingDirectory -Recurse
}
}
if ($Analyzer) {
if (!(Get-Module -Name PSScriptAnalyzer -ListAvailable)) {
'[Progress] Installing PSScriptAnalyzer.'
Install-Module -Name PSScriptAnalyzer -Force
}
if ($env:System_PullRequest_TargetBranch) {
'[Progress] Get target branch.'
$TempGitClone = Join-Path ([IO.Path]::GetTempPath()) (New-Guid)
Copy-Item -Path $PWD -Destination $TempGitClone -Recurse
(Get-Item (Join-Path $TempGitClone '.git')).Attributes += 'Hidden'
"[Progress] git clean."
git -C $TempGitClone clean -f
"[Progress] git reset."
git -C $TempGitClone reset --hard
"[Progress] git checkout."
git -C $TempGitClone checkout -q $env:System_PullRequest_TargetBranch
$DirsToProcess = @{ 'Pull Request' = $PWD ; $env:System_PullRequest_TargetBranch = $TempGitClone }
}
else {
$DirsToProcess = @{ 'GitHub' = $PWD }
}
"[Progress] Running Script Analyzer."
$AnalyzerResults = $DirsToProcess.GetEnumerator() | ForEach-Object {
$DirName = $_.Key
Write-Verbose "[Progress] Running Script Analyzer on $DirName."
Invoke-ScriptAnalyzer -Path $_.Value -Recurse -ErrorAction SilentlyContinue |
Add-Member -MemberType NoteProperty -Name Location -Value $DirName -PassThru
}
if ($AnalyzerResults) {
if (!(Get-Module -Name ImportExcel -ListAvailable)) {
'[Progress] Installing ImportExcel.'
Install-Module -Name ImportExcel -Force
}
'[Progress] Creating ScriptAnalyzer.xlsx.'
$ExcelParams = @{
Path = 'ScriptAnalyzer.xlsx'
WorksheetName = 'FullResults'
Now = $true
Activate = $true
Show = $false
}
$PivotParams = @{
PivotTableName = 'BreakDown'
PivotData = @{RuleName = 'Count' }
PivotRows = 'Severity', 'RuleName'
PivotColumns = 'Location'
PivotTotals = 'Rows'
}
Remove-Item -Path $ExcelParams['Path'] -ErrorAction SilentlyContinue
$PivotParams['PivotChartDefinition'] = New-ExcelChartDefinition -ChartType 'BarClustered' -Column (1 + $DirsToProcess.Count) -Title "Script analysis" -LegendBold
$ExcelParams['PivotTableDefinition'] = New-PivotTableDefinition @PivotParams
$AnalyzerResults | Export-Excel @ExcelParams
'[Progress] Analyzer finished.'
}
else {
"[Info] Invoke-ScriptAnalyzer didn't return any problems."
}
}

191
CI/Install.ps1 Normal file
View File

@@ -0,0 +1,191 @@
<#
.SYNOPSIS
Installs module from Git clone or directly from GitHub.
File must not have BOM for GitHub deploy to work.
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
param(
# Path to install the module to, if not provided -Scope used.
[Parameter(Mandatory, ParameterSetName = 'ModulePath')]
[ValidateNotNullOrEmpty()]
[String]$ModulePath,
# Path to install the module to, PSModulePath "CurrentUser" or "AllUsers", if not provided "CurrentUser" used.
[Parameter(Mandatory, ParameterSetName = 'Scope')]
[ValidateSet('CurrentUser', 'AllUsers')]
[string]
$Scope = 'CurrentUser',
# Get module from GitHub instead of local Git clone, for example "https://raw.githubusercontent.com/ili101/Module.Template/master/Install.ps1"
[ValidateNotNullOrEmpty()]
[Uri]$FromGitHub
)
# Set Files and Folders patterns to Include/Exclude.
$IncludeFiles = @(
'EPPlus.dll',
'*.psd1',
'*.psm1',
'*.ps1'
'Charting',
'en-US',
'Examples',
'Public',
'Private',
'images',
'InferData',
'InternalFunctions',
'Pivot',
'spikes',
'Testimonials',
'README.md',
'LICENSE.txt'
)
$ExcludeFiles = @(
'Install.ps1',
'InstallModule.ps1',
'PublishToGallery.PS1'
)
function Invoke-MultiLike {
[alias("LikeAny")]
[CmdletBinding()]
param
(
$InputObject,
[Parameter(Mandatory)]
[String[]]$Filters,
[Switch]$Not
)
$FiltersRegex = foreach ($Filter In $Filters) {
$Filter = [regex]::Escape($Filter)
if ($Filter -match "^\\\*") {
$Filter = $Filter.Remove(0, 2)
}
else {
$Filter = '^' + $Filter
}
if ($Filter -match "\\\*$") {
$Filter = $Filter.Substring(0, $Filter.Length - 2)
}
else {
$Filter = $Filter + '$'
}
$Filter
}
if ($Not) {
$InputObject -notmatch ($FiltersRegex -join '|').replace('\*', '.*').replace('\?', '.')
}
else {
$InputObject -match ($FiltersRegex -join '|').replace('\*', '.*').replace('\?', '.')
}
}
Push-Location "$PSScriptRoot\.."
try {
Write-Verbose -Message "Module installation started. Installing from $PWD"
if (!$ModulePath) {
if ($Scope -eq 'CurrentUser') {
$ModulePathIndex = 0
}
else {
$ModulePathIndex = 1
}
if ($IsLinux -or $IsMacOS) {
$ModulePathSeparator = ':'
}
else {
$ModulePathSeparator = ';'
}
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator)[$ModulePathIndex]
}
Write-Verbose -Message "Installing to $ModulePath"
# Get $ModuleName, $TargetPath, [$Links]
if ($FromGitHub) {
# Fix Could not create SSL/TLS secure channel
#$SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$WebClient = [System.Net.WebClient]::new()
$GitUri = $FromGitHub.AbsolutePath.Split('/')[1, 2] -join '/'
$GitBranch = $FromGitHub.AbsolutePath.Split('/')[3]
$Links = (Invoke-RestMethod -Uri "https://api.github.com/repos/$GitUri/contents" -Body @{ref = $GitBranch }) | Where-Object { (LikeAny $_.name $IncludeFiles) -and (LikeAny $_.name $ExcludeFiles -Not) }
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension(($Links | Where-Object { $_.name -like '*.psm1' }).name)
$ModuleVersion = (. ([Scriptblock]::Create((Invoke-WebRequest -Uri ($Links | Where-Object { $_.name -eq "$ModuleName.psd1" }).download_url)))).ModuleVersion
}
else {
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path $PWD))
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path (Join-Path $PWD "$ModuleName.psd1") | Out-String)))).ModuleVersion
}
$TargetPath = Join-Path -Path $ModulePath -ChildPath $ModuleName
$TargetPath = Join-Path -Path $TargetPath -ChildPath $ModuleVersion
# Create Directory
if (-not (Test-Path -Path $TargetPath)) {
$null = New-Item -Path $TargetPath -ItemType Directory -ErrorAction Stop
Write-Verbose -Message ('Created module folder: "{0}"' -f $TargetPath)
}
# Copy Files
if ($FromGitHub) {
foreach ($Link in $Links) {
$TargetPathItem = Join-Path -Path $TargetPath -ChildPath $Link.name
if ($Link.type -ne 'dir') {
$WebClient.DownloadFile($Link.download_url, $TargetPathItem)
Write-Verbose -Message ('Installed module file: "{0}"' -f $Link.name)
}
else {
if (-not (Test-Path -Path $TargetPathItem)) {
$null = New-Item -Path $TargetPathItem -ItemType Directory -ErrorAction Stop
Write-Verbose -Message 'Created module folder: "{0}"' -f $TargetPathItem
}
$SubLinks = (Invoke-RestMethod -Uri $Link.git_url -Body @{recursive = '1' }).tree
foreach ($SubLink in $SubLinks) {
$TargetPathSub = Join-Path -Path $TargetPathItem -ChildPath $SubLink.path
if ($SubLink.'type' -EQ 'tree') {
if (-not (Test-Path -Path $TargetPathSub)) {
$null = New-Item -Path $TargetPathSub -ItemType Directory -ErrorAction Stop
Write-Verbose -Message 'Created module folder: "{0}"' -f $TargetPathSub
}
}
else {
$WebClient.DownloadFile(
('https://raw.githubusercontent.com/{0}/{1}/{2}/{3}' -f $GitUri, $GitBranch, $Link.name, $SubLink.path),
$TargetPathSub
)
}
}
}
}
}
else {
Get-ChildItem -Path $PWD -Exclude $ExcludeFiles | Where-Object { LikeAny $_.Name $IncludeFiles } | ForEach-Object {
if ($_.Attributes -ne 'Directory') {
Copy-Item -Path $_ -Destination $TargetPath
Write-Verbose -Message ('Installed module file "{0}"' -f $_)
}
else {
Copy-Item -Path $_ -Destination $TargetPath -Recurse -Force
Write-Verbose -Message ('Installed module folder "{0}"' -f $_)
}
}
}
# Import Module
Write-Verbose -Message "$ModuleName module installation successful to $TargetPath"
Import-Module -Name $ModuleName -Force
Write-Verbose -Message "Module installed"
}
catch {
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
}
finally {
#if ($FromGitHub) {
# [Net.ServicePointManager]::SecurityProtocol = $SecurityProtocol
#}
Write-Verbose -Message 'Module installation end'
Pop-Location
}

30
CI/InstallPowerShell.ps1 Normal file
View File

@@ -0,0 +1,30 @@
<#
.SYNOPSIS
Installs PowerShell Core on Windows.
#>
[CmdLetBinding()]
Param
(
# Version to install in the format from the .msi, for example "7.0.0-preview.1"
[String]$Version
)
$ErrorActionPreference = 'Stop'
if (-not $Version) {
$Version = (Invoke-RestMethod https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json).StableReleaseTag
}
$Version = $Version -replace "^v",""
'[Progress] Downloading PowerShell Core.'
$MsiPath = Join-Path $env:TEMP "PowerShell-$Version-win-x64.msi"
[System.Net.WebClient]::new().DownloadFile("https://github.com/PowerShell/PowerShell/releases/download/v$Version/PowerShell-$Version-win-x64.msi", $MsiPath)
'[Progress] Installing PowerShell Core.'
Start-Process 'msiexec.exe' -Wait -ArgumentList "/i $MsiPath /quiet"
Remove-Item -Path $MsiPath
$PowerShellFolder = $Version[0]
if ($Version -like "*preview*") {
$PowerShellFolder += '-preview'
}
$env:Path = "$env:ProgramFiles\PowerShell\$PowerShellFolder;$env:Path"
'[Progress] PowerShell Core Installed.'

255
CI/PS-CI.ps1 Normal file
View File

@@ -0,0 +1,255 @@
[cmdletbinding(DefaultParameterSetName='Scope')]
Param(
[Parameter(Mandatory = $true, ParameterSetName = 'ModulePath')]
[ValidateNotNullOrEmpty()]
[String]$ModulePath,
# Path to install the module to, PSModulePath "CurrentUser" or "AllUsers", if not provided "CurrentUser" used.
[Parameter(ParameterSetName = 'Scope')]
[ValidateSet('CurrentUser', 'AllUsers')]
[string]
$Scope = 'CurrentUser',
[Parameter(Mandatory=$true, ParameterSetName = 'PreCheckOnly')]
[switch]$PreCheckOnly,
[Parameter(ParameterSetName = 'ModulePath')]
[Parameter(ParameterSetName = 'Scope')]
[switch]$SkipPreChecks,
[Parameter(ParameterSetName = 'ModulePath')]
[Parameter(ParameterSetName = 'Scope')]
[switch]$SkipPostChecks,
[Parameter(ParameterSetName = 'ModulePath')]
[Parameter(ParameterSetName = 'Scope')]
[switch]$SkipPesterTests,
[Parameter(ParameterSetName = 'ModulePath')]
[Parameter(ParameterSetName = 'Scope')]
[switch]$SkipHelp,
[Parameter(ParameterSetName = 'ModulePath')]
[Parameter(ParameterSetName = 'Scope')]
[switch]$CleanModuleDir
)
Function Show-Warning {
param(
[Parameter(Position=0,ValueFromPipeline=$true)]
$message
)
process {
write-output "##vso[task.logissue type=warning]File $message"
$message >> $script:warningfile
}
}
if ($PSScriptRoot) {
$workingdir = Split-Path -Parent $PSScriptRoot
Push-Location $workingdir
}
$psdpath = Get-Item "*.psd1"
if (-not $psdpath -or $psdpath.count -gt 1) {
if ($PSScriptRoot) { Pop-Location }
throw "Did not find a unique PSD file "
}
else {
try {$null = Test-ModuleManifest -Path $psdpath -ErrorAction stop}
catch {throw $_ ; return}
$ModuleName = $psdpath.Name -replace '\.psd1$' , ''
$Settings = $(& ([scriptblock]::Create(($psdpath | Get-Content -Raw))))
$approvedVerbs = Get-Verb | Select-Object -ExpandProperty verb
$script:warningfile = Join-Path -Path $pwd -ChildPath "warnings.txt"
}
#pre-build checks - manifest found, files in it found, public functions and aliases loaded in it. Public functions correct.
if (-not $SkipPreChecks) {
#Check files in the manifest are present
foreach ($file in $Settings.FileList) {
if (-not (Test-Path $file)) {
Show-Warning "File $file in the manifest file list is not present"
}
}
#Check files in public have Approved_verb-noun names and are 1 function using the file name as its name with
# its name and any alias names in the manifest; function should have a param block and help should be in an MD file
# We will want a regex which captures from "function verb-noun {" to its closing "}"
# need to match each { to a } - $reg is based on https://stackoverflow.com/questions/7898310/using-regex-to-balance-match-parenthesis
$reg = [Regex]::new(@"
function\s*[-\w]+\s*{ # The function name and opening '{'
(?:
[^{}]+ # Match all non-braces
|
(?<open> { ) # Match '{', and capture into 'open'
|
(?<-open> } ) # Match '}', and delete the 'open' capture
)*
(?(open)(?!)) # Fails if 'open' stack isn't empty
} # Functions closing '}'
"@, 57) # 57 = compile,multi-line ignore case and white space.
foreach ($file in (Get-Item .\Public\*.ps1)) {
$name = $file.name -replace(".ps1","")
if ($name -notmatch ("(\w+)-\w+")) {Show-Warning "$name in the public folder is not a verb-noun name"}
elseif ($Matches[1] -notin $approvedVerbs) {Show-Warning "$name in the public folder does not start with an approved verb"}
if(-not ($Settings.FunctionsToExport -ceq $name)) {
Show-Warning ('File {0} in the public folder does not match an exported function in the manifest' -f $file.name)
}
else {
$fileContent = Get-Content $file -Raw
$m = $reg.Matches($fileContent)
if ($m.Count -eq 0) {Show-Warning ('Could not find {0} function in {1}' -f $name, $file.name); continue}
elseif ($m.Count -ge 2) {Show-Warning ('Multiple functions in {0}' -f $item.name) ; Continue}
elseif ($m[0] -imatch "^\function\s" -and
$m[0] -cnotmatch "^\w+\s+$name") {Show-Warning ('function name does not match file name for {0}' -f $file.name)}
#$m[0] runs form the f of function to its final } -find the section up to param, check for aliases & comment-based help
$m2 = [regex]::Match($m[0],"^.*?param",17) # 17 = multi-line, ignnore case
if (-not $m2.Success) {Show-Warning "function $name has no param() block"}
else {
if ($m2.value -match "(?<!#\s*)\[\s*Alias\(\s*.([\w-]+).\s*\)\s*\]") {
foreach ($a in ($Matches[1] -split '\s*,\s*')) {
$a = $a -replace "'","" -replace '"',''
if (-not ($Settings.AliasesToExport -eq $a)) {
Show-Warning "Function $name has alias $a which is not in the manifest"
}
}
}
if ($m2.value -match "\.syopsis|\.Description|\.Example") {
Show-Warning "Function $name appears to have comment based help."
}
}
}
}
#Warn about functions which are exported but not found in public
$notFromPublic = $Settings.FunctionsToExport.Where({-not (Test-Path ".\public\$_.ps1")})
If ($notFromPublic) {Show-Warning ('Exported function(s) {0} are not loaded from the Public folder' -f ($notFromPublic -join ', '))}
}
if ($PreCheckOnly) {return}
#region build, determine module path if necessary, create target directory if necessary, copy files based on manifest, build help
try {
if ($ModulePath) {
$ModulePath = $ModulePath -replace "\\$|/$",""
}
else {
if ($IsLinux -or $IsMacOS) {$ModulePathSeparator = ':' }
else {$ModulePathSeparator = ';' }
if ($Scope -eq 'CurrentUser') {$dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) }
else {$dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFiles) }
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator).where({$_ -like "$dir*"},"First",1)
$ModulePath = Join-Path -Path $ModulePath -ChildPath $ModuleName
$ModulePath = Join-Path -Path $ModulePath -ChildPath $Settings.ModuleVersion
}
# Clean-up / Create Directory
if (-not (Test-Path -Path $ModulePath)) {
$null = New-Item -Path $ModulePath -ItemType Directory -ErrorAction Stop
'Created module folder: "{0}"' -f $ModulePath
}
elseif ($CleanModuleDir) {
'{0} exists - cleaning before copy' -f $ModulePath
Get-ChildItem -Path $ModulePath | Remove-Item -Force -Recurse
}
'Copying files to: "{0}"' -f $ModulePath
$outputFile = $psdpath | Copy-Item -Destination $ModulePath -PassThru
$outputFile.fullname
foreach ($file in $Settings.FileList) {
if ($file -like '.\*') {
$dest = ($file -replace '\.\\',"$ModulePath\")
if (-not (Test-Path -PathType Container (Split-Path -Parent $dest))) {
$null = New-item -Type Directory -Path (Split-Path -Parent $dest)
}
}
else {$dest = $ModulePath }
Copy-Item -Path $file -Destination $dest -Force -Recurse
}
if ((Test-Path -PathType Container "mdHelp") -and -not $SkipHelp) {
if (-not (Get-Module -ListAvailable platyPS)) {
'Installing Platyps to build help files'
Install-Module -Name platyPS -Force -SkipPublisherCheck
}
$platypsInfo = Import-Module platyPS -PassThru -force
Get-ChildItem .\mdHelp -Directory | ForEach-Object {
'Building help for language ''{0}'', using {1} V{2}.' -f $_.Name,$platypsInfo.Name, $platypsInfo.Version
$Null = New-ExternalHelp -Path $_.FullName -OutputPath (Join-Path $ModulePath $_.Name) -Force
}
}
#Leave module path for things which follow.
$env:PSNewBuildModule = $ModulePath
}
catch {
if ($PSScriptRoot) { Pop-Location }
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
}
finally {
if (-not $outputFile -or -not (Test-Path $outputFile)) { throw "Failed to create module"}
}
#endregion
if ($env:Build_ArtifactStagingDirectory) {
Copy-Item -Path (split-path -Parent $ModulePath) -Destination $env:Build_ArtifactStagingDirectory -Recurse
}
#Check valid command names, help, run script analyzer over the files in the module directory
if (-not $SkipPostChecks) {
try {$outputFile | Import-Module -Force -ErrorAction stop }
catch {
if ($PSScriptRoot) { Pop-Location }
throw "New module failed to load"
}
$commands = Get-Command -Module $ModuleName -CommandType function,Cmdlet
$commands.where({$_.name -notmatch "(\w+)-\w+" -or $Matches[1] -notin $approvedVerbs}) | ForEach-Object {
Show-Warning ('{0} does not meet the ApprovedVerb-Noun naming rules' -f $_.name)
}
$helpless = $commands | Get-Help | Where-Object {$_.Synopsis -match "^\s+$($_.name)\s+\["} | Select-Object -ExpandProperty name
foreach ($command in $helpless ) {
Show-Warning ('On-line help is missing for {0}.' -f $command)
}
if (-not (Get-Module -Name PSScriptAnalyzer -ListAvailable)) {
Install-Module -Name PSScriptAnalyzer -Force
}
$PSSAInfo = Import-module -Name PSScriptAnalyzer -PassThru -force
"Running {1} V{2} against '{0}' " -f $ModulePath , $PSSAInfo.name, $PSSAInfo.Version
$AnalyzerResults = Invoke-ScriptAnalyzer -Path $ModulePath -Recurse -ErrorAction SilentlyContinue
if ($AnalyzerResults) {
if (-not (Get-Module -Name ImportExcel -ListAvailable)) {
#ironically we use this to build import-excel Shouldn't need this there!
'Installing ImportExcel.'
Install-Module -Name ImportExcel -Force
}
$chartDef = New-ExcelChartDefinition -ChartType 'BarClustered' -Column 2 -Title "Script analysis" -LegendBold
$ExcelParams = @{
Path = (Join-Path $pwd 'ScriptAnalyzer.xlsx')
WorksheetName = 'FullResults'
TableStyle = 'Medium6'
AutoSize = $true
Activate = $true
PivotTableDefinition = @{BreakDown = @{
PivotData = @{RuleName = 'Count' }
PivotRows = 'Severity', 'RuleName'
PivotTotals = 'Rows'
PivotChartDefinition = $chartDef }}
}
Remove-Item -Path $ExcelParams['Path'] -ErrorAction SilentlyContinue
$AnalyzerResults | Export-Excel @ExcelParams
if (Test-Path $ExcelParams['Path']) {
"Try to uploadfile {0}" -f $ExcelParams['Path']
"##vso[task.uploadfile]{0}" -f $ExcelParams['Path']
}
}
}
if (Test-Path $script:warningfile) {
"Try to uploadfile {0}" -f $script:warningfile
"##vso[task.uploadfile]{0}" -f $script:warningfile
}
#if there are test files, run pester (unless told not to)
if (-not $SkipPesterTests -and (Get-ChildItem -Recurse *.tests.ps1)) {
Import-Module -Force $outputFile
if (-not (Get-Module -ListAvailable pester | Where-Object -Property version -ge ([version]::new(4,4,1)))) {
Install-Module Pester -Force -SkipPublisherCheck
}
Import-Module Pester
$PesterOutputPath = Join-Path $pwd -ChildPath ('TestResultsPS{0}.xml' -f $PSVersionTable.PSVersion)
if ($PSScriptRoot) { Pop-Location }
Invoke-Pester -OutputFile $PesterOutputPath
}
elseif ($PSScriptRoot) { Pop-Location }

106
CI/Publish.ps1 Normal file
View File

@@ -0,0 +1,106 @@
<#
.SYNOPSIS
Deploy module to PowerShellGallery.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "Success")]
[CmdletBinding(DefaultParameterSetName = 'ModuleName')]
Param
(
# The name of the installed module to be deployed, if not provided the name of the .psm1 file in the parent folder is used.
[Parameter(ParameterSetName = 'ModuleName')]
[ValidateNotNullOrEmpty()]
[String]$ModuleName,
# Publish module from path (module folder), if not provided -ModuleName is used.
[Parameter(Mandatory, ParameterSetName = 'Path')]
[ValidateNotNullOrEmpty()]
[String]$Path,
# Key for PowerShellGallery deployment, if not provided $env:NugetApiKey is used.
[ValidateNotNullOrEmpty()]
[String]$NugetApiKey,
# Skip Version verification for PowerShellGallery deployment, can be used for first release.
[Switch]$Force
)
$ErrorActionPreference = 'Stop'
if ($Path) {
$Path = Resolve-Path -Path $Path
if ($Path.Count -ne 1) {
throw ('Invalid Path, $Path.Count: {0}.' -f $Path.Count)
}
$Psd1Path = (Get-ChildItem -File -Filter *.psd1 -Path $Path -Recurse)[0].FullName
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension($Psd1Path)
$VersionLocal = (. ([Scriptblock]::Create((Get-Content -Path $Psd1Path | Out-String)))).ModuleVersion
}
else {
# Get Script Root
if ($PSScriptRoot) {
$ScriptRoot = $PSScriptRoot
}
elseif ($psISE.CurrentFile.IsUntitled -eq $false) {
$ScriptRoot = Split-Path -Path $psISE.CurrentFile.FullPath
}
elseif ($null -ne $psEditor.GetEditorContext().CurrentFile.Path -and $psEditor.GetEditorContext().CurrentFile.Path -notlike 'untitled:*') {
$ScriptRoot = Split-Path -Path $psEditor.GetEditorContext().CurrentFile.Path
}
else {
$ScriptRoot = '.'
}
# Get Module Info
if (!$ModuleName) {
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path (Split-Path $ScriptRoot)))
}
$VersionLocal = ((Get-Module -Name $ModuleName -ListAvailable).Version | Measure-Object -Maximum).Maximum
}
"[Progress] Deploy Script Start for Module: $ModuleName, Version: $VersionLocal."
# Deploy to PowerShell Gallery if run locally OR from AppVeyor & GitHub master
if (!$env:APPVEYOR -or $env:APPVEYOR_REPO_BRANCH -eq 'master') {
if ($env:APPVEYOR) {
$Success = $true
$AppVeyorProject = Invoke-RestMethod -Uri "https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG"
$AppVeyorProject.build.jobs | ForEach-Object {
'[Info] AppVeyor job name: "{0}", Id: {1}, Status: {2}.' -f $_.name, $_.jobId, $_.status
if ($_.jobId -ne $env:APPVEYOR_JOB_ID -and $_.status -ne "success") {
$Success = $false
}
}
if (!$Success) {
'[Info] There are filed jobs skipping PowerShell Gallery deploy.'
break
}
}
try {
$VersionGallery = (Find-Module -Name $ModuleName -ErrorAction Stop).Version
}
catch {
if ($_.Exception.Message -notlike 'No match was found for the specified search criteria*' -or !$Force) {
throw $_
}
}
"[Info] PowerShellGallery. $ModuleName, VersionGallery: $VersionGallery, VersionLocal: $VersionLocal."
if ($VersionGallery -lt $VersionLocal -or $Force) {
if (!$NugetApiKey) {
$NugetApiKey = $env:NugetApiKey
}
"[Info] PowerShellGallery. Deploying $ModuleName version $VersionLocal."
if ($Path) {
Publish-Module -NuGetApiKey $NugetApiKey -Path $Path
}
else {
Publish-Module -NuGetApiKey $NugetApiKey -Name $ModuleName -RequiredVersion $VersionLocal
}
}
else {
'[Info] PowerShellGallery Deploy Skipped (Version Check).'
}
}
else {
'[Info] PowerShellGallery Deploy Skipped.'
}
'[Progress] Deploy Ended.'

6
CI/PublishToGallery.ps1 Normal file
View File

@@ -0,0 +1,6 @@
$p = @{
Name = "ImportExcel"
NuGetApiKey = $NuGetApiKey
}
Publish-Module @p

View File

@@ -0,0 +1,54 @@

function Test-SingleFunction {
param (
[parameter(ValueFromPipeline=$true)]
$path )
begin {
$psd = Get-Content -Raw "$PSScriptRoot\..\ImportExcel.psd1"
$exportedFunctions = (Invoke-Command ([scriptblock]::Create($psd))).functionsToExport
$reg = [Regex]::new(@"
function\s*[-\w]+\s*{ # The function name and opening '{'
(?:
[^{}]+ # Match all non-braces
|
(?<open> { ) # Match '{', and capture into 'open'
|
(?<-open> } ) # Match '}', and delete the 'open' capture
)*
(?(open)(?!)) # Fails if 'open' stack isn't empty
} # Functions closing '}'
"@, 57) # 41 = compile ignore case and white space.
$reg2 = [Regex]::new(@"
^function\s*[-\w]+\s*{ # The function name and opening '{'
(
\#.*?[\r\n]+ # single line comment
| # or
\s*<\#.*?\#> # <#comment block#>
| # or
\s*\[.*?\] # [attribute tags]
)*
"@, 57)
# 43 = compile, multi-line, ignore case and white space.
}
process {
$item = Get-item $Path
$name = $item.Name -replace "\.\w+$",""
Write-Verbose $name
$file = Get-Content $item -Raw
$m = $reg.Matches($file)
#based on https://stackoverflow.com/questions/7898310/using-regex-to-balance-match-parenthesis
if ($m.Count -eq 0) {return "Could not find $name function in $($item.name)"}
elseif ($m.Count -ge 2) {return "Multiple functions in $($item.name)"}
elseif ($exportedFunctions -cnotcontains $name) {return "$name not exported (or in the wrong case)"}
elseif ($m[0] -cnotmatch "^\w+\s+$name") {return "function $name in wrong case"}
$m2 = [regex]::Match($m[0],"param",[System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
if (-not $m2.Success) {return "No param block in $name"}
# elseif ($m[0] -inotmatch "(?s)^function\s*$name\s*{(\s*<\#.*?\#>|\s*\[.*?\])*\s*param")
# elseif ($reg2.IsMatch($m[0].Value)) {return "function $name has comment-based help"}
elseif ($m[0] -inotmatch "\[CmdletBinding\(" -and
$m[0] -inotmatch "\[parameter\(" ) {return "$name has is not an advanced function"}
#elseif (-not (& $Name -?).synopsis) {return "$name has no help"}
else {Write-Verbose "$name OK"}
}
}

80
CI/build.ps1 Normal file
View File

@@ -0,0 +1,80 @@
[CmdletBinding(DefaultParameterSetName = 'Default')]
param(
# Path to install the module to, if not provided -Scope used.
[Parameter(Mandatory, ParameterSetName = 'ModulePath')]
[ValidateNotNullOrEmpty()]
[String]$ModulePath,
# Path to install the module to, PSModulePath "CurrentUser" or "AllUsers", if not provided "CurrentUser" used.
[Parameter(Mandatory, ParameterSetName = 'Scope')]
[ValidateSet('CurrentUser', 'AllUsers')]
[string]
$Scope = 'CurrentUser',
[switch]$Passthru
)
if ($PSScriptRoot) { Push-Location "$PSScriptRoot\.." }
$psdpath = Get-Item "*.psd1"
if (-not $psdpath -or $psdpath.count -gt 1) {
throw "Did not find a unique PSD file "
}
else {
$ModuleName = $psdpath.Name -replace '\.psd1$' , ''
$Settings = $(& ([scriptblock]::Create(($psdpath | Get-Content -Raw))))
}
try {
Write-Verbose -Message 'Module installation started'
if (!$ModulePath) {
if ($IsLinux -or $IsMacOS) {$ModulePathSeparator = ':' }
else {$ModulePathSeparator = ';' }
if ($Scope -eq 'CurrentUser') { $dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) }
else { $dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFiles) }
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator).where({$_ -like "$dir*"},"First",1)
$ModulePath = Join-Path -Path $ModulePath -ChildPath $ModuleName
$ModulePath = Join-Path -Path $ModulePath -ChildPath $Settings.ModuleVersion
}
# Create Directory
if (-not (Test-Path -Path $ModulePath)) {
$null = New-Item -Path $ModulePath -ItemType Directory -ErrorAction Stop
Write-Verbose -Message ('Created module folder: "{0}"' -f $ModulePath)
}
Write-Verbose -Message ('Copying files to "{0}"' -f $ModulePath)
$outputFile = $psdpath | Copy-Item -Destination $ModulePath -PassThru
Foreach ($file in $Settings.FileList) {
if ($file -like '.\*') {
$dest = ($file -replace '\.\\',"$ModulePath\")
if (-not (Test-Path -PathType Container (Split-Path -Parent $dest))) {
$null = New-item -Type Directory -Path (Split-Path -Parent $dest)
}
}
else {$dest = $ModulePath }
Copy-Item $file -Destination $dest -Force -Recurse
}
if (Test-Path -PathType Container "mdHelp") {
if (-not (Get-Module -ListAvailable platyPS)) {
Write-Verbose-Message ('Installing Platyps to build help files')
Install-Module -Name platyPS -Force -SkipPublisherCheck
}
Import-Module platyPS
Get-ChildItem .\mdHelp -Directory | ForEach-Object {
New-ExternalHelp -Path $_.FullName -OutputPath (Join-Path $ModulePath $_.Name) -Force -Verbose
}
}
$env:PSNewBuildModule = $ModulePath
if ($Passthru) {$outputFile}
}
catch {
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
}
finally {
if ($PSScriptRoot) { Pop-Location }
Write-Verbose -Message 'Module installation end'
}

75
CI/pipeline.yml Normal file
View File

@@ -0,0 +1,75 @@
# https://aka.ms/yaml
trigger:
branches:
include:
- '*'
# - master
# - releases/*
paths:
exclude:
- README.md
- CHANGELOG.md
jobs:
- job: 'Windows_PowerShell_all_options'
pool:
vmImage: 'windows-latest'
steps:
- powershell: 'Install-Module -Name Pester -Force -SkipPublisherCheck'
displayName: 'Update Pester'
- powershell: './CI/PS-CI.ps1 '
displayName: 'Check Build Check Pack Test'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults*.xml'
failTaskOnFailedTests: true
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/ImportExcel'
artifact: 'ImportExcel'
- job: 'PowerShell_Core_on_Windows_Build_and_Pester_only'
pool:
vmImage: 'windows-latest'
steps:
- pwsh: 'Install-Module -Name Pester -Force'
displayName: 'Update Pester'
- pwsh: '.\CI\PS-CI.ps1 -SkipPreChecks -SkipHelp -SkipPostChecks'
displayName: 'Install and Test'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults*.xml'
failTaskOnFailedTests: true
- job: 'Ubuntu_Build_and_Pester_Only'
pool:
vmImage: 'ubuntu-latest'
steps:
- powershell: 'Install-Module -Name Pester -Force'
displayName: 'Update Pester'
- powershell: './CI/PS-CI.ps1 -SkipPreChecks -SkipHelp -SkipPostChecks '
displayName: 'Install and Test'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults*.xml'
failTaskOnFailedTests: true
- job: 'macOS_Build_and_Pester_Only'
pool:
vmImage: 'macOS-latest'
steps:
- script: brew install mono-libgdiplus
displayName: 'Install mono-libgdiplus'
- powershell: 'Install-Module -Name Pester -Force'
displayName: 'Update Pester'
- powershell: './CI/PS-CI.ps1 -SkipPreChecks -SkipHelp -SkipPostChecks'
displayName: 'Install and Test'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults*.xml'
failTaskOnFailedTests: true

137
Charting/BarChart.md Normal file
View File

@@ -0,0 +1,137 @@
---
external help file: ImportExcel-help.xml
Module Name: ImportExcel
online version:
schema: 2.0.0
---
# BarChart
## SYNOPSIS
{{ Fill in the Synopsis }}
## SYNTAX
```
BarChart [[-targetData] <Object>] [[-title] <Object>] [[-ChartType] <eChartType>] [-NoLegend] [-ShowCategory]
[-ShowPercent] [<CommonParameters>]
```
## DESCRIPTION
{{ Fill in the Description }}
## EXAMPLES
### Example 1
```powershell
PS C:\> {{ Add example code here }}
```
{{ Add example description here }}
## PARAMETERS
### -ChartType
{{ Fill ChartType Description }}
```yaml
Type: eChartType
Parameter Sets: (All)
Aliases:
Accepted values: Area, Line, Pie, Bubble, ColumnClustered, ColumnStacked, ColumnStacked100, ColumnClustered3D, ColumnStacked3D, ColumnStacked1003D, BarClustered, BarStacked, BarStacked100, BarClustered3D, BarStacked3D, BarStacked1003D, LineStacked, LineStacked100, LineMarkers, LineMarkersStacked, LineMarkersStacked100, PieOfPie, PieExploded, PieExploded3D, BarOfPie, XYScatterSmooth, XYScatterSmoothNoMarkers, XYScatterLines, XYScatterLinesNoMarkers, AreaStacked, AreaStacked100, AreaStacked3D, AreaStacked1003D, DoughnutExploded, RadarMarkers, RadarFilled, Surface, SurfaceWireframe, SurfaceTopView, SurfaceTopViewWireframe, Bubble3DEffect, StockHLC, StockOHLC, StockVHLC, StockVOHLC, CylinderColClustered, CylinderColStacked, CylinderColStacked100, CylinderBarClustered, CylinderBarStacked, CylinderBarStacked100, CylinderCol, ConeColClustered, ConeColStacked, ConeColStacked100, ConeBarClustered, ConeBarStacked, ConeBarStacked100, ConeCol, PyramidColClustered, PyramidColStacked, PyramidColStacked100, PyramidBarClustered, PyramidBarStacked, PyramidBarStacked100, PyramidCol, XYScatter, Radar, Doughnut, Pie3D, Line3D, Column3D, Area3D
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -NoLegend
{{ Fill NoLegend Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowCategory
{{ Fill ShowCategory Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowPercent
{{ Fill ShowPercent Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -targetData
{{ Fill targetData Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 0
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```
### -title
{{ Fill title Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
## INPUTS
### System.Object
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS

View File

@@ -9,7 +9,7 @@ function DoChart {
)
if($targetData[0] -is [System.ValueType]) {
$chart = New-ExcelChart -YRange "A1:A$($targetData.count)" -Title $title -ChartType $ChartType
$chart = New-ExcelChartDefinition -YRange "A1:A$($targetData.count)" -Title $title -ChartType $ChartType
} else {
$xyRange = Get-XYRange $targetData
@@ -19,7 +19,7 @@ function DoChart {
$Y = $xyRange.YRange.ExcelColumn
$YRange = "{0}2:{0}{1}" -f $Y,($targetData.count+1)
$chart = New-ExcelChart -XRange $xRange -YRange $yRange -Title $title -ChartType $ChartType `
$chart = New-ExcelChartDefinition -XRange $xRange -YRange $yRange -Title $title -ChartType $ChartType `
-NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent
}

137
Charting/ColumnChart.md Normal file
View File

@@ -0,0 +1,137 @@
---
external help file: ImportExcel-help.xml
Module Name: ImportExcel
online version:
schema: 2.0.0
---
# ColumnChart
## SYNOPSIS
{{ Fill in the Synopsis }}
## SYNTAX
```
ColumnChart [[-targetData] <Object>] [[-title] <Object>] [[-ChartType] <eChartType>] [-NoLegend]
[-ShowCategory] [-ShowPercent] [<CommonParameters>]
```
## DESCRIPTION
{{ Fill in the Description }}
## EXAMPLES
### Example 1
```powershell
PS C:\> {{ Add example code here }}
```
{{ Add example description here }}
## PARAMETERS
### -ChartType
{{ Fill ChartType Description }}
```yaml
Type: eChartType
Parameter Sets: (All)
Aliases:
Accepted values: Area, Line, Pie, Bubble, ColumnClustered, ColumnStacked, ColumnStacked100, ColumnClustered3D, ColumnStacked3D, ColumnStacked1003D, BarClustered, BarStacked, BarStacked100, BarClustered3D, BarStacked3D, BarStacked1003D, LineStacked, LineStacked100, LineMarkers, LineMarkersStacked, LineMarkersStacked100, PieOfPie, PieExploded, PieExploded3D, BarOfPie, XYScatterSmooth, XYScatterSmoothNoMarkers, XYScatterLines, XYScatterLinesNoMarkers, AreaStacked, AreaStacked100, AreaStacked3D, AreaStacked1003D, DoughnutExploded, RadarMarkers, RadarFilled, Surface, SurfaceWireframe, SurfaceTopView, SurfaceTopViewWireframe, Bubble3DEffect, StockHLC, StockOHLC, StockVHLC, StockVOHLC, CylinderColClustered, CylinderColStacked, CylinderColStacked100, CylinderBarClustered, CylinderBarStacked, CylinderBarStacked100, CylinderCol, ConeColClustered, ConeColStacked, ConeColStacked100, ConeBarClustered, ConeBarStacked, ConeBarStacked100, ConeCol, PyramidColClustered, PyramidColStacked, PyramidColStacked100, PyramidBarClustered, PyramidBarStacked, PyramidBarStacked100, PyramidCol, XYScatter, Radar, Doughnut, Pie3D, Line3D, Column3D, Area3D
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -NoLegend
{{ Fill NoLegend Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowCategory
{{ Fill ShowCategory Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowPercent
{{ Fill ShowPercent Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -targetData
{{ Fill targetData Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 0
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```
### -title
{{ Fill title Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
## INPUTS
### System.Object
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS

137
Charting/LineChart.md Normal file
View File

@@ -0,0 +1,137 @@
---
external help file: ImportExcel-help.xml
Module Name: ImportExcel
online version: https://github.com/dfinke/ImportExcel
schema: 2.0.0
---
# LineChart
## SYNOPSIS
{{ Fill in the Synopsis }}
## SYNTAX
```
LineChart [[-targetData] <Object>] [[-title] <Object>] [[-ChartType] <eChartType>] [-NoLegend] [-ShowCategory]
[-ShowPercent] [<CommonParameters>]
```
## DESCRIPTION
{{ Fill in the Description }}
## EXAMPLES
### Example 1
```powershell
PS C:\> {{ Add example code here }}
```
{{ Add example description here }}
## PARAMETERS
### -ChartType
{{ Fill ChartType Description }}
```yaml
Type: eChartType
Parameter Sets: (All)
Aliases:
Accepted values: Area, Line, Pie, Bubble, ColumnClustered, ColumnStacked, ColumnStacked100, ColumnClustered3D, ColumnStacked3D, ColumnStacked1003D, BarClustered, BarStacked, BarStacked100, BarClustered3D, BarStacked3D, BarStacked1003D, LineStacked, LineStacked100, LineMarkers, LineMarkersStacked, LineMarkersStacked100, PieOfPie, PieExploded, PieExploded3D, BarOfPie, XYScatterSmooth, XYScatterSmoothNoMarkers, XYScatterLines, XYScatterLinesNoMarkers, AreaStacked, AreaStacked100, AreaStacked3D, AreaStacked1003D, DoughnutExploded, RadarMarkers, RadarFilled, Surface, SurfaceWireframe, SurfaceTopView, SurfaceTopViewWireframe, Bubble3DEffect, StockHLC, StockOHLC, StockVHLC, StockVOHLC, CylinderColClustered, CylinderColStacked, CylinderColStacked100, CylinderBarClustered, CylinderBarStacked, CylinderBarStacked100, CylinderCol, ConeColClustered, ConeColStacked, ConeColStacked100, ConeBarClustered, ConeBarStacked, ConeBarStacked100, ConeCol, PyramidColClustered, PyramidColStacked, PyramidColStacked100, PyramidBarClustered, PyramidBarStacked, PyramidBarStacked100, PyramidCol, XYScatter, Radar, Doughnut, Pie3D, Line3D, Column3D, Area3D
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -NoLegend
{{ Fill NoLegend Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowCategory
{{ Fill ShowCategory Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowPercent
{{ Fill ShowPercent Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -targetData
{{ Fill targetData Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 0
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```
### -title
{{ Fill title Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
## INPUTS
### System.Object
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS

137
Charting/PieChart.md Normal file
View File

@@ -0,0 +1,137 @@
---
external help file: ImportExcel-help.xml
Module Name: ImportExcel
online version:
schema: 2.0.0
---
# PieChart
## SYNOPSIS
{{ Fill in the Synopsis }}
## SYNTAX
```
PieChart [[-targetData] <Object>] [[-title] <Object>] [[-ChartType] <eChartType>] [-NoLegend] [-ShowCategory]
[-ShowPercent] [<CommonParameters>]
```
## DESCRIPTION
{{ Fill in the Description }}
## EXAMPLES
### Example 1
```powershell
PS C:\> {{ Add example code here }}
```
{{ Add example description here }}
## PARAMETERS
### -ChartType
{{ Fill ChartType Description }}
```yaml
Type: eChartType
Parameter Sets: (All)
Aliases:
Accepted values: Area, Line, Pie, Bubble, ColumnClustered, ColumnStacked, ColumnStacked100, ColumnClustered3D, ColumnStacked3D, ColumnStacked1003D, BarClustered, BarStacked, BarStacked100, BarClustered3D, BarStacked3D, BarStacked1003D, LineStacked, LineStacked100, LineMarkers, LineMarkersStacked, LineMarkersStacked100, PieOfPie, PieExploded, PieExploded3D, BarOfPie, XYScatterSmooth, XYScatterSmoothNoMarkers, XYScatterLines, XYScatterLinesNoMarkers, AreaStacked, AreaStacked100, AreaStacked3D, AreaStacked1003D, DoughnutExploded, RadarMarkers, RadarFilled, Surface, SurfaceWireframe, SurfaceTopView, SurfaceTopViewWireframe, Bubble3DEffect, StockHLC, StockOHLC, StockVHLC, StockVOHLC, CylinderColClustered, CylinderColStacked, CylinderColStacked100, CylinderBarClustered, CylinderBarStacked, CylinderBarStacked100, CylinderCol, ConeColClustered, ConeColStacked, ConeColStacked100, ConeBarClustered, ConeBarStacked, ConeBarStacked100, ConeCol, PyramidColClustered, PyramidColStacked, PyramidColStacked100, PyramidBarClustered, PyramidBarStacked, PyramidBarStacked100, PyramidCol, XYScatter, Radar, Doughnut, Pie3D, Line3D, Column3D, Area3D
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -NoLegend
{{ Fill NoLegend Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowCategory
{{ Fill ShowCategory Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowPercent
{{ Fill ShowPercent Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -targetData
{{ Fill targetData Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 0
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```
### -title
{{ Fill title Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
## INPUTS
### System.Object
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS

134
Charting/doChart.md Normal file
View File

@@ -0,0 +1,134 @@
---
external help file: ImportExcel-help.xml
Module Name: ImportExcel
online version:
schema: 2.0.0
---
# DoChart
## SYNOPSIS
{{ Fill in the Synopsis }}
## SYNTAX
```
DoChart [[-targetData] <Object>] [[-title] <Object>] [[-ChartType] <eChartType>] [-NoLegend] [-ShowCategory]
[-ShowPercent]
```
## DESCRIPTION
{{ Fill in the Description }}
## EXAMPLES
### Example 1
```powershell
PS C:\> {{ Add example code here }}
```
{{ Add example description here }}
## PARAMETERS
### -ChartType
{{ Fill ChartType Description }}
```yaml
Type: eChartType
Parameter Sets: (All)
Aliases:
Accepted values: Area, Line, Pie, Bubble, ColumnClustered, ColumnStacked, ColumnStacked100, ColumnClustered3D, ColumnStacked3D, ColumnStacked1003D, BarClustered, BarStacked, BarStacked100, BarClustered3D, BarStacked3D, BarStacked1003D, LineStacked, LineStacked100, LineMarkers, LineMarkersStacked, LineMarkersStacked100, PieOfPie, PieExploded, PieExploded3D, BarOfPie, XYScatterSmooth, XYScatterSmoothNoMarkers, XYScatterLines, XYScatterLinesNoMarkers, AreaStacked, AreaStacked100, AreaStacked3D, AreaStacked1003D, DoughnutExploded, RadarMarkers, RadarFilled, Surface, SurfaceWireframe, SurfaceTopView, SurfaceTopViewWireframe, Bubble3DEffect, StockHLC, StockOHLC, StockVHLC, StockVOHLC, CylinderColClustered, CylinderColStacked, CylinderColStacked100, CylinderBarClustered, CylinderBarStacked, CylinderBarStacked100, CylinderCol, ConeColClustered, ConeColStacked, ConeColStacked100, ConeBarClustered, ConeBarStacked, ConeBarStacked100, ConeCol, PyramidColClustered, PyramidColStacked, PyramidColStacked100, PyramidBarClustered, PyramidBarStacked, PyramidBarStacked100, PyramidCol, XYScatter, Radar, Doughnut, Pie3D, Line3D, Column3D, Area3D
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -NoLegend
{{ Fill NoLegend Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowCategory
{{ Fill ShowCategory Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ShowPercent
{{ Fill ShowPercent Description }}
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -targetData
{{ Fill targetData Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -title
{{ Fill title Description }}
```yaml
Type: Object
Parameter Sets: (All)
Aliases:
Required: False
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
## INPUTS
### None
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS

View File

@@ -1,26 +0,0 @@
Function ColorCompletion {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
[System.Drawing.KnownColor].GetFields() | Where-Object {$_.IsStatic -and $_.name -like "$wordToComplete*" } |
Sort-Object name | ForEach-Object {New-CompletionResult $_.name $_.name
}
}
if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue) {
Register-ArgumentCompleter -CommandName Export-Excel -ParameterName TitleBackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName DataBarColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName ForeGroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName AllDataBackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName TabColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
}

View File

@@ -1,74 +0,0 @@
Function Convert-XlRangeToImage {
<#
.Synopsis
Gets the specified part of an Excel file and exports it as an image
.Description
Excel allows charts to be exported directly to a file, but can't do this with the rest of a sheet. To work round this this function
* Opens a copy of Excel and loads a file
* Selects a worksheet and then a range of cells in that worksheet
* Copies the select to the clipboard
* Saves the clipboard contents as an image file (it will save as .JPG unless the file name ends .BMP or .PNG)
* Copies a single cell to the clipboard (to prevent the "you have put a lot in the clipboard" message appearing)
* Closes Excel
#>
Param (
#Path to the Excel file
[parameter(Mandatory=$true)]
$Path,
#Worksheet name - if none is specified "Sheet1" will be assumed
$workSheetname = "Sheet1" ,
#Range of cells within the sheet, e.g "A1:Z99"
[parameter(Mandatory=$true)]
$range,
#A bmp, png or jpg file where the result will be saved
$destination = "$pwd\temp.png",
#If specified opens the image in the default viewer.
[switch]$show
)
$extension = $destination -replace '^.*\.(\w+)$' ,'$1'
if ($extension -in @('JPEG','BMP','PNG')) {
$Format = [system.Drawing.Imaging.ImageFormat]$extension
} #if we don't recognise the extension OR if it is JPG with an E, use JPEG format
else { $Format = [system.Drawing.Imaging.ImageFormat]::Jpeg}
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Starting Excel"
$xlApp = New-Object -ComObject "Excel.Application"
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Opening Workbook and copying data"
$xlWbk = $xlApp.Workbooks.Open($Path)
$xlWbk.Worksheets($workSheetname).Select()
$xlWbk.ActiveSheet.Range($range).Select() | Out-Null
$xlApp.Selection.Copy() | Out-Null
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Saving copied data"
# Get-Clipboard came in with PS5. Older versions can use [System.Windows.Clipboard] but it is ugly.
$image = Get-Clipboard -Format Image
$image.Save($destination, $Format)
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Closing Excel"
$xlWbk.ActiveSheet.Range("a1").Select() | Out-Null
$xlApp.Selection.Copy() | Out-Null
$xlApp.Quit()
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Completed
if ($show) {Start-Process -FilePath $destination}
else {Get-Item -Path $destination}
}
<#
del demo*.xlsx
$workSheetname = 'Processes'
$Path = "$pwd\demo.xlsx"
$myData = Get-Process | Select-Object -Property Name,WS,CPU,Description,company,startTime
$excelPackage = $myData | Export-Excel -KillExcel -Path $Path -WorkSheetname $workSheetname -ClearSheet -AutoSize -AutoFilter -BoldTopRow -FreezeTopRow -PassThru
$workSheet = $excelPackage.Workbook.Worksheets[$workSheetname]
$range = $workSheet.Dimension.Address
Set-Format -WorkSheet $workSheet -Range "b:b" -NumberFormat "#,###" -AutoFit
Set-Format -WorkSheet $workSheet -Range "C:C" -NumberFormat "#,##0.00" -AutoFit
Set-Format -WorkSheet $workSheet -Range "F:F" -NumberFormat "dd MMMM HH:mm:ss" -AutoFit
Add-ConditionalFormatting -WorkSheet $workSheet -Range "c2:c1000" -DataBarColor Blue
Add-ConditionalFormatting -WorkSheet $workSheet -Range "b2:B1000" -RuleType GreaterThan -ConditionValue '104857600' -ForeGroundColor "Red" -Bold
Export-Excel -ExcelPackage $excelPackage -WorkSheetname $workSheetname
Convert-XlRangeToImage -Path $Path -workSheetname $workSheetname -range $range -destination "$pwd\temp.png" -show
#>
#Convert-XlRangeToImage -Path $Path -workSheetname $workSheetname -range $range -destination "$pwd\temp.png" -show

View File

@@ -1,130 +0,0 @@
function ConvertFrom-ExcelToSQLInsert {
<#
.SYNOPSIS
Generate SQL insert statements from Excel spreadsheet.
.DESCRIPTION
Generate SQL insert statements from Excel spreadsheet.
.PARAMETER TableName
Name of the target database table.
.PARAMETER Path
Path to an existing .XLSX file
This parameter is passed to Import-Excel as is.
.PARAMETER WorkSheetname
Specifies the name of the worksheet in the Excel workbook to import. By default, if no name is provided, the first worksheet will be imported.
This parameter is passed to Import-Excel as is.
.PARAMETER StartRow
The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
When the parameters -NoHeader and -HeaderName are not provided, this row will contain the column headers that will be used as property names. When one of both parameters are provided, the property names are automatically created and this row will be treated as a regular row containing data.
.PARAMETER Header
Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
In case you provide less header names than there is data in the worksheet, then only the data with a corresponding header name will be imported and the data without header name will be disregarded.
In case you provide more header names than there is data in the worksheet, then all data will be imported and all objects will have all the property names you defined in the header names. As such, the last properties will be blanc as there is no data for them.
.PARAMETER NoHeader
Automatically generate property names (P1, P2, P3, ..) instead of the ones defined in the column headers of the TopRow.
This switch is best used when you want to import the complete worksheet as is and are not concerned with the property names.
.PARAMETER DataOnly
Import only rows and columns that contain data, empty rows and empty columns are not imported.
.PARAMETER ConvertEmptyStringsToNull
If specified, cells without any data are replaced with NULL, instead of an empty string.
This is to address behviors in certain DBMS where an empty string is insert as 0 for INT column, instead of a NULL value.
.EXAMPLE
Generate SQL insert statements from Movies.xlsx file, leaving blank cells as empty strings:
----------------------------------------------------------
| File: Movies.xlsx - Sheet: Sheet1 |
----------------------------------------------------------
| A B C |
|1 Movie Name Year Rating |
|2 The Bodyguard 1992 9 |
|3 The Matrix 1999 8 |
|4 Skyfall 2012 9 |
|5 The Avengers 2012 |
----------------------------------------------------------
PS C:\> Import-Excel -TableName "Movies" -Path 'C:\Movies.xlsx'
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Bodyguard', '1992', '9');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Matrix', '1999', '8');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('Skyfall', '2012', '9');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Avengers', '2012', '');
.EXAMPLE
Generate SQL insert statements from Movies.xlsx file, specify NULL instead of an empty string.
----------------------------------------------------------
| File: Movies.xlsx - Sheet: Sheet1 |
----------------------------------------------------------
| A B C |
|1 Movie Name Year Rating |
|2 The Bodyguard 1992 9 |
|3 The Matrix 1999 8 |
|4 Skyfall 2012 9 |
|5 The Avengers 2012 |
----------------------------------------------------------
PS C:\> ConvertFrom-ExcelToSQLInsert -TableName "Movies" -Path "C:\Movies.xlsx" -ConvertEmptyStringsToNull
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Bodyguard', '1992', '9');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Matrix', '1999', '8');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('Skyfall', '2012', '9');
INSERT INTO Movies ('Movie Name', 'Year', 'Rating') Values('The Avengers', '2012', NULL);
.NOTES
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
$TableName,
[Alias("FullName")]
[Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, Mandatory = $true)]
[ValidateScript( { Test-Path $_ -PathType Leaf })]
$Path,
[Alias("Sheet")]
$WorkSheetname = 1,
[Alias('HeaderRow', 'TopRow')]
[ValidateRange(1, 9999)]
[Int]$StartRow,
[string[]]$Header,
[switch]$NoHeader,
[switch]$DataOnly,
[switch]$ConvertEmptyStringsToNull
)
$null = $PSBoundParameters.Remove('TableName')
$null = $PSBoundParameters.Remove('ConvertEmptyStringsToNull')
$params = @{} + $PSBoundParameters
ConvertFrom-ExcelData @params {
param($propertyNames, $record)
$ColumnNames = "'" + ($PropertyNames -join "', '") + "'"
$values = foreach ($propertyName in $PropertyNames) {
if ($ConvertEmptyStringsToNull.IsPresent -and [string]::IsNullOrEmpty($record.$propertyName)) {
'NULL'
}
else {
"'" + $record.$propertyName + "'"
}
}
$targetValues = ($values -join ", ")
"INSERT INTO {0} ({1}) Values({2});" -f $TableName, $ColumnNames, $targetValues
}
}

View File

@@ -1,22 +0,0 @@
function Copy-ExcelWorkSheet {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$SourceWorkbook,
[Parameter(Mandatory=$true)]
$SourceWorkSheet,
[Parameter(Mandatory=$true)]
$DestinationWorkbook,
$DestinationWorkSheet,
[Switch]$Show
)
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
if(!$DestinationWorkSheet) {
$DestinationWorkSheet = $SourceWorkSheet
}
Import-Excel -Path $SourceWorkbook -WorkSheetname $SourceWorkSheet |
Export-Excel -Path $DestinationWorkbook -WorkSheetname $DestinationWorkSheet -Show:$Show
}

Binary file not shown.

View File

@@ -0,0 +1,15 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlSourcefile = "$env:TEMP\Source.xlsx"
Write-Verbose -Verbose -Message "Save location: $xlSourcefile"
Remove-Item $xlSourcefile -ErrorAction Ignore
#Put some simple data in a worksheet and Get an excel package object to represent the file
1..5 | Export-Excel $xlSourcefile -WorksheetName 'Tab1' -AutoSize -AutoFilter
#Add another tab. Replace the $TabData2 with your data
1..10 | Export-Excel $xlSourcefile -WorksheetName 'Tab 2' -AutoSize -AutoFilter
#Add another tab. Replace the $TabData3 with your data
1..15 | Export-Excel $xlSourcefile -WorksheetName 'Tab 3' -AutoSize -AutoFilter -Show

View File

@@ -0,0 +1,12 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlSourcefile = "$env:TEMP\Source.xlsx"
Remove-Item $xlSourcefile -ErrorAction Ignore
#Put some simple data in a worksheet and Get an excel package object to represent the file
$excel = 1..10 | Export-Excel $xlSourcefile -PassThru
#Add a new worksheet named 'NewSheet' and copying the sheet that was just made (Sheet1) to the new sheet
Add-Worksheet -ExcelPackage $excel -WorkSheetname "NewSheet" -CopySource $excel.Workbook.Worksheets["Sheet1"]
#Save and open in Excel
Close-ExcelPackage -ExcelPackage $excel -Show

View File

@@ -0,0 +1,21 @@
# Creates a worksheet, addes a chart and then a Linear trendline
$xlfile = "$env:TEMP\trendLine.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Region,Item,TotalSold
West,screws,60
South,lemon,48
South,apple,71
East,screwdriver,70
East,kiwi,32
West,screwdriver,1
South,melon,21
East,apple,79
South,apple,68
South,avocado,73
"@
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine Linear
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange -Show

View File

@@ -1,12 +1,14 @@
rm temp.xlsx -ErrorAction Ignore
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$data = invoke-sum (ps) company handles,pm,VirtualMemorySize
Remove-Item temp.xlsx -ErrorAction Ignore
$c = New-ExcelChart -Title Stats `
$data = Invoke-Sum -data (Get-Process) -dimension Company -measure Handles, PM, VirtualMemorySize
$c = New-ExcelChartDefinition -Title "ProcessStats" `
-ChartType LineMarkersStacked `
-Header "Stuff" `
-XRange "Processes[Company]" `
-YRange "Processes[PM]","Processes[VirtualMemorySize]"
$data |
Export-Excel temp.xlsx -AutoSize -TableName Processes -Show -ExcelChartDefinition $c
-XRange "Processes[Name]" `
-YRange "Processes[PM]","Processes[VirtualMemorySize]" `
-SeriesHeader "PM","VM"
$data |
Export-Excel -Path temp.xlsx -AutoSize -TableName Processes -ExcelChartDefinition $c -Show

View File

@@ -1,16 +1,19 @@
rm temp.xlsx -ErrorAction Ignore
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Remove-Item temp.xlsx -ErrorAction Ignore
$data = @"
A,B,C,Date
2,1,1,2016-03-29
5,10,1,2016-03-29
"@ | ConvertFrom-Csv
"@
$c = New-ExcelChart -Title Impressions `
-ChartType Line -Header "Something" `
$c = New-ExcelChartDefinition -Title Impressions `
-ChartType Line `
-XRange "Impressions[Date]" `
-YRange @("Impressions[B]","Impressions[A]") `
-SeriesHeader 'B data','A data'
-SeriesHeader 'B data','A data' `
-Row 0 -Column 0
$data |
Export-Excel temp.xlsx -AutoSize -TableName Impressions -Show -ExcelChartDefinition $c
$data | ConvertFrom-Csv | Export-Excel -path temp.xlsx -AutoSize -TableName Impressions
Export-Excel -path temp.xlsx -worksheetName chartPage -ExcelChartDefinition $c -show

View File

@@ -1,19 +1,19 @@
rm *.xlsx
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Remove-Item -Path Tools.xlsx
$data = @"
ID,Product,Quantity,Price,Total
12001,Nails,37,3.99,147.63
12002,Hammer,5,12.10,60.5
12003,Saw,12,15.37,184.44
12010,Drill,20,8,160
12010,Drill,20,8,160
12011,Crowbar,7,23.48,164.36
"@ | ConvertFrom-Csv
"@
$xRange = "Product"
$c1 = New-ExcelChartDefinition -YRange "Price" -XRange "Product" -Title "Item price" -NoLegend -Height 225
$c2 = New-ExcelChartDefinition -YRange "Total "-XRange "Product" -Title "Total sales" -NoLegend -Height 225 -Row 9 -Column 15
$c3 = New-ExcelChartDefinition -YRange "Quantity"-XRange "Product" -Title "Sales volume" -NoLegend -Height 225 -Row 15
$yRange="Price"; $c1 = New-ExcelChart -YRange $yRange -XRange $xRange -Title $yRange -Height 225
$yRange="Total"; $c2 = New-ExcelChart -YRange $yRange -XRange $xRange -Title $yRange -Row 9 -Column 15 -Height 225
$yRange="Quantity"; $c3 = New-ExcelChart -YRange $yRange -XRange $xRange -Title $yRange -Row 15 -Height 225
$data |
Export-Excel -ExcelChartDefinition $c1,$c2,$c3 Tools.xlsx -Show -AutoFilter -AutoNameRange -AutoSize
$data | ConvertFrom-Csv |
Export-Excel -Path "Tools.xlsx" -AutoFilter -AutoNameRange -AutoSize -ExcelChartDefinition $c1,$c2,$c3 -Show

View File

@@ -0,0 +1,27 @@
$xlfile = "$env:TEMP\visitors.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Week, TotalVisitors
1,11916
2,11665
3,13901
4,15444
5,21592
6,15057
7,26187
8,20662
9,28935
10,32443
"@
$cd = New-ExcelChartDefinition `
-XRange Week `
-YRange TotalVisitors `
-Title "No. Of Visitors" `
-ChartType ColumnClustered `
-NoLegend `
-ChartTrendLine Linear
$data | Export-Excel $xlfile -Show -AutoNameRange -AutoSize -TableName Visitors -ExcelChartDefinition $cd

View File

@@ -1,3 +1,5 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
function plot {
param(
$f,
@@ -7,20 +9,20 @@ function plot {
$minx=[math]::Round($minx,1)
$maxx=[math]::Round($maxx,1)
$file = 'C:\temp\plot.xlsx'
rm $file -ErrorAction Ignore
$c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
$file = 'C:\temp\plot.xlsx'
Remove-Item $file -ErrorAction Ignore
# $c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
$(for ($i = $minx; $i -lt $maxx-.1; $i+=.1) {
[pscustomobject]@{
X=$i.ToString("N1")
Y=(&$f $i)
}
}) | Export-Excel $file -Show -AutoNameRange -ExcelChartDefinition $c
}) | Export-Excel $file -Show -AutoNameRange -LineChart -NoLegend #-ExcelChartDefinition $c
}
function pi {[math]::pi}
plot {[math]::Tan($args[0])} (pi) (3*(pi)/2-.01)
plot -f {[math]::Tan($args[0])} -minx (pi) -maxx (3*(pi)/2-.01)

View File

@@ -1,9 +1,9 @@
echo Last7Days LastMonth LastWeek NextMonth NextWeek ThisMonth ThisWeek Today Tomorrow Yesterday |
% {
"Last7Days", "LastMonth", "LastWeek", "NextMonth", "NextWeek", "ThisMonth", "ThisWeek", "Today", "Tomorrow", "Yesterday" |
Foreach-Object {
$text = @"
`$f = ".\testExport.xlsx"
rm `$f -ErrorAction Ignore
remove-item `$f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel `$f -Show -AutoSize -ConditionalText `$(

View File

@@ -1,11 +1,13 @@
$file = ".\conditionalTextFormatting.xlsx"
rm $file -ErrorAction Ignore
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Get-Service |
Select Status, Name, DisplayName, ServiceName |
$file = "$env:temp\conditionalTextFormatting.xlsx"
Remove-Item $file -ErrorAction Ignore
Get-Service |
Select-Object Status, Name, DisplayName, ServiceName |
Export-Excel $file -Show -AutoSize -AutoFilter -ConditionalText $(
New-ConditionalText stop
New-ConditionalText runn darkblue cyan
New-ConditionalText -ConditionalType EndsWith svc wheat green
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat
New-ConditionalText stop #Stop is the condition value, the rule is defaults to 'Contains text' and the default Colors are used
New-ConditionalText runn darkblue cyan #runn is the condition value, the rule is defaults to 'Contains text'; the foregroundColur is darkblue and the background is cyan
New-ConditionalText -ConditionalType EndsWith svc wheat green #the rule here is 'Ends with' and the value is 'svc' the forground is wheat and the background dark green
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat #this is 'Begins with "Windows"' the forground is dark green and the background wheat
)

View File

@@ -1,15 +1,19 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
#Define a "Contains blanks" rule. No format is specified so it default to dark-red text on light-pink background.
$ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks
$data = $(
New-PSItem a b c (echo p1 p2 p3)
New-PSItem
New-PSItem a b c @('p1', 'p2', 'p3')
New-PSItem
New-PSItem d e f
New-PSItem
New-PSItem
New-PSItem g h i
New-PSItem
New-PSItem
New-PSItem g h i
)
$file ="c:\temp\testblanks.xlsx"
$file ="$env:temp\testblanks.xlsx"
rm $file -ErrorAction Ignore
Remove-Item $file -ErrorAction Ignore
#use the conditional format definition created above
$data | Export-Excel $file -show -ConditionalText $ContainsBlanks

View File

@@ -0,0 +1,32 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$path = "$env:temp\test.xlsx"
Remove-Item -Path $path -ErrorAction Ignore
#Export processes, and get an ExcelPackage object representing the file.
$excel = Get-Process |
Select-Object -Property Name,Company,Handles,CPU,PM,NPM,WS |
Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -PassThru
$sheet = $excel.Workbook.Worksheets["Processes"]
#Apply fixed formatting to columns. -NFormat is an alias for numberformat
$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit
$sheet.Column(2) | Set-ExcelRange -Width 29 -WrapText
$sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NFormat "#,###"
Set-ExcelRange -Range -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
Set-ExcelRange -Range $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
#In Set-ExcelRange "-Address" is an alias for "-Range"
Set-ExcelRange -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
#Create a Red Data-bar for the values in Column D
Add-ConditionalFormatting -Worksheet $sheet -Address "D2:D1048576" -DataBarColor Red
# Conditional formatting applies to "Addreses" aliases allow either "Range" or "Address" to be used in Set-ExcelRange or Add-Conditional formatting.
Add-ConditionalFormatting -Worksheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red
foreach ($c in 5..9) {Set-ExcelRange -Address $sheet.Column($c) -AutoFit }
#Create a pivot and save the file.
Export-Excel -ExcelPackage $excel -WorkSheetname "Processes" -IncludePivotChart -ChartType ColumnClustered -NoLegend -PivotRows company -PivotData @{'Name'='Count'} -Show

View File

@@ -1,11 +1,13 @@
$f = ".\testExport.xlsx"
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
rm $f -ErrorAction Ignore
$f = "$env:TEMP\testExport.xlsx"
Remove-Item $f -ErrorAction Ignore
$data = $(
New-PSItem North 111 (echo Region Amount )
New-PSItem East 111
New-PSItem North 111 @( 'Region', 'Amount' )
New-PSItem East 111
New-PSItem West 122
New-PSItem South 200
@@ -14,11 +16,13 @@ $data = $(
New-PSItem SouthWest 136
New-PSItem South 127
New-PSItem NorthByNory 100
New-PSItem NothEast 110
New-PSItem Westerly 120
New-PSItem NorthByNory 100
New-PSItem NothEast 110
New-PSItem Westerly 120
New-PSItem SouthWest 118
)
)
# in this example instead of doing $variable = New-Conditional text <parameters> .... ; Export-excel -ConditionalText $variable <other parameters>
# the syntax is used is Export-excel -ConditionalText (New-Conditional text <parameters>) <other parameters>
#$data | Export-Excel $f -Show -AutoSize -ConditionalText (New-ConditionalText -ConditionalType AboveAverage)

View File

@@ -1,6 +1,6 @@
function Get-DateOffset {
param($days=0)
(Get-Date).AddDays($days).ToShortDateString()
}
@@ -8,7 +8,7 @@ function Get-Number {
Get-Random -Minimum 10 -Maximum 100
}
New-PSItem (Get-DateOffset -7) (Get-Number) 'LastWeek,Last7Days,ThisMonth' (echo Date Amount Label)
New-PSItem (Get-DateOffset -7) (Get-Number) 'LastWeek,Last7Days,ThisMonth' @('Date', 'Amount', 'Label')
New-PSItem (Get-DateOffset) (Get-Number) 'Today,ThisMonth,ThisWeek'
New-PSItem (Get-DateOffset -30) (Get-Number) LastMonth
New-PSItem (Get-DateOffset -1) (Get-Number) 'Yesterday,ThisMonth,ThisWeek'

View File

@@ -1,8 +1,12 @@
rm .\testExport.xlsx -ErrorAction Ignore
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
ps | where Company | select Company, Name, PM, Handles, *mem* |
Remove-Item "$env:TEMP\testExport.xlsx" -ErrorAction Ignore
Export-Excel .\testExport.xlsx -Show -AutoSize -AutoNameRange `
Get-Process | Where-Object Company | Select-Object Company, Name, PM, Handles, *mem* |
#This example creates a 3 Icon set for the values in the "PM column, and Highlights company names (anywhere in the data) with different colors
Export-Excel "$env:TEMP\testExport.xlsx" -Show -AutoSize -AutoNameRange `
-ConditionalFormat $(
New-ConditionalFormattingIconSet -Range "C:C" `
-ConditionalFormat ThreeIconSet -IconType Arrows

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,6 +1,8 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
.\GenDates.ps1 |
Export-Excel $f -Show -AutoSize -ConditionalText $(

View File

@@ -1,23 +1,25 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
Remove-Item $f -ErrorAction Ignore
$data = $(
New-PSItem North 111 (echo Region Amount )
New-PSItem East 11
New-PSItem West 12
New-PSItem South 1000
New-PSItem North 111 @('Region', 'Amount' )
New-PSItem East 11
New-PSItem West 12
New-PSItem South 1000
New-PSItem NorthEast 10
New-PSItem SouthEast 14
New-PSItem SouthWest 13
New-PSItem South 12
New-PSItem NorthEast 10
New-PSItem SouthEast 14
New-PSItem SouthWest 13
New-PSItem South 12
New-PSItem NorthByNory 100
New-PSItem NothEast 110
New-PSItem Westerly 120
New-PSItem SouthWest 11
)
New-PSItem NorthByNory 100
New-PSItem NothEast 110
New-PSItem Westerly 120
New-PSItem SouthWest 11
)
$data | Export-Excel $f -Show -AutoSize -ConditionalText (New-ConditionalText -ConditionalType DuplicateValues)

View File

@@ -0,0 +1,25 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Remove-Item -Path .\test.xlsx -ErrorAction Ignore
$excel = @"
Month,New York City,Austin Texas,Portland Oregon
Jan,39,61,46
Feb,42,65,51
Mar,50,73,56
Apr,62,80,61
May,72,86,67
Jun,80,92,73
Jul,85,95,80
Aug,84,96,80
Sep,76,90,75
Oct,65,82,63
Nov,54,71,52
Dec,44,63,46
"@ | ConvertFrom-csv |
Export-Excel -Path .\test.xlsx -WorkSheetname Sheet1 -AutoNameRange -AutoSize -Title "Monthly Temperatures" -PassThru
$sheet = $excel.Workbook.Worksheets["Sheet1"]
Add-ConditionalFormatting -Worksheet $sheet -Range "B1:D14" -DataBarColor CornflowerBlue
Close-ExcelPackage $excel -Show

View File

@@ -1,16 +1,17 @@
ipmo ImportExcel -Force
$f = ".\testExport.xlsx"
rm $f -ErrorAction Ignore
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
function Get-DateOffset ($days=0) {
$f = ".\testExport.xlsx"
Remove-Item $f -ErrorAction Ignore
function Get-DateOffset ($days=0) {
(Get-Date).AddDays($days).ToShortDateString()
}
$(
New-PSItem (Get-DateOffset -1) (Get-DateOffset 1) (echo Start End)
New-PSItem (Get-DateOffset) (Get-DateOffset 7)
New-PSItem (Get-DateOffset -10) (Get-DateOffset -1)
) |
New-PSItem (Get-DateOffset -1) (Get-DateOffset 1) @("Start", "End")
New-PSItem (Get-DateOffset) (Get-DateOffset 7)
New-PSItem (Get-DateOffset -10) (Get-DateOffset -1)
) |
Export-Excel $f -Show -AutoSize -AutoNameRange -ConditionalText $(
New-ConditionalText -Range Start -ConditionalType Yesterday -ConditionalTextColor Red

View File

@@ -0,0 +1,22 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Remove-Item -Path .\test.xlsx -ErrorAction Ignore
$excel = @"
Month,Sales
Jan,1277
Feb,1003
Mar,1105
Apr,952
May,770
Jun,621
"@ | ConvertFrom-csv |
Export-Excel -Path .\test.xlsx -WorkSheetname Sheet1 -AutoNameRange -PassThru
$sheet = $excel.Workbook.Worksheets["Sheet1"]
Add-ConditionalFormatting -Worksheet $sheet -Range "B1:B7" -DataBarColor LawnGreen
Set-ExcelRange -Address $sheet.Cells["A8"] -Value "Total"
Set-ExcelRange -Address $sheet.Cells["B8"] -Formula "=Sum(Sales)"
Close-ExcelPackage $excel -Show

View File

@@ -1,20 +1,18 @@
cls
ipmo ..\..\ImportExcel.psd1 -Force
try {Import-Module ..\..\ImportExcel.psd1 -Force} catch {throw ; return}
$data = $(
New-PSItem 100 (echo test testx)
New-PSItem 100 @('test', 'testx')
New-PSItem 200
New-PSItem 300
New-PSItem 400
New-PSItem 500
)
$file1 = "tryComparison1.xlsx"
$file2 = "tryComparison2.xlsx"
$file1 = "$env:Temp\tryComparison1.xlsx"
$file2 = "$env:Temp\tryComparison2.xlsx"
rm $file1 -ErrorAction Ignore
rm $file2 -ErrorAction Ignore
Remove-Item -Path $file1 -ErrorAction Ignore
Remove-Item -Path $file2 -ErrorAction Ignore
$data | Export-Excel $file1 -Show -ConditionalText $(
New-ConditionalText -ConditionalType GreaterThan 300
@@ -22,6 +20,6 @@ $data | Export-Excel $file1 -Show -ConditionalText $(
)
$data | Export-Excel $file2 -Show -ConditionalText $(
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
New-ConditionalText -ConditionalType LessThanOrEqual 250 -BackgroundColor cyan
)

View File

@@ -1,3 +1,4 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
ConvertFrom-ExcelToSQLInsert People .\testSQLGen.xlsx

View File

@@ -1,6 +1,6 @@
Import-Module ..\..\ImportExcel.psd1 -Force
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$f = ".\dashboard.xlsx"
$f = "$env:temp\dashboard.xlsx"
Remove-Item $f -ErrorAction Ignore
$data = @"
@@ -22,51 +22,51 @@ $sheet1 = $excel.Workbook.Worksheets["sheet1"]
$sheet1.View.ShowGridLines = $false
$sheet1.View.ShowHeaders = $false
Set-Format -Address $sheet1.Cells["C:C"] -NumberFormat "$#,##0" -WrapText -HorizontalAlignment Center
Set-Format -Address $sheet1.Cells["D:D"] -NumberFormat "#.#0%" -WrapText -HorizontalAlignment Center
Set-ExcelRange -Address $sheet1.Cells["C:C"] -NumberFormat "$#,##0" -WrapText -HorizontalAlignment Center
Set-ExcelRange -Address $sheet1.Cells["D:D"] -NumberFormat "#.#0%" -WrapText -HorizontalAlignment Center
Set-Format -Address $sheet1.Cells["E:E"] -NumberFormat "$#,##0" -WrapText -HorizontalAlignment Center
Set-Format -Address $sheet1.Cells["F:F"] -NumberFormat "#.#0%" -WrapText -HorizontalAlignment Center
Set-ExcelRange -Address $sheet1.Cells["E:E"] -NumberFormat "$#,##0" -WrapText -HorizontalAlignment Center
Set-ExcelRange -Address $sheet1.Cells["F:F"] -NumberFormat "#.#0%" -WrapText -HorizontalAlignment Center
Set-Format -Address $sheet1.Cells["G:H"] -WrapText -HorizontalAlignment Center
Set-ExcelRange -Address $sheet1.Cells["G:H"] -WrapText -HorizontalAlignment Center
## Insert Rows/Columns
$sheet1.InsertRow(1, 1)
foreach ($col in Write-Output 2 4 6 8 10 12 14) {
foreach ($col in @(2, 4, 6, 8, 10, 12, 14)) {
$sheet1.InsertColumn($col, 1)
$sheet1.Column($col).width = .75
}
Set-Format -Address $sheet1.Cells["E:E"] -Width 12
Set-Format -Address $sheet1.Cells["I:I"] -Width 12
Set-ExcelRange -Address $sheet1.Cells["E:E"] -Width 12
Set-ExcelRange -Address $sheet1.Cells["I:I"] -Width 12
$BorderBottom = "Thick"
$BorderColor = "Black"
Set-Format -Address $sheet1.Cells["A2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-ExcelRange -Address $sheet1.Cells["A2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["C2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["E2:G2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["I2:K2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["M2:O2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-ExcelRange -Address $sheet1.Cells["C2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-ExcelRange -Address $sheet1.Cells["E2:G2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-ExcelRange -Address $sheet1.Cells["I2:K2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-ExcelRange -Address $sheet1.Cells["M2:O2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["A2:C8"] -FontColor GrayText
Set-ExcelRange -Address $sheet1.Cells["A2:C8"] -FontColor Gray
$HorizontalAlignment = "Center"
Set-Format -Address $sheet1.Cells["F1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Revenue
Set-Format -Address $sheet1.Cells["J1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Margin
Set-Format -Address $sheet1.Cells["N1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Passenger
Set-ExcelRange -Address $sheet1.Cells["F1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Revenue
Set-ExcelRange -Address $sheet1.Cells["J1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Margin
Set-ExcelRange -Address $sheet1.Cells["N1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Passenger
Set-Format -Address $sheet1.Cells["E2"] -Value '($)'
Set-Format -Address $sheet1.Cells["G2"] -Value '%'
Set-Format -Address $sheet1.Cells["I2"] -Value '($)'
Set-Format -Address $sheet1.Cells["K2"] -Value '%'
Set-ExcelRange -Address $sheet1.Cells["E2"] -Value '($)'
Set-ExcelRange -Address $sheet1.Cells["G2"] -Value '%'
Set-ExcelRange -Address $sheet1.Cells["I2"] -Value '($)'
Set-ExcelRange -Address $sheet1.Cells["K2"] -Value '%'
Set-Format -Address $sheet1.Cells["C10"] -HorizontalAlignment Right -Bold -Value "Grand Total Calculation"
Set-Format -Address $sheet1.Cells["E10"] -Formula "=Sum(E3:E8)" -Bold
Set-Format -Address $sheet1.Cells["I10"] -Formula "=Sum(I3:I8)" -Bold
Set-Format -Address $sheet1.Cells["M10"] -Formula "=Sum(M3:M8)" -Bold
Set-Format -Address $sheet1.Cells["O10"] -Formula "=Sum(O3:O8)" -Bold
Set-ExcelRange -Address $sheet1.Cells["C10"] -HorizontalAlignment Right -Bold -Value "Grand Total Calculation"
Set-ExcelRange -Address $sheet1.Cells["E10"] -Formula "=Sum(E3:E8)" -Bold
Set-ExcelRange -Address $sheet1.Cells["I10"] -Formula "=Sum(I3:I8)" -Bold
Set-ExcelRange -Address $sheet1.Cells["M10"] -Formula "=Sum(M3:M8)" -Bold
Set-ExcelRange -Address $sheet1.Cells["O10"] -Formula "=Sum(O3:O8)" -Bold
Close-ExcelPackage $excel -Show
Close-ExcelPackage $excel -Show

View File

@@ -0,0 +1,89 @@
<#
This is an example on how to customize Export-Excel to your liking.
First select a name for your function, in ths example its "Out-Excel" you can even set the name to "Export-Excel".
You can customize the following things:
1. To add parameters to the function define them in "param()", here I added "Preset1" and "Preset2".
The parameters need to be removed after use (see comments and code below).
2. To remove parameters from the function add them to the list under "$_.Name -notmatch", I removed "Now".
3. Add your custom code, here I defined what the Presets do:
Preset1 configure the TableStyle, name the table depending on WorksheetName and FreezeTopRow.
Preset2 will set AutoFilter and add the Title "Daily Report".
(see comments and code below).
#>
function Out-Excel {
[CmdletBinding(DefaultParameterSetName = 'Default')]
param(
[switch]
${Preset1},
[switch]
${Preset2}
)
DynamicParam {
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
foreach ($P in (Get-Command -Name Export-Excel).Parameters.values.where( { $_.Name -notmatch 'Verbose|Debug|Action$|Variable$|Buffer$|Now' })) {
$paramDictionary.Add($P.Name, [System.Management.Automation.RuntimeDefinedParameter]::new( $P.Name, $P.ParameterType, $P.Attributes ) )
}
return $paramDictionary
}
begin {
try {
# Run you custom code here if it need to run before calling Export-Excel.
$PSBoundParameters['Now'] = $true
if ($Preset1) {
$PSBoundParameters['TableStyle'] = 'Medium7'
$PSBoundParameters['FreezeTopRow'] = $true
if ($PSBoundParameters['WorksheetName'] -and -not $PSBoundParameters['TableName']) {
$PSBoundParameters['TableName'] = $PSBoundParameters['WorksheetName'] + '_Table'
}
}
elseif ($Preset2) {
$PSBoundParameters['Title'] = 'Daily Report'
$PSBoundParameters['AutoFilter'] = $true
}
# Remove the extra params we added as Export-Excel will not know what to do with them:
$null = $PSBoundParameters.Remove('Preset1')
$null = $PSBoundParameters.Remove('Preset2')
# The rest of the code was auto generated.
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Excel', [System.Management.Automation.CommandTypes]::Function)
# You can add a pipe after @PSBoundParameters to manipulate the output.
$scriptCmd = { & $wrappedCmd @PSBoundParameters }
$steppablePipeline = $scriptCmd.GetSteppablePipeline()
$steppablePipeline.Begin($PSCmdlet)
}
catch {
throw
}
}
process {
try {
$steppablePipeline.Process($_)
}
catch {
throw
}
}
end {
try {
$steppablePipeline.End()
}
catch {
throw
}
}
<#
.ForwardHelpTargetName Export-Excel
.ForwardHelpCategory Function
#>
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,31 @@
# DSUM
# Adds the numbers in a field (column) of records in a list or database that match conditions that you specify.
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Color,Date,Sales
Red,1/15/2018,250
Blue,1/15/2018,200
Red,1/16/2018,175
Blue,1/16/2018,325
Red,1/17/2018,150
Blue,1/17/2018,300
"@
$xl = Export-Excel -InputObject $data -Path $xlfile -AutoSize -AutoFilter -TableName SalesInfo -AutoNameRange -PassThru
$databaseAddress = $xl.Sheet1.Dimension.Address
Set-Format -Worksheet $xl.Sheet1 -Range C:C -NumberFormat '$##0'
Set-Format -Worksheet $xl.Sheet1 -Range E1 -Value Color
Set-Format -Worksheet $xl.Sheet1 -Range F1 -Value Date
Set-Format -Worksheet $xl.Sheet1 -Range G1 -Value Sales
Set-Format -Worksheet $xl.Sheet1 -Range E2 -Value Red
Set-Format -Worksheet $xl.Sheet1 -Range E4 -Value Sales
Set-Format -Worksheet $xl.Sheet1 -Range F4 -Formula ('=DSUM({0},"Sales",E1:G2)' -f $databaseAddress) -NumberFormat '$##0'
Close-ExcelPackage $xl -Show

View File

@@ -0,0 +1,19 @@
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Fruit,Amount
Apples,50
Oranges,20
Bananas,60
Lemons,40
"@
$xl = Export-Excel -InputObject $data -Path $xlfile -PassThru -AutoSize
Set-ExcelRange -Worksheet $xl.Sheet1 -Range D2 -BackgroundColor LightBlue -Value Apples
$Rows = $xl.Sheet1.Dimension.Rows
Set-ExcelRange -Worksheet $xl.Sheet1 -Range E2 -Formula "=VLookup(D2,A2:B$($Rows),2,FALSE)"
Close-ExcelPackage $xl -Show

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -0,0 +1,85 @@
#region Setup
<#
This examples demos three types of validation:
* Creating a list using a PowerShell array
* Creating a list data from another Excel Worksheet
* Creating a rule for numbers to be between 0 an 10000
Run the script then try"
* Add random data in Column B
* Then choose from the drop down list
* Add random data in Column C
* Then choose from the drop down list
* Add .01 in column F
#>
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$path = "$Env:TEMP\DataValidation.xlsx"
Remove-Item $path -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv -InputObject @"
ID,Region,Product,Quantity,Price
12001,North,Nails,37,3.99
12002,South,Hammer,5,12.10
12003,East,Saw,12,15.37
12010,West,Drill,20,8
12011,North,Crowbar,7,23.48
"@
# Export the raw data
$excelPackage = $Data |
Export-Excel -WorksheetName "Sales" -Path $path -PassThru
# Creates a sheet with data that will be used in a validation rule
$excelPackage = @('Chisel', 'Crowbar', 'Drill', 'Hammer', 'Nails', 'Saw', 'Screwdriver', 'Wrench') |
Export-excel -ExcelPackage $excelPackage -WorksheetName Values -PassThru
#endregion
#region Creating a list using a PowerShell array
$ValidationParams = @{
Worksheet = $excelPackage.sales
ShowErrorMessage = $true
ErrorStyle = 'stop'
ErrorTitle = 'Invalid Data'
}
$MoreValidationParams = @{
Range = 'B2:B1001'
ValidationType = 'List'
ValueSet = @('North', 'South', 'East', 'West')
ErrorBody = "You must select an item from the list."
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Creating a list data from another Excel Worksheet
$MoreValidationParams = @{
Range = 'C2:C1001'
ValidationType = 'List'
Formula = 'values!$a$1:$a$10'
ErrorBody = "You must select an item from the list.`r`nYou can add to the list on the values page" #Bucket
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Creating a rule for numbers to be between 0 an 10000
$MoreValidationParams = @{
Range = 'F2:F1001'
ValidationType = 'Integer'
Operator = 'between'
Value = 0
Value2 = 10000
ErrorBody = 'Quantity must be a whole number between 0 and 10000'
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Close Package
Close-ExcelPackage -ExcelPackage $excelPackage -Show
#endregion

View File

@@ -0,0 +1,6 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
ConvertFrom-ExcelToSQLInsert -TableName "Movies" -Path ".\Movies.xlsx" -ConvertEmptyStringsToNull
''
'# UseMSSQLSyntax'
ConvertFrom-ExcelToSQLInsert -UseMSSQLSyntax -TableName "Movies" -Path ".\Movies.xlsx" -ConvertEmptyStringsToNull

Binary file not shown.

View File

@@ -1,15 +1,17 @@
param ($fibonacciDigits=10)
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$file = "fib.xlsx"
rm "fib.xlsx" -ErrorAction Ignore
Remove-Item "fib.xlsx" -ErrorAction Ignore
$(
New-PSItem 0
New-PSItem 1
(
2..$fibonacciDigits |
ForEach {
ForEach-Object {
New-PSItem ('=a{0}+a{1}' -f ($_+1),$_)
}
)

View File

@@ -1,12 +1,16 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlfile = "$env:temp\testFmt.xlsx"
Get-Process |
Select-Object Company,Handles,PM, NPM|
Select-Object Company,Handles,PM, NPM|
Export-Excel $xlfile -Show -AutoSize -CellStyleSB {
param(
$workSheet,
$totalRows,
$lastColumn
)
Set-CellStyle $workSheet 1 $LastColumn Solid Cyan
foreach($row in (2..$totalRows | Where-Object {$_ % 2 -eq 0})) {

View File

@@ -0,0 +1,24 @@
$data = ConvertFrom-Csv @'
Item,Quantity,Price,Total Cost
Footballs,9,21.95,197.55
Cones,36,7.99,287.64
Shin Guards,14,10.95,153.3
Turf Shoes,22,79.95,1758.9
Baseballs,68,7.99,543.32
Baseball Gloves,31,65.00,2015.00
Baseball Bats,38,159.00,6042.00
'@
$f = "$env:TEMP\styles.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pkg = $data | Export-Excel -Path $f -AutoSize -PassThru
$ws = $pkg.Workbook.Worksheets["Sheet1"]
Set-ExcelRange -Worksheet $ws -Range "A2:C6" -BackgroundColor PeachPuff -FontColor Purple -FontSize 12 -Width 12
Set-ExcelRange -Worksheet $ws -Range "D2:D6" -BackgroundColor WhiteSmoke -FontColor Orange -Bold -FontSize 12 -Width 12
Set-ExcelRange -Worksheet $ws -Range "A1:D1" -BackgroundColor BlueViolet -FontColor Wheat -FontSize 12 -Width 12
Set-ExcelRange -Worksheet $ws -Range "A:A" -Width 15
Close-ExcelPackage -ExcelPackage $pkg -Show

View File

@@ -1,15 +1,20 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlfile = "$env:temp\testFmt.xlsx"
Remove-Item $xlfile -ErrorAction Ignore
$RandomStyle = {
param(
$workSheet,
$totalRows,
$lastColumn
)
)
2..$totalRows | ForEach-Object{
Set-CellStyle $workSheet $_ $LastColumn Solid (Write-Output LightGreen Gray Red|Get-Random)
Set-CellStyle $workSheet $_ $LastColumn Solid (Get-Random @("LightGreen", "Gray", "Red"))
}
}
Get-Process |
Select-Object Company,Handles,PM, NPM|
Select-Object Company,Handles,PM, NPM|
Export-Excel $xlfile -Show -AutoSize -CellStyleSB $RandomStyle

View File

@@ -0,0 +1,38 @@
if(!(Get-Command ig -ErrorAction SilentlyContinue)) {
"Use ``Install-Module NameIT`` to get the needed module from the gallery to support running this script"
return
}
$sign=@{sign=@( "+", "-" )}
$location=@{location=@("Atlanta", "Newark", "Washington", "Chicago", "Philadelphia", "Houston", "Phoneix")}
$(1..6 | Foreach-Object {
$from=$to=""
while($from -eq $to) {
$from=ig "[location]" -CustomData $location
$to=ig "[location]" -CustomData $location
}
[double]$a=ig "########"
[double]$b=ig ".####"
[double]$c=ig "#######"
[double]$d=ig "[sign].##" -CustomData $sign
[double]$e=ig "###"
[double]$f=ig "[sign]##" -CustomData $sign
#"{0},{1},{2},{3},{4},{5},{6},{7}" -f $from, $to, $a, $b, $c, $d, $e, $f
[PSCustomObject][Ordered]@{
From=$from
To=$to
RDollars=$a
RPercent=$b
MDollars=$c
MPercent=$d
Revenue=$e
Margin=$f
}
} | ConvertTo-Csv -NoTypeInformation) -replace '"','' # | Export-Excel

View File

@@ -0,0 +1,101 @@
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
French,24/06/2018,8,Carlos Sainz,7,Renault,4
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
1 Race Date FinishPosition Driver GridPosition Team Points
2 Australian 25/03/2018 1 Sebastian Vettel 3 Ferrari 25
3 Australian 25/03/2018 2 Lewis Hamilton 1 Mercedes 18
4 Australian 25/03/2018 3 Kimi Räikkönen 2 Ferrari 15
5 Australian 25/03/2018 4 Daniel Ricciardo 8 Red Bull Racing-TAG Heuer 12
6 Australian 25/03/2018 5 Fernando Alonso 10 McLaren-Renault 10
7 Australian 25/03/2018 6 Max Verstappen 4 Red Bull Racing-TAG Heuer 8
8 Australian 25/03/2018 7 Nico Hülkenberg 7 Renault 6
9 Australian 25/03/2018 8 Valtteri Bottas 15 Mercedes 4
10 Australian 25/03/2018 9 Stoffel Vandoorne 11 McLaren-Renault 2
11 Australian 25/03/2018 10 Carlos Sainz 9 Renault 1
12 Bahrain 08/04/2018 1 Sebastian Vettel 1 Ferrari 25
13 Bahrain 08/04/2018 2 Valtteri Bottas 3 Mercedes 18
14 Bahrain 08/04/2018 3 Lewis Hamilton 9 Mercedes 15
15 Bahrain 08/04/2018 4 Pierre Gasly 5 STR-Honda 12
16 Bahrain 08/04/2018 5 Kevin Magnussen 6 Haas-Ferrari 10
17 Bahrain 08/04/2018 6 Nico Hülkenberg 7 Renault 8
18 Bahrain 08/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
19 Bahrain 08/04/2018 8 Stoffel Vandoorne 14 McLaren-Renault 4
20 Bahrain 08/04/2018 9 Marcus Ericsson 17 Sauber-Ferrari 2
21 Bahrain 08/04/2018 10 Esteban Ocon 8 Force India-Mercedes 1
22 Chinese 15/04/2018 1 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 25
23 Chinese 15/04/2018 2 Valtteri Bottas 3 Mercedes 18
24 Chinese 15/04/2018 3 Kimi Räikkönen 2 Ferrari 15
25 Chinese 15/04/2018 4 Lewis Hamilton 4 Mercedes 12
26 Chinese 15/04/2018 5 Max Verstappen 5 Red Bull Racing-TAG Heuer 10
27 Chinese 15/04/2018 6 Nico Hülkenberg 7 Renault 8
28 Chinese 15/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
29 Chinese 15/04/2018 8 Sebastian Vettel 1 Ferrari 4
30 Chinese 15/04/2018 9 Carlos Sainz 9 Renault 2
31 Chinese 15/04/2018 10 Kevin Magnussen 11 Haas-Ferrari 1
32 Azerbaijan 29/04/2018 1 Lewis Hamilton 2 Mercedes 25
33 Azerbaijan 29/04/2018 2 Kimi Räikkönen 6 Ferrari 18
34 Azerbaijan 29/04/2018 3 Sergio Pérez 8 Force India-Mercedes 15
35 Azerbaijan 29/04/2018 4 Sebastian Vettel 1 Ferrari 12
36 Azerbaijan 29/04/2018 5 Carlos Sainz 9 Renault 10
37 Azerbaijan 29/04/2018 6 Charles Leclerc 13 Sauber-Ferrari 8
38 Azerbaijan 29/04/2018 7 Fernando Alonso 12 McLaren-Renault 6
39 Azerbaijan 29/04/2018 8 Lance Stroll 10 Williams-Mercedes 4
40 Azerbaijan 29/04/2018 9 Stoffel Vandoorne 16 McLaren-Renault 2
41 Azerbaijan 29/04/2018 10 Brendon Hartley 19 STR-Honda 1
42 Spanish 13/05/2018 1 Lewis Hamilton 1 Mercedes 25
43 Spanish 13/05/2018 2 Valtteri Bottas 2 Mercedes 18
44 Spanish 13/05/2018 3 Max Verstappen 5 Red Bull Racing-TAG Heuer 15
45 Spanish 13/05/2018 4 Sebastian Vettel 3 Ferrari 12
46 Spanish 13/05/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
47 Spanish 13/05/2018 6 Kevin Magnussen 7 Haas-Ferrari 8
48 Spanish 13/05/2018 7 Carlos Sainz 9 Renault 6
49 Spanish 13/05/2018 8 Fernando Alonso 8 McLaren-Renault 4
50 Spanish 13/05/2018 9 Sergio Pérez 15 Force India-Mercedes 2
51 Spanish 13/05/2018 10 Charles Leclerc 14 Sauber-Ferrari 1
52 Monaco 27/05/2018 1 Daniel Ricciardo 1 Red Bull Racing-TAG Heuer 25
53 Monaco 27/05/2018 2 Sebastian Vettel 2 Ferrari 18
54 Monaco 27/05/2018 3 Lewis Hamilton 3 Mercedes 15
55 Monaco 27/05/2018 4 Kimi Räikkönen 4 Ferrari 12
56 Monaco 27/05/2018 5 Valtteri Bottas 5 Mercedes 10
57 Monaco 27/05/2018 6 Esteban Ocon 6 Force India-Mercedes 8
58 Monaco 27/05/2018 7 Pierre Gasly 10 STR-Honda 6
59 Monaco 27/05/2018 8 Nico Hülkenberg 11 Renault 4
60 Monaco 27/05/2018 9 Max Verstappen 20 Red Bull Racing-TAG Heuer 2
61 Monaco 27/05/2018 10 Carlos Sainz 8 Renault 1
62 Canadian 10/06/2018 1 Sebastian Vettel 1 Ferrari 25
63 Canadian 10/06/2018 2 Valtteri Bottas 2 Mercedes 18
64 Canadian 10/06/2018 3 Max Verstappen 3 Red Bull Racing-TAG Heuer 15
65 Canadian 10/06/2018 4 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 12
66 Canadian 10/06/2018 5 Lewis Hamilton 4 Mercedes 10
67 Canadian 10/06/2018 6 Kimi Räikkönen 5 Ferrari 8
68 Canadian 10/06/2018 7 Nico Hülkenberg 7 Renault 6
69 Canadian 10/06/2018 8 Carlos Sainz 9 Renault 4
70 Canadian 10/06/2018 9 Esteban Ocon 8 Force India-Mercedes 2
71 Canadian 10/06/2018 10 Charles Leclerc 13 Sauber-Ferrari 1
72 French 24/06/2018 1 Lewis Hamilton 1 Mercedes 25
73 French 24/06/2018 2 Max Verstappen 4 Red Bull Racing-TAG Heuer 18
74 French 24/06/2018 3 Kimi Räikkönen 6 Ferrari 15
75 French 24/06/2018 4 Daniel Ricciardo 5 Red Bull Racing-TAG Heuer 12
76 French 24/06/2018 5 Sebastian Vettel 3 Ferrari 10
77 French 24/06/2018 6 Kevin Magnussen 9 Haas-Ferrari 8
78 French 24/06/2018 7 Valtteri Bottas 2 Mercedes 6
79 French 24/06/2018 8 Carlos Sainz 7 Renault 4
80 French 24/06/2018 9 Nico Hülkenberg 12 Renault 2
81 French 24/06/2018 10 Charles Leclerc 8 Sauber-Ferrari 1
82 Austrian 01/07/2018 1 Max Verstappen 4 Red Bull Racing-TAG Heuer 25
83 Austrian 01/07/2018 2 Kimi Räikkönen 3 Ferrari 18
84 Austrian 01/07/2018 3 Sebastian Vettel 6 Ferrari 15
85 Austrian 01/07/2018 4 Romain Grosjean 5 Haas-Ferrari 12
86 Austrian 01/07/2018 5 Kevin Magnussen 8 Haas-Ferrari 10
87 Austrian 01/07/2018 6 Esteban Ocon 11 Force India-Mercedes 8
88 Austrian 01/07/2018 7 Sergio Pérez 15 Force India-Mercedes 6
89 Austrian 01/07/2018 8 Fernando Alonso 20 McLaren-Renault 4
90 Austrian 01/07/2018 9 Charles Leclerc 17 Sauber-Ferrari 2
91 Austrian 01/07/2018 10 Marcus Ericsson 18 Sauber-Ferrari 1
92 British 08/07/2018 1 Sebastian Vettel 2 Ferrari 25
93 British 08/07/2018 2 Lewis Hamilton 1 Mercedes 18
94 British 08/07/2018 3 Kimi Räikkönen 3 Ferrari 15
95 British 08/07/2018 4 Valtteri Bottas 4 Mercedes 12
96 British 08/07/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
97 British 08/07/2018 6 Nico Hülkenberg 11 Renault 8
98 British 08/07/2018 7 Esteban Ocon 10 Force India-Mercedes 6
99 British 08/07/2018 8 Fernando Alonso 13 McLaren-Renault 4
100 British 08/07/2018 9 Kevin Magnussen 7 Haas-Ferrari 2
101 British 08/07/2018 10 Sergio Pérez 12 Force India-Mercedes 1

View File

@@ -0,0 +1,10 @@
$xlfile = "$env:TEMP\Points.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Points `
-PivotRows Driver, Date -PivotData @{Points = "SUM"} -GroupDateRow Date -GroupDatePart Years, Months
Import-Csv "$PSScriptRoot\First10Races.csv" |
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition

View File

@@ -0,0 +1,10 @@
$xlfile = "$env:TEMP\Places.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Places `
-PivotRows Driver, FinishPosition -PivotData @{Date = "Count"} -GroupNumericRow FinishPosition -GroupNumericMin 1 -GroupNumericMax 25 -GroupNumericInterval 3
Import-Csv "$PSScriptRoot\First10Races.csv" |
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition

View File

@@ -0,0 +1,39 @@
$data = ConvertFrom-Csv @"
Timestamp,Tenant
10/29/2018 3:00:00.123,1
10/29/2018 3:00:10.456,1
10/29/2018 3:01:20.389,1
10/29/2018 3:00:30.222,1
10/29/2018 3:00:40.143,1
10/29/2018 3:00:50.809,1
10/29/2018 3:01:00.193,1
10/29/2018 3:01:10.555,1
10/29/2018 3:01:20.739,1
10/29/2018 3:01:30.912,1
10/29/2018 3:01:40.989,1
10/29/2018 3:01:50.545,1
10/29/2018 3:02:00.999,1
"@ | Select-Object @{n = 'Timestamp'; e = {Get-date $_.timestamp}}, tenant, @{n = 'Bucket'; e = { - (Get-date $_.timestamp).Second % 30}}
$f = "$env:temp\pivottest.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pivotDefParams = @{
PivotTableName = 'Timestamp Buckets'
PivotRows = @('Timestamp', 'Tenant')
PivotData = @{'Bucket' = 'count'}
GroupDateRow = 'TimeStamp'
GroupDatePart = @('Hours', 'Minutes')
Activate = $true
}
$excelParams = @{
PivotTableDefinition = New-PivotTableDefinition @pivotDefParams
Path = $f
WorkSheetname = "Log Data"
AutoSize = $true
AutoFilter = $true
Show = $true
}
$data | Export-Excel @excelParams

View File

@@ -0,0 +1,101 @@
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
French,24/06/2018,8,Carlos Sainz,7,Renault,4
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
1 Race Date FinishPosition Driver GridPosition Team Points
2 Australian 25/03/2018 1 Sebastian Vettel 3 Ferrari 25
3 Australian 25/03/2018 2 Lewis Hamilton 1 Mercedes 18
4 Australian 25/03/2018 3 Kimi Räikkönen 2 Ferrari 15
5 Australian 25/03/2018 4 Daniel Ricciardo 8 Red Bull Racing-TAG Heuer 12
6 Australian 25/03/2018 5 Fernando Alonso 10 McLaren-Renault 10
7 Australian 25/03/2018 6 Max Verstappen 4 Red Bull Racing-TAG Heuer 8
8 Australian 25/03/2018 7 Nico Hülkenberg 7 Renault 6
9 Australian 25/03/2018 8 Valtteri Bottas 15 Mercedes 4
10 Australian 25/03/2018 9 Stoffel Vandoorne 11 McLaren-Renault 2
11 Australian 25/03/2018 10 Carlos Sainz 9 Renault 1
12 Bahrain 08/04/2018 1 Sebastian Vettel 1 Ferrari 25
13 Bahrain 08/04/2018 2 Valtteri Bottas 3 Mercedes 18
14 Bahrain 08/04/2018 3 Lewis Hamilton 9 Mercedes 15
15 Bahrain 08/04/2018 4 Pierre Gasly 5 STR-Honda 12
16 Bahrain 08/04/2018 5 Kevin Magnussen 6 Haas-Ferrari 10
17 Bahrain 08/04/2018 6 Nico Hülkenberg 7 Renault 8
18 Bahrain 08/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
19 Bahrain 08/04/2018 8 Stoffel Vandoorne 14 McLaren-Renault 4
20 Bahrain 08/04/2018 9 Marcus Ericsson 17 Sauber-Ferrari 2
21 Bahrain 08/04/2018 10 Esteban Ocon 8 Force India-Mercedes 1
22 Chinese 15/04/2018 1 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 25
23 Chinese 15/04/2018 2 Valtteri Bottas 3 Mercedes 18
24 Chinese 15/04/2018 3 Kimi Räikkönen 2 Ferrari 15
25 Chinese 15/04/2018 4 Lewis Hamilton 4 Mercedes 12
26 Chinese 15/04/2018 5 Max Verstappen 5 Red Bull Racing-TAG Heuer 10
27 Chinese 15/04/2018 6 Nico Hülkenberg 7 Renault 8
28 Chinese 15/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
29 Chinese 15/04/2018 8 Sebastian Vettel 1 Ferrari 4
30 Chinese 15/04/2018 9 Carlos Sainz 9 Renault 2
31 Chinese 15/04/2018 10 Kevin Magnussen 11 Haas-Ferrari 1
32 Azerbaijan 29/04/2018 1 Lewis Hamilton 2 Mercedes 25
33 Azerbaijan 29/04/2018 2 Kimi Räikkönen 6 Ferrari 18
34 Azerbaijan 29/04/2018 3 Sergio Pérez 8 Force India-Mercedes 15
35 Azerbaijan 29/04/2018 4 Sebastian Vettel 1 Ferrari 12
36 Azerbaijan 29/04/2018 5 Carlos Sainz 9 Renault 10
37 Azerbaijan 29/04/2018 6 Charles Leclerc 13 Sauber-Ferrari 8
38 Azerbaijan 29/04/2018 7 Fernando Alonso 12 McLaren-Renault 6
39 Azerbaijan 29/04/2018 8 Lance Stroll 10 Williams-Mercedes 4
40 Azerbaijan 29/04/2018 9 Stoffel Vandoorne 16 McLaren-Renault 2
41 Azerbaijan 29/04/2018 10 Brendon Hartley 19 STR-Honda 1
42 Spanish 13/05/2018 1 Lewis Hamilton 1 Mercedes 25
43 Spanish 13/05/2018 2 Valtteri Bottas 2 Mercedes 18
44 Spanish 13/05/2018 3 Max Verstappen 5 Red Bull Racing-TAG Heuer 15
45 Spanish 13/05/2018 4 Sebastian Vettel 3 Ferrari 12
46 Spanish 13/05/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
47 Spanish 13/05/2018 6 Kevin Magnussen 7 Haas-Ferrari 8
48 Spanish 13/05/2018 7 Carlos Sainz 9 Renault 6
49 Spanish 13/05/2018 8 Fernando Alonso 8 McLaren-Renault 4
50 Spanish 13/05/2018 9 Sergio Pérez 15 Force India-Mercedes 2
51 Spanish 13/05/2018 10 Charles Leclerc 14 Sauber-Ferrari 1
52 Monaco 27/05/2018 1 Daniel Ricciardo 1 Red Bull Racing-TAG Heuer 25
53 Monaco 27/05/2018 2 Sebastian Vettel 2 Ferrari 18
54 Monaco 27/05/2018 3 Lewis Hamilton 3 Mercedes 15
55 Monaco 27/05/2018 4 Kimi Räikkönen 4 Ferrari 12
56 Monaco 27/05/2018 5 Valtteri Bottas 5 Mercedes 10
57 Monaco 27/05/2018 6 Esteban Ocon 6 Force India-Mercedes 8
58 Monaco 27/05/2018 7 Pierre Gasly 10 STR-Honda 6
59 Monaco 27/05/2018 8 Nico Hülkenberg 11 Renault 4
60 Monaco 27/05/2018 9 Max Verstappen 20 Red Bull Racing-TAG Heuer 2
61 Monaco 27/05/2018 10 Carlos Sainz 8 Renault 1
62 Canadian 10/06/2018 1 Sebastian Vettel 1 Ferrari 25
63 Canadian 10/06/2018 2 Valtteri Bottas 2 Mercedes 18
64 Canadian 10/06/2018 3 Max Verstappen 3 Red Bull Racing-TAG Heuer 15
65 Canadian 10/06/2018 4 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 12
66 Canadian 10/06/2018 5 Lewis Hamilton 4 Mercedes 10
67 Canadian 10/06/2018 6 Kimi Räikkönen 5 Ferrari 8
68 Canadian 10/06/2018 7 Nico Hülkenberg 7 Renault 6
69 Canadian 10/06/2018 8 Carlos Sainz 9 Renault 4
70 Canadian 10/06/2018 9 Esteban Ocon 8 Force India-Mercedes 2
71 Canadian 10/06/2018 10 Charles Leclerc 13 Sauber-Ferrari 1
72 French 24/06/2018 1 Lewis Hamilton 1 Mercedes 25
73 French 24/06/2018 2 Max Verstappen 4 Red Bull Racing-TAG Heuer 18
74 French 24/06/2018 3 Kimi Räikkönen 6 Ferrari 15
75 French 24/06/2018 4 Daniel Ricciardo 5 Red Bull Racing-TAG Heuer 12
76 French 24/06/2018 5 Sebastian Vettel 3 Ferrari 10
77 French 24/06/2018 6 Kevin Magnussen 9 Haas-Ferrari 8
78 French 24/06/2018 7 Valtteri Bottas 2 Mercedes 6
79 French 24/06/2018 8 Carlos Sainz 7 Renault 4
80 French 24/06/2018 9 Nico Hülkenberg 12 Renault 2
81 French 24/06/2018 10 Charles Leclerc 8 Sauber-Ferrari 1
82 Austrian 01/07/2018 1 Max Verstappen 4 Red Bull Racing-TAG Heuer 25
83 Austrian 01/07/2018 2 Kimi Räikkönen 3 Ferrari 18
84 Austrian 01/07/2018 3 Sebastian Vettel 6 Ferrari 15
85 Austrian 01/07/2018 4 Romain Grosjean 5 Haas-Ferrari 12
86 Austrian 01/07/2018 5 Kevin Magnussen 8 Haas-Ferrari 10
87 Austrian 01/07/2018 6 Esteban Ocon 11 Force India-Mercedes 8
88 Austrian 01/07/2018 7 Sergio Pérez 15 Force India-Mercedes 6
89 Austrian 01/07/2018 8 Fernando Alonso 20 McLaren-Renault 4
90 Austrian 01/07/2018 9 Charles Leclerc 17 Sauber-Ferrari 2
91 Austrian 01/07/2018 10 Marcus Ericsson 18 Sauber-Ferrari 1
92 British 08/07/2018 1 Sebastian Vettel 2 Ferrari 25
93 British 08/07/2018 2 Lewis Hamilton 1 Mercedes 18
94 British 08/07/2018 3 Kimi Räikkönen 3 Ferrari 15
95 British 08/07/2018 4 Valtteri Bottas 4 Mercedes 12
96 British 08/07/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
97 British 08/07/2018 6 Nico Hülkenberg 11 Renault 8
98 British 08/07/2018 7 Esteban Ocon 10 Force India-Mercedes 6
99 British 08/07/2018 8 Fernando Alonso 13 McLaren-Renault 4
100 British 08/07/2018 9 Kevin Magnussen 7 Haas-Ferrari 2
101 British 08/07/2018 10 Sergio Pérez 12 Force India-Mercedes 1

View File

@@ -1,7 +1,8 @@
#$(
# New-PSItem 'Every Man a King' http://orisonswettmarden.wwwhubs.com/ccount/click.php?id=2
# New-PSItem 'Be Good to Yourself' http://orisonswettmarden.wwwhubs.com/ccount/click.php?id=3
# New-PSItem 'Character : The Grandest Thing in the World' http://orisonswettmarden.wwwhubs.com/ccount/click.php?id=4
# New-PSItem 'The Conquest of Worry' http://orisonswettmarden.wwwhubs.com/ccount/click.php?id=5
# New-PSItem 'Success Nuggets' http://orisonswettmarden.wwwhubs.com/ccount/click.php?id=6
#) | Export-Excel hyperlinks.xlsx -Show -AutoSize
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
@"
site,link
google,http://www.google.com
stackoverflow,http://stackoverflow.com
microsoft,http://microsoft.com
"@ | ConvertFrom-Csv | Export-Excel

View File

@@ -0,0 +1,27 @@
#First 10 races is a CSV file containing the top 10 finishers for the first 10 Formula one races of 2018. Read this file and group the results by race
#We will create links to each race in the first 10 rows of the spreadSheet
#The next row will be column labels
#After that will come a block for each race.
#Read the data, and decide how much space to leave for the hyperlinks
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
$results = Import-Csv -Path $dataPath | Group-Object -Property RACE
$topRow = $lastDataRow = 1 + $results.Count
#Export the first row of the first group (race) with headers.
$path = "$env:TEMP\Results.xlsx"
Remove-Item -Path $path -ErrorAction SilentlyContinue
$excel = $results[0].Group[0] | Export-Excel -Path $path -StartRow $TopRow -BoldTopRow -PassThru
#export each group (race) below the last one, without headers, and create a range for each using the group (Race) name
foreach ($r in $results) {
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow +1) -RangeName $R.Name -PassThru -AutoSize
$lastDataRow += $R.Group.Count
}
#Create a hyperlink for each property with display text of "RaceNameGP" which links to the range created when the rows were exported a
$results | ForEach-Object {(New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList "Sheet1!$($_.Name)" , "$($_.name) GP")} |
Export-Excel -ExcelPackage $excel -AutoSize -Show

View File

@@ -1,2 +1,4 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Import-Html "http://en.wikipedia.org/wiki/Demographics_of_India" 4

View File

@@ -1 +1,3 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Import-Html "http://www.science.co.il/PTelements.asp" 1

View File

@@ -1 +1,3 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
Import-Html "https://en.wikipedia.org/wiki/List_of_Star_Trek:_The_Original_Series_episodes" 2

View File

@@ -0,0 +1,41 @@
#requires -modules "Get-IndexedItem"
[CmdletBinding()]
Param()
Remove-Item ~\documents\music.xlsx -ErrorAction SilentlyContinue
[System.Diagnostics.Stopwatch]$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
#Query system index for .MP3 files in C:\Users, where album artist is non-blank. Leave sorted table with columns of interest in $Music.
Get-IndexedItem "itemtype='.mp3'","AlbumArtist like '%'" -Recurse C:\Users -OutputVariable Music `
-OrderBy AlbumArtist, AlbumTitle, TrackNumber, Title -NoFiles `
-Property AlbumArtist, AlbumTitle, TrackNumber, Title, Duration, Size, SampleRate
Write-Verbose -Message ("Fetched " + $music.Rows.Count + " rows from index: " + $stopwatch.Elapsed.TotalSeconds)
#Send Table in $Music to Excel, format as a table, point $ws to the Worksheet
$excel = Send-SQLDataToExcel -Path ~\documents\music.xlsx -DataTable $music -WorkSheetname Music -TableName Music -Passthru
Write-Verbose -Message ("Inserted into Excel: " + $stopwatch.Elapsed.TotalSeconds)
$ws = $excel.Music
#Strip "SYSTEM.", "SYSTEM.AUDIO", "SYSTEM.MEDIA", "SYSTEM.MUSIC" from the column headings
#Convert Duration (column 5) from 100ns ticks to days and format as minutes, seconds, decimal
#Format filesize and sample rate nicely
#Autofit the columns.
Set-ExcelRow -Worksheet $ws -Row 1 -Value {($worksheet.cells[$row,$column].value -replace '^SYSTEM\.','') -replace '^MEDIA\.|^AUDIO\.|^MUSIC\.','' }
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'mm:ss.0' -StartRow 2 -Value {$worksheet.cells[$row,$column].value / 864000000000 }
Write-Verbose -Message ("Cells Reset: " + $stopwatch.Elapsed.TotalSeconds)
Set-ExcelColumn -Worksheet $ws -Column 6 -NumberFormat '#.#,,"MB"'
Set-ExcelColumn -Worksheet $ws -Column 7 -NumberFormat '0.0,"KHz"'
$ws.Cells[$ws.Dimension].AutoFitColumns()
#Make a Pivot table for sum of space and count of tracks by artist. Sort by artist, apply formatting to space, give it nice titles.
$pt = Add-PivotTable -PassThru -PivotTableName SpaceUsedByMusic -ExcelPackage $excel -SourceWorkSheet $ws `
-PivotRows ALBUMARTIST -PivotData ([ordered]@{"Size"="Sum"; "Duration"="Count"}) -PivotDataToColumn
$pt.RowFields[0].Sort = [OfficeOpenXml.Table.PivotTable.eSortType]::Ascending
$pt.DataFields[0].Format = '#.0,,"MB"'
$pt.DataFields[0].Name = 'Space Used'
$pt.DataFields[1].Name = 'Tracks'
#Save the file, and load it into Excel
$stopwatch.Stop()
Write-Verbose -Message ("Pivot Done: " + $stopwatch.Elapsed.TotalSeconds)
Close-ExcelPackage -show $excel

View File

@@ -0,0 +1,26 @@
param(
$PesterTestsPath = "$PSScriptRoot\..\..\..\__tests__\"
)
$xlfile = "$env:Temp\testResults.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$xlparams = @{
Path = $xlfile
InputObject = (Invoke-Pester -Script $PesterTestsPath -PassThru).TestResult | Sort-Object describe
WorksheetName = 'FullResults'
IncludePivotTable = $true
PivotRows = 'Describe'
PivotColumns = 'Passed'
PivotData = @{'Passed' = 'Count' }
IncludePivotChart = $true
ChartType = 'BarClustered'
AutoSize = $true
AutoFilter = $true
Activate = $true
}
Export-Excel -Show @xlparams

View File

@@ -0,0 +1,62 @@
<#
.Synopsis
Runs PsScriptAnalyzer against one or more folders and pivots the results to form a report.
.Example
Analyze_this.ps1
Invokes script analyzer on the current directory; creates a file in $env:temp and opens it in Excel
.Example
Analyze_this.ps1 -xlfile ..\mymodule.xlsx -quiet
Invokes script analyzer on the current directory; creates a file in the parent directory but does not open it
.Example
"." , (dir 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel\') | .\examples\ScriptAnalyzer\Analyze_this.ps1
run from a developemnt directory for importExcel it will produce a report for that directory compared against installed versions
this creates the file in the default location and opens it
#>
[CmdletBinding()]
param (
[parameter(ValueFromPipeline = $true)]
$Path = $PWD,
$xlfile = "$env:TEMP\ScriptAnalyzer.xlsx",
$ChartType = 'BarClustered' ,
$PivotColumns = 'Location',
[switch]$Quiet
)
begin {
Remove-Item -Path $xlfile -ErrorAction SilentlyContinue
$xlparams = @{
Path = $xlfile
WorksheetName = 'FullResults'
AutoSize = $true
AutoFilter = $true
Activate = $true
Show = (-not $Quiet)
}
$pivotParams = @{
PivotTableName = 'BreakDown'
PivotData = @{RuleName = 'Count' }
PivotRows = 'Severity', 'RuleName'
PivotColumns = 'Location'
PivotTotals = 'Rows'
}
$dirsToProcess = @()
}
process {
if ($path.fullName) {$dirsToProcess += $path.fullName}
elseif ($path.path) {$dirsToProcess += $path.Path}
else {$dirsToProcess += $path}
}
end {
$pivotParams['-PivotChartDefinition'] = New-ExcelChartDefinition -ChartType $chartType -Column (1 + $dirsToProcess.Count) -Title "Script analysis" -LegendBold
$xlparams['PivotTableDefinition'] = New-PivotTableDefinition @pivotParams
$dirsToProcess | ForEach-Object {
$dirName = (Resolve-Path -Path $_) -replace "^.*\\(.*?)\\(.*?)$", '$1-$2'
Write-Progress -Activity "Running Script Analyzer" -CurrentOperation $dirName
Invoke-ScriptAnalyzer -Path $_ -ErrorAction SilentlyContinue |
Add-Member -MemberType NoteProperty -Name Location -Value $dirName -PassThru
} | Export-Excel @xlparams
Write-Progress -Activity "Running Script Analyzer" -Completed
}

View File

@@ -0,0 +1,6 @@
"Region","Item","UnitSold","UnitCost"
"East","Banana","38","0.26"
"East","Kale","71","0.69"
"East","Apple","35","0.55"
"East","Potato","48","0.48"
"East","Kale","41","0.74"
1 Region Item UnitSold UnitCost
2 East Banana 38 0.26
3 East Kale 71 0.69
4 East Apple 35 0.55
5 East Potato 48 0.48
6 East Kale 41 0.74

View File

@@ -0,0 +1,43 @@
#Get rid of pre-exisiting sheet
$path = "$Env:TEMP\test.xlsx"
remove-item -Path $path -ErrorAction SilentlyContinue
#Create simple pages for 3 stores with product ID, Product Name, quanity price and total
@"
ID,Product,Quantity,Price,Total
12001,Nails,37,3.99,147.63
12002,Hammer,5,12.10,60.5
12003,Saw,12,15.37,184.44
12010,Drill,20,8,160
12011,Crowbar,7,23.48,164.36
"@ | ConvertFrom-Csv| Export-Excel -Path $path -WorkSheetname Oxford
@"
ID,Product,Quantity,Price,Total
12001,Nails,53,3.99,211.47
12002,Hammer,6,12.10,72.60
12003,Saw,10,15.37,153.70
12010,Drill,10,8,80
12012,Pliers,2,14.99,29.98
"@ | ConvertFrom-Csv| Export-Excel -Path $path -WorkSheetname Abingdon
@"
ID,Product,Quantity,Price,Total
12001,Nails,20,3.99,79.80
12002,Hammer,2,12.10,24.20
12010,Drill,11,8,88
12012,Pliers,3,14.99,44.97
"@ | ConvertFrom-Csv| Export-Excel -Path $path -WorkSheetname Banbury
#define a pivot table with a chart to show a sales by store, broken down by product
$ptdef = New-PivotTableDefinition -PivotTableName "Summary" -PivotRows "Store" -PivotColumns "Product" -PivotData @{"Total"="SUM"} -IncludePivotChart -ChartTitle "Sales Breakdown" -ChartType ColumnStacked -ChartColumn 10
#Join the 3 worksheets.
#Name the combined page "Total" and Name the column with the sheet names "store" (as the sheets 'Oxford','Abingdon' and 'Banbury' are the names of the stores
#Format the data as a table named "Summary", using the style "Light1", put the column headers in bold
#Put in a title and freeze to top of the sheet including title and colmun headings
#Add the Pivot table.
#Show the result
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Combined" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef -show

View File

@@ -0,0 +1,13 @@
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#Export disk volume, and Network adapter to their own sheets.
Get-CimInstance -ClassName Win32_LogicalDisk |
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
Get-NetAdapter |
Select-Object -Property Name,InterfaceDescription,MacAddress,LinkSpeed |
Export-Excel -Path $path -WorkSheetname NetAdapters
#Create a summary page with a title of Summary, label the blocks with the name of the sheet they came from and hide the source sheets
Join-Worksheet -Path $path -HideSource -WorkSheetName Summary -NoHeader -LabelBlocks -AutoSize -Title "Summary" -TitleBold -TitleSize 22 -show

View File

@@ -0,0 +1,23 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlfile = "$env:temp\AllSales.xlsx"
Remove-Item $xlfile -ErrorAction Ignore
$params = @{
AutoSize = $true
AutoFilter = $true
AutoNameRange = $true
ExcelChartDefinition = New-ExcelChartDefinition -XRange Item -YRange UnitSold -Title 'Units Sold'
Path = $xlfile
}
#Import 4 sets of sales data from 4 CSV files, using the parameters above.
Import-Csv $PSScriptRoot\NorthSales.csv | Export-Excel -WorkSheetname North @params
Import-Csv $PSScriptRoot\EastSales.csv | Export-Excel -WorkSheetname East @params
Import-Csv $PSScriptRoot\SouthSales.csv | Export-Excel -WorkSheetname South @params
Import-Csv $PSScriptRoot\WestSales.csv | Export-Excel -WorkSheetname West @params
#Join the 4 worksheets together on a sheet named Allsales, use the same parameters, except for AutoNameRange and ExcelChartDefinition.
$params.Remove("AutoNameRange")
$params.Remove("ExcelChartDefinition")
Join-Worksheet -WorkSheetName AllSales -Show @params

View File

@@ -0,0 +1,5 @@
"Region","Item","UnitSold","UnitCost"
"North","Apple","40","0.68"
"North","Kale","55","0.35"
"North","Banana","33","0.31"
"North","Pear","29","0.74"
1 Region Item UnitSold UnitCost
2 North Apple 40 0.68
3 North Kale 55 0.35
4 North Banana 33 0.31
5 North Pear 29 0.74

View File

@@ -0,0 +1,6 @@
"Region","Item","UnitSold","UnitCost"
"South","Banana","54","0.46"
"South","Pear","39","0.44"
"South","Potato","33","0.46"
"South","Banana","49","0.31"
"South","Apple","38","0.59"
1 Region Item UnitSold UnitCost
2 South Banana 54 0.46
3 South Pear 39 0.44
4 South Potato 33 0.46
5 South Banana 49 0.31
6 South Apple 38 0.59

View File

@@ -0,0 +1,12 @@
"Region","Item","UnitSold","UnitCost"
"West","Banana","74","0.56"
"West","Apple","26","0.7"
"West","Banana","59","0.49"
"West","Potato","56","0.62"
"West","Banana","60","0.64"
"West","Pear","32","0.29"
"West","Apple","73","0.26"
"West","Banana","49","0.59"
"West","Pear","65","0.35"
"West","Apple","60","0.34"
"West","Kale","67","0.38"
1 Region Item UnitSold UnitCost
2 West Banana 74 0.56
3 West Apple 26 0.7
4 West Banana 59 0.49
5 West Potato 56 0.62
6 West Banana 60 0.64
7 West Pear 32 0.29
8 West Apple 73 0.26
9 West Banana 49 0.59
10 West Pear 65 0.35
11 West Apple 60 0.34
12 West Kale 67 0.38

View File

@@ -1,9 +1,11 @@
ColumnChart -Title "Central Limit Theorem" ($(
for ($i = 1; $i -le 500; $i++) {
$s=0
for ($j = 1; $j -le 100; $j++){
$s+=Get-Random -Minimum 0 -Maximum 2
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
ColumnChart -Title "Central Limit Theorem" -NoLegend ($(
for ($i = 1; $i -le 500; $i++) {
$s = 0
for ($j = 1; $j -le 100; $j++) {
$s += Get-Random -Minimum 0 -Maximum 2
}
$s
}
$s
}
) | Sort | Group | select Count, Name)
) | Sort-Object | Group-Object | Select-Object Count, Name)

View File

@@ -2,5 +2,7 @@
# Sum up handles by company
# Show the Pie Chart
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
PieChart -Title "Total Handles by Company" `
(Invoke-Sum (Get-Process|Where company) company handles)
(Invoke-Sum (Get-Process | Where-Object company) company handles)

View File

@@ -2,6 +2,8 @@
# Sum up PM by company
# Show the Pie Chart
PieChart -Title "Total PM by Company" `
(Invoke-Sum (Get-Process|Where company) company pm)
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
PieChart -Title "Total PM by Company" `
(Invoke-Sum (Get-Process|Where-Object company) company pm)

View File

@@ -1,4 +1,4 @@
$PropertyNames = echo Cost Date Name
$PropertyNames = @("Cost", "Date", "Name")
New-PSItem 1.1 1/1/2015 John $PropertyNames
New-PSItem 2.1 1/2/2015 Tom

View File

@@ -1 +1,3 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
BarChart (.\TargetData.ps1) "A BarChart"

View File

@@ -1 +1,3 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
ColumnChart (.\TargetData.ps1) "A ColumnChart"

View File

@@ -1 +1,3 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
PieChart (.\TargetData.ps1) "A PieChart"

View File

@@ -0,0 +1,19 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$xlFile = "$env:TEMP\mw.xlsx"
Remove-Item $xlFile -ErrorAction Ignore
$leftCsv = @"
MyProp1,MyProp2,Length
a,b,10
c,d,20
"@ | ConvertFrom-Csv
$rightCsv = @"
MyProp1,MyProp2,Length
a,b,10
c,d,21
"@ | ConvertFrom-Csv
Merge-Worksheet -OutputFile $xlFile -ReferenceObject $leftCsv -DifferenceObject $rightCsv -Key Length -Show

View File

@@ -0,0 +1,21 @@
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
#Get a subset of services into $s and export them
[System.Collections.ArrayList]$s = Get-service | Select-Object -first 25 -Property *
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
$s[2].DisplayName = "Changed from the orginal" #This will be row 4 in Excel - this should be highlighted as a change
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d) #This will be row 5 in Excel - this should be highlighted as a new item
$s.RemoveAt(5) #This will be row 7 in Excel - this should be highlighted as deleted item
$s | Export-Excel -Path $env:temp\server2.xlsx
#This use of Merge-worksheet Assumes a default worksheet name, (sheet1) We will check and output Name (the key), DisplayName and StartType and ignore other properties.
Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined1.xlsx" -Property name,displayname,startType -Key name -Show

View File

@@ -0,0 +1,34 @@
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
#Get a subset of services into $s and export them
[System.Collections.ArrayList]$s = Get-service | Select-Object -first 25 -Property Name,DisplayName,StartType
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal" #This will be excel row 4 and Server 2 will show as changed.
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d) #This will be Excel row 5 and server 2 will show as changed - so will Server 3
$s.RemoveAt(5) #This will be Excel row 7 and Server 2 will show as missing.
$s | Export-Excel -Path $env:temp\server2.xlsx
#Make some more changes to $s and export it to a third file
$s[2].displayname = $row4Displayname #Server 3 row 4 will match server 1 so won't be highlighted
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Second Service"
$d.Name = "Service2"
$s.Insert(6,$d) #This will be an extra row in Server 3 at row 8. It will show as missing in Server 2.
$s.RemoveAt(8) #This will show as missing in Server 3 at row 11 ()
$s | Export-Excel -Path $env:temp\server3.xlsx
#Now bring the three files together.
Merge-MultipleSheets -Path "$env:temp\server1.xlsx", "$env:temp\Server2.xlsx","$env:temp\Server3.xlsx" -OutputFile "$env:temp\combined3.xlsx" -Property name,displayname,startType -Key name -Show

View File

@@ -0,0 +1,56 @@
<#
Fixed Rate Loan/Mortgage Calculator in Excel
#>
param(
$Amount = 400000,
$InterestRate = .065,
$Term = 30
)
function New-CellData {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification='Does not change system state')]
param(
$Range,
$Value,
$Format
)
$setFormatParams = @{
Worksheet = $ws
Range = $Range
NumberFormat = $Format
}
if ($Value -is [string] -and $Value.StartsWith('=')) {
$setFormatParams.Formula = $Value
}
else {
$setFormatParams.Value = $Value
}
Set-ExcelRange @setFormatParams
}
$f = "$PSScriptRoot\mortgage.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pkg = "" | Export-Excel $f -Title 'Fixed Rate Loan Payments' -PassThru -AutoSize
$ws = $pkg.Workbook.Worksheets["Sheet1"]
New-CellData -Range A3 -Value 'Amount'
New-CellData -Range B3 -Value $Amount -Format '$#,##0'
New-CellData -Range A4 -Value "Interest Rate"
New-CellData -Range B4 -Value $InterestRate -Format 'Percentage'
New-CellData -Range A5 -Value "Term (Years)"
New-CellData -Range B5 -Value $Term
New-CellData -Range D3 -Value "Monthly Payment"
New-CellData -Range F3 -Value "=-PMT(F4, B5*12, B3)" -Format '$#,##0.#0'
New-CellData -Range D4 -Value "Monthly Rate"
New-CellData -Range F4 -Value "=((1+B4)^(1/12))-1" -Format 'Percentage'
Close-ExcelPackage $pkg -Show

Some files were not shown because too many files have changed in this diff Show More